vue使用echarts實(shí)現(xiàn)中國地圖和點(diǎn)擊省份進(jìn)行查看功能
1,實(shí)現(xiàn)的效果和功能
vue使用echarts實(shí)現(xiàn)中國地圖和點(diǎn)擊省份進(jìn)行查看;
下面是效果圖:主要實(shí)現(xiàn)的功能如下:
1,第一張是實(shí)現(xiàn)中國地圖,點(diǎn)擊任意省份能夠顯示tooltip提示框 ;
2,第二張是點(diǎn)擊詳情
能夠在原來的位置顯示此省的地圖并可以查看詳細(xì);
3,第三張是點(diǎn)擊第二張左上角的返回箭頭 重新返回到 第一張中國地圖
;
需要的保費(fèi)模擬數(shù)據(jù)我會(huì)放到文章的最后面;
echarts官網(wǎng):https://echarts.apache.org/examples/zh/index.html
map地圖參考:https://echarts.apache.org/zh/option.html#series-map
效果圖:
2,安裝ECharts
npm install echarts --save // 最新版本 ### 之前版本 npm install echarts@4.8.0 --save ### 卸載echarts npm uninstall echarts
注意:echarts5.0版本下會(huì)有地圖的數(shù)據(jù),5.0版本以上則沒有地圖的數(shù)據(jù),需要自己下載;
或者安裝低版本的echart把map文件夾的地圖數(shù)據(jù)復(fù)制到高版本的對(duì)應(yīng)文件下面也是可以的;
1.1 地圖數(shù)據(jù)的位置
中國地圖和各省的地圖繪制信息需要放到依賴?yán)锩娴膃charts下面的map文件夾下面;如下圖:
1.2 還可以自己下載這些地圖數(shù)據(jù)
下載地址:https://datav.aliyun.com/portal/school/atlas/area_selector
3,main.js里面引入echarts
// 引入echarts import * as echarts from 'echarts' Vue.prototype.$echarts = echarts //掛載到原型上面 也可以選擇不掛載 直接在頁面上引入
4,實(shí)現(xiàn)如下
主要流程如下:
1,需要有一個(gè)容器
<div id="chinaMap" v-if="pyName === 'china'"></div>
且有唯一 id值
2,this.$echarts.init(document.getElementById('chinaMap'))
; 用來初始化節(jié)點(diǎn) id和上面的相對(duì)應(yīng);
3,require('../../../node_modules/echarts/map/json/china.json');
用來導(dǎo)入相對(duì)應(yīng)的地圖數(shù)據(jù),echarts進(jìn)行渲染
4,options
配置項(xiàng)用來設(shè)置echarts圖表的樣式和展示數(shù)據(jù)相關(guān);
5,this.myEchartsOfChina.setOption(options);
設(shè)置圖表實(shí)例的配置項(xiàng)以及數(shù)據(jù),萬能接口,所有參數(shù)和數(shù)據(jù)的修改都可以通過 setOption 完成,ECharts 會(huì)合并新的參數(shù)和數(shù)據(jù),然后刷新圖表;
6,options
:formatter
html里面的點(diǎn)擊事件需要在mounted里面先行注冊(cè)一下,否則此方法會(huì)報(bào)錯(cuò):undefined;
全部代碼如下:
<template> <div> <h1>echarts可視化</h1> <hr /> <div class="container"> <!-- 全國地圖 機(jī)構(gòu)趨勢(shì)模塊 --> <div class="china"> <!-- 點(diǎn)擊返回全國--> <div @click="returnCh"> <img v-if="pyName !== 'china'" class="returnImg" src="@/assets/img/return.png" /> </div> <div id="chinaMap" v-if="pyName === 'china'"></div> <div id="provinceMap" v-if="pyName !== 'china'">111</div> </div> </div> </div> </template> <script> import { cityArr, totalMap } from './data/mapData'; export default { components: {}, data() { return { // 全省保費(fèi)信息 totalMap: null, // 各個(gè)城市的數(shù)據(jù) cityArr: null, myEchartsOfChina: null, // 默認(rèn)選擇的城市 這是拼音 pyName: 'china', // 保留一份省名的中文 pyNameOfChinese: '', }; }, created() { // 拿到數(shù)據(jù) this.totalMap = totalMap; this.cityArr = cityArr; // 頁面進(jìn)來注冊(cè)tooltip上面的點(diǎn)擊事件 否則會(huì)報(bào)此事件undefined window.lookVideoGo = this.lookVideoGo; }, // 頁面掛載完成后調(diào)用 mounted() { this.chinaMapFun(); }, methods: { /*中國地圖 參考文章:https://echarts.apache.org/zh/option.html#series-map*/ chinaMapFun(cityName) { // 先處理數(shù)據(jù) 很重要 let mapData = []; for (let i = 0; i < this.totalMap.length; i++) { let obj = { value: 0, datas: [] }; // 數(shù)組里面是多個(gè)對(duì)象 obj.name = this.totalMap[i].comname2; // names屬性時(shí)數(shù)據(jù)所對(duì)應(yīng)的地圖區(qū)域的名稱,例如 '廣東','浙江';參考文章: https://echarts.apache.org/zh/option.html#series-map.data obj.value = this.totalMap[i].achieveRate; // 該區(qū)域的數(shù)據(jù)值 number類型 obj.datas[0] = this.totalMap[i].preium; obj.datas[1] = this.totalMap[i].target; //注意: 此行是模擬下面的省份用的 實(shí)際開發(fā)中每個(gè)省份的數(shù)據(jù)是后端返回的 if (this.totalMap[i].children) { obj.children = this.totalMap[i].children; } mapData.push(obj); } // 這里進(jìn)行篩選傳進(jìn)來的省份數(shù)據(jù) 模擬黑龍江省份下面的和黑河市 if (this.pyNameOfChinese) { mapData = mapData.map((item) => { if (item.children) { return { name: item.children.comname2, value: item.children.achieveRate, datas: [item.children.preium, item.children.target] }; } }); } console.log('當(dāng)前渲染的地圖:', this.pyName); console.log('當(dāng)前渲染的數(shù)據(jù)2:', mapData); // 1,初始化節(jié)點(diǎn) // 檢測(cè)是否已經(jīng)存在echarts實(shí)例,如果不存在,則不再去初始化 if (this.pyName === 'china') { this.myEchartsOfChina = this.$echarts.init(document.getElementById('chinaMap')); } else { this.myEchartsOfChina = this.$echarts.init(document.getElementById('provinceMap')); } // 顯示加載動(dòng)畫 this.myEchartsOfChina.showLoading(); if (this.pyName === 'china') { let province = require('../../../node_modules/echarts/map/json/china.json'); // 注冊(cè)地圖數(shù)據(jù) this.$echarts.registerMap(this.pyName, province); } else { // 單獨(dú)引入其他省份的地圖 注意:registerMap方法的第一參數(shù)要和引入的省名相同 let province = require('../../../node_modules/echarts/map/json/province/' + this.pyName + '.json'); this.$echarts.registerMap(this.pyName, province); } this.myEchartsOfChina.hideLoading(); /* 參考文檔: https://echarts.apache.org/zh/option.html#series-map */ // 設(shè)置整個(gè)中國地圖的參數(shù) let options = { title: { show: false, // 是否顯示標(biāo)題組件 text: '中國地圖', // 主標(biāo)題文本 subtext: '注:展示當(dāng)月和當(dāng)年累計(jì)情況', left: '3%', top: '85%', }, tooltip: { enterable: true, // 允許點(diǎn)擊觸發(fā)tooltip中的事件 show: true, // 是否顯示提示框組件,包括提示框浮層和 axisPointer。 [ default: true ] trigger: 'item', // 觸發(fā)類型。 [ default: 'item' ] triggerOn: 'click', // 只有點(diǎn)擊時(shí)才觸發(fā) 不設(shè)置默認(rèn)隨鼠標(biāo)移動(dòng)并顯示 formatter: (array, returnData, callback) => { if (isNaN(array.value)) { if (this.cityArr.includes(array.name)) { return '保費(fèi): 暫無' + '<br/>' + '目標(biāo): 暫無' + '<br/>' + '保費(fèi)達(dá)成率: 暫無'; } else { return '保費(fèi): 暫無' + '<br/>'; } } else { let result = '<div style="display: flex"><div style="float:left;">保費(fèi): ' + array.data.datas[0] + '萬元 <br/> 目標(biāo): ' + array.data.datas[1] + '萬元 <br/> 保費(fèi)達(dá)成率: ' + array.data.value + '%</div>' + '<div style="float:left; margin-left: 0.1rem;width: 0.05rem;height: 1rem; background: #D8D8D8;"></div>' + '<div style="float:left; margin-left: 0.1rem; "οnclick="lookVideoGo(\'' + array.name + '\')"><p style="height:2rem; line-height:2rem;">詳 情 > </p></div></div>'; return result; } }, backgroundColor: 'rgba(50,50,50,0.7)', // tooltip 背景顏色 rgba // 文本設(shè)置 textStyle: { color: 'rgb(255,255,255)', // 值域文字顏色 fontSize: 12, }, }, // 底部小導(dǎo)航圖標(biāo) visualMap: { // text: ['注:展示當(dāng)月和當(dāng)年累計(jì)情況'], orient: 'horizontal', itemWidth: 15, textGap: 2, // calculable: false, show: true, left: 'center', y: 'bottom', splitList: [ { end: 0, label: '無', color: '#DDDDDD' }, { end: 30, color: 'rgb(255,248,220)' }, { start: 30, end: 60, label: '30-60', color: 'rgb(252,235,207)' }, { start: 60, end: 90, label: '60-90', color: '#FFDAB9' }, { start: 90, end: 100, label: '90-100', color: 'rgb(245,158,131)' }, // 245 158 131 { start: 100, label: '>=100', color: 'rgb(40,183,163)' }, // 40 183 163 ], }, backgroundColor: '#fff', // 圖表背景色 series: [ { name: '省份', type: 'map', // 指定是地圖類型 map: this.pyName, // 和上面registerMap中的第一個(gè)參數(shù)值一致才可以正常加載地圖 zoom: 1.2, roam: true, // 是否開啟平游或縮放 // geoIndex: 0, // aspectScale: 0.75, // scaleLimit: { // 滾輪縮放的極限控制 // min: 1, // max: 2 // }, selectedMode: 'single', // 選中模式,表示是否支持多個(gè)選中,默認(rèn)關(guān)閉,支持布爾值和字符串,字符串取值可選'single'表示單選,或者'multiple'表示多選。 itemStyle: { areaColor: '#FFFFFF', borderColor: '#0f0f0f', normal: { label: { show: true }, areaColor: '#DDDDDD' }, emphasis: { label: { show: true } }, }, emphasis: { // 強(qiáng)調(diào)的樣式,也就是鼠標(biāo)移入后的樣式==高亮狀態(tài)下的多邊形和標(biāo)簽樣式。 itemStyle: { areaColor: '#000000', }, }, label: { normal: { show: true, // 是否顯示標(biāo)簽,這里顯示的就是省份的名字。默認(rèn)就是false textStyle: { fontWeight: 300, color: '#000000', // 值域文字顏色 fontSize: 7, // 文字的字體大 小 }, }, emphasis: { show: false, // 在鼠標(biāo)移入時(shí),是否顯示,如果不寫,默認(rèn)是顯示的 }, }, data: mapData, // 各省地圖數(shù)據(jù)導(dǎo)入 }, ], }; // 設(shè)置各個(gè)省份地圖的參數(shù) let options1 = { title: { show: false, // 是否顯示標(biāo)題組件 subtext: '注:展示當(dāng)月和當(dāng)年累計(jì)情況', left: '3%', top: '85%', }, tooltip: { enterable: true, // 允許點(diǎn)擊觸發(fā)tooltip中的事件 show: true, // 是否顯示提示框組件,包括提示框浮層和 axisPointer。 [ default: true ] trigger: 'item', // 觸發(fā)類型。 [ default: 'item' ] backgroundColor: 'rgba(50,50,50,0.7)', // tooltip 背景顏色 rgba // 文本設(shè)置 textStyle: { color: 'rgb(255,255,255)', // 值域文字顏色 fontSize: 12, }, formatter: (array, returnData, callback) => { console.log(array); if (isNaN(array.value)) { if (this.cityArr.includes(array.name)) { return '保費(fèi): 暫無' + '<br/>' + '目標(biāo): 暫無' + '<br/>' + '保費(fèi)達(dá)成率: 暫無'; } else { return '保費(fèi): 暫無' + '<br/>'; } } else { let result = '<div style="display: flex"><div style="float:left;">保費(fèi): ' + array.data.datas[0] + '萬元 <br/> 目標(biāo): ' + array.data.datas[1] + '萬元 <br/> 保費(fèi)達(dá)成率: ' + array.data.value + '%</div>' + '<div style="float:left; margin-left: 0.1rem;width: 0.05rem;height: 1rem; background: #D8D8D8;"></div>' + '<div style="float:left; margin-left: 0.1rem; "οnclick="lookVideoGo(\'' + array.name ; return result; } }, }, // 底部小導(dǎo)航圖標(biāo) visualMap: { // text: ['注:展示當(dāng)月和當(dāng)年累計(jì)情況'], orient: 'horizontal', itemWidth: 15, textGap: 2, // calculable: false, show: true, left: 'center', y: 'bottom', splitList: [ { start: 6, label: '>=7', color: '#FFDAB9' }, { start: 3, end: 6, label: '4-6', color: 'rgb(245,158,131)' }, // 245 158 131 { start: 1, end: 3, label: '1-3', color: 'rgb(40,183,163)' }, // 40 183 163 { end: 0, label: '無', color: '#DDDDDD' }, ], }, series: [ { name: '省份', // 系列名稱,用于tooltip的顯示,legend 的圖例篩選,在 setOption 更新數(shù)據(jù)和配置項(xiàng)時(shí)用于指定對(duì)應(yīng)的系列。見上:可以在tooltip中獲取到 type: 'map', // 指定是地圖類型 map: this.pyName, // 和上面registerMap中的一直 zoom: 1.2, selectedMode: 'single', // 選中模式,表示是否支持多個(gè)選中,默認(rèn)關(guān)閉,支持布爾值和字符串,字符串取值可選'single'表示單選,或者'multiple'表示多選。 itemStyle: { areaColor: '#FFFFFF', borderColor: '#0f0f0f', normal: { label: { show: true }, areaColor: '#DDDDDD' }, emphasis: { label: { show: true } }, }, emphasis: { // 強(qiáng)調(diào)的樣式,也就是鼠標(biāo)移入后的樣式==高亮狀態(tài)下的多邊形和標(biāo)簽樣式。 itemStyle: { areaColor: '#000000', }, }, label: { normal: { show: true, // 是否顯示標(biāo)簽,這里顯示的就是省份的名字。默認(rèn)就是false textStyle: { fontWeight: 300, color: '#000000', // 值域文字顏色 fontSize: 7, // 文字的字體大 小 }, }, emphasis: { show: false, // 在鼠標(biāo)移入時(shí),是否顯示,如果不寫,默認(rèn)是顯示的 }, }, // 數(shù)據(jù)對(duì)不上 省下面的地區(qū)對(duì)不上 data: mapData, }, ], }; // 判斷是否是各個(gè)省份 if (this.pyName === 'china') { this.myEchartsOfChina.setOption(options); } else { this.myEchartsOfChina.setOption(options1); } }, /* 傳過來的參數(shù)是省份名 */ lookVideoGo(cityName) { // 保留一份中文 this.pyNameOfChinese = cityName; // this.myEchartsOfChina.clear(); // 清空當(dāng)前實(shí)例,會(huì)移除實(shí)例中所有的組件和圖表。 this.myEchartsOfChina.dispose(); // 銷毀后實(shí)例無法在使用 // 獲取城市拼音 for (var i = 0, len = this.cityArr[0].length; i < len; i++) { if (cityName === this.cityArr[0][i]) { // 獲取得城市拼音 this.pyName = this.cityArr[1][i]; // 使用nextTick Api 防止echarts初始化時(shí)避免節(jié)點(diǎn)不存在的報(bào)錯(cuò) this.$nextTick(() => { this.chinaMapFun(this.pyName); }); break; } else { console.warn('沒有找到此城市的拼音'); } } }, /* 點(diǎn)擊返回全國 */ returnCh() { // this.myEchartsOfChina.clear(); // 清空當(dāng)前實(shí)例,會(huì)移除實(shí)例中所有的組件和圖表。 this.myEchartsOfChina.dispose(); // 銷毀后實(shí)例 這里使用dispose防止殘留 this.pyName = 'china'; this.pyNameOfChinese = ''; // 使用nextTick Api 防止echarts初始化時(shí)避免節(jié)點(diǎn)不存在的報(bào)錯(cuò) this.$nextTick(() => { this.chinaMapFun(); }); }, }, }; </script> <style lang="scss" scoped> .container { width: 90%; // margin: 0 auto; border: 1px solid balck; display: flex; justify-content: flex-start; align-items: center; flex-direction: row; flex-wrap: wrap; #chinaMap,#provinceMap { width: 400px; height: 400px; margin-right: 30px; margin-top: 20px; } .china{ } // 返回箭頭 .returnImg{ cursor: pointer; display: block; width: 25px; } } </style>
5,遇到的問題
5.1 渲染中國地圖時(shí)警告地圖不存在:
原因:series里面的map屬性沒有和上面registerMap中的第一個(gè)參數(shù)值保持一致
正確寫法:
5,2 點(diǎn)擊tooltip提示框中的詳情 生產(chǎn)省份地圖失敗,警告如下:
原因:沒有拿到dom節(jié)點(diǎn),需要在 this.$nextTick API里面獲取dom節(jié)點(diǎn)
正確寫法:
// 獲取城市拼音 for (var i = 0, len = this.cityArr[0].length; i < len; i++) { if (cityName === this.cityArr[0][i]) { // 獲取得城市拼音 this.pyName = this.cityArr[1][i]; // 使用nextTick Api 防止echarts初始化時(shí)避免節(jié)點(diǎn)不存在的報(bào)錯(cuò) this.$nextTick(() => { this.chinaMapFun(this.pyName); }); break; } else { console.warn('沒有找到此城市的拼音'); } }
6,用到的模擬數(shù)據(jù)
mapData.js
// 定義全國省份的數(shù)組 export const cityArr = [ [ '上海', '河北', '山西', '內(nèi)蒙古', '遼寧', '吉林', '黑龍江', '江蘇', '浙江', '安徽', '福建', '江西', '山東', '河南', '湖北', '湖南', '廣東', '廣西', '海南', '四川', '貴州', '云南', '西藏', '陜西', '甘肅', '青海', '寧夏', '新疆', '北京', '天津', '重慶', '香港', '澳門', '臺(tái)灣', ], [ 'shanghai', 'hebei', 'shanxi', 'neimenggu', 'liaoning', 'jilin', 'heilongjiang', 'jiangsu', 'zhejiang', 'anhui', 'fujian', 'jiangxi', 'shandong', 'henan', 'hubei', 'hunan', 'guangdong', 'guangxi', 'hainan', 'sichuan', 'guizhou', 'yunnan', 'xizang', 'shanxi1', 'gansu', 'qinghai', 'ningxia', 'xinjiang', 'beijing', 'tianjin', 'chongqing', 'xianggang', 'aomen', 'taiwan', ], ]; // 全省保費(fèi)信息 export const totalMap = [ { achieveRate: 104.1, comname2: '山東', preium: 22855, target: 21960, }, { achieveRate: 154, comname2: '新疆', preium: 893, target: 580, }, { achieveRate: 128.6, comname2: '青海', preium: 935, target: 727, }, { achieveRate: 84.7, comname2: '四川', preium: 7357, target: 8687, }, { achieveRate: 79.4, comname2: '陜西', preium: 5102, target: 6427, }, { achieveRate: 84.6, comname2: '內(nèi)蒙古', preium: 10448, target: 12357, }, { achieveRate: 0, comname2: '無錫', preium: 21, target: 0, }, { achieveRate: 74.8, comname2: '甘肅', preium: 5468, target: 7308, }, { achieveRate: 93.4, comname2: '海南', preium: 3746, target: 4009, }, { achieveRate: 71.4, comname2: '湖北', preium: 2870, target: 4017, }, { achieveRate: 39.4, comname2: '廈門', preium: 188, target: 477, }, { achieveRate: 63.3, comname2: '寧夏', preium: 1292, target: 2042, }, { achieveRate: 135.2, comname2: '江西', preium: 5616, target: 4155, }, { achieveRate: 0, comname2: '東莞', preium: 0, target: 0, }, { achieveRate: 95, comname2: '貴州', preium: 6931, target: 7298, }, { achieveRate: 39.1, comname2: '江蘇', preium: 2303, target: 5893, }, { achieveRate: 0, comname2: '上海', preium: 6, target: 0, }, { achieveRate: 85.7, comname2: '天津', preium: 1672, target: 1950, }, { achieveRate: 60.1, comname2: '廣東', preium: 3260, target: 5428, }, { achieveRate: 58.6, comname2: '青島', preium: 1979, target: 3380, }, { achieveRate: 67.7, comname2: '吉林', preium: 12375, target: 18288, }, { achieveRate: 45.3, comname2: '湖南', preium: 4527, target: 9995, }, { achieveRate: 52.2, comname2: '北京', preium: 6, target: 12, }, { achieveRate: 86.1, comname2: '河南', preium: 5733, target: 6659, }, { achieveRate: 71.6, comname2: '安徽', preium: 3201, target: 4471, }, { achieveRate: 50.6, comname2: '黑龍江', preium: 3127, target: 6186, children:{ comname2:'黑河市', preium: 3127, target: 6186, achieveRate: 50.6, } }, { achieveRate: 0, comname2: '蘇州', preium: 193, target: 0, }, { achieveRate: 69.9, comname2: '山西', preium: 2051, target: 2935, }, { achieveRate: 77.6, comname2: '福建', preium: 4371, target: 5632, }, { achieveRate: 96.5, comname2: '浙江', preium: 9650, target: 10000, }, { achieveRate: 73.5, comname2: '遼寧', preium: 8753, target: 11915, }, { achieveRate: 78.1, comname2: '重慶', preium: 2587, target: 3313, }, { achieveRate: -0.5, comname2: '深圳', preium: 0, target: 24, }, { achieveRate: 112.5, comname2: '寧波', preium: 1233, target: 1096, }, { achieveRate: 122.7, comname2: '云南', preium: 5477, target: 4462, }, { achieveRate: 104.9, comname2: '河北', preium: 13750, target: 13107, }, { achieveRate: 66.4, comname2: '廣西', preium: 1134, target: 1707, }, ];
到此這篇關(guān)于vue使用echarts實(shí)現(xiàn)中國地圖和點(diǎn)擊省份進(jìn)行查看的文章就介紹到這了,更多相關(guān)vue echarts 中國地圖內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用vue-infinite-scroll實(shí)現(xiàn)無限滾動(dòng)效果
vue-infinite-scroll插件可以無限滾動(dòng)實(shí)現(xiàn)加載更多,其作用是是當(dāng)滾動(dòng)條滾動(dòng)到距離底部的指定高度時(shí)觸發(fā)某個(gè)方法。這篇文章主要介紹了用vue-infinite-scroll實(shí)現(xiàn)無限滾動(dòng)效果,需要的朋友可以參考下2018-06-06Vuejs學(xué)習(xí)筆記之使用指令v-model完成表單的數(shù)據(jù)雙向綁定
表單類控件承載了一個(gè)網(wǎng)頁數(shù)據(jù)的錄入與交互,本章將介紹如何使用指令v-model完成表單的數(shù)據(jù)雙向綁定功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值。感興趣的朋友跟隨小編一起看看吧2019-04-04基于element-ui封裝可搜索的懶加載tree組件的實(shí)現(xiàn)
這篇文章主要介紹了基于element-ui封裝可搜索的懶加載tree組件的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05vue指令之表單控件綁定v-model v-model與v-bind結(jié)合使用
這篇文章主要介紹了vue指令之表單控件綁定v-model v-model與v-bind結(jié)合使用,需要的朋友可以參考下2019-04-04