??近期做了一些echarts圖表的開(kāi)發(fā),都是基本的單軸和雙軸的折線圖、餅圖、柱狀圖等,看到百度疫情實(shí)時(shí)地圖,對(duì)中國(guó)地圖和各個(gè)省份地圖充滿了好奇,想著通過(guò)echarts模仿實(shí)現(xiàn)百度疫情實(shí)時(shí)地圖。
??整體代碼在vue中實(shí)現(xiàn),跟普通的html和js中實(shí)現(xiàn)并無(wú)太大差距,差距主要體現(xiàn)在vue的數(shù)據(jù)雙向綁定上。
1.創(chuàng)建vue項(xiàng)目,配置路由相關(guān)等設(shè)置,創(chuàng)建展示的頁(yè)面。
<template>
<div class="home">
</div>
</template>
<script>
export default {
name: 'ChinaMap'
}
</script>
<style scoped>
</style>
2.vue中獲取并引入 ECharts、引入Echarts中的中國(guó)地圖
(1)在控制臺(tái)中執(zhí)行命令:npm install echarts --save,安裝完成后vue項(xiàng)目中就獲取到了echarts,在依賴文件夾node_modules中,即可找到獲取到的echarts:

(2)項(xiàng)目中引入echart以及echarts提供的中國(guó)地圖
<template>
<div class="home">
</div>
</template>
<script>
import echarts from 'echarts'
import china from 'echarts/map/js/china'
export default {
name: 'ChinaMap'
}
</script>
<style scoped>
</style>
3.初始化地圖
(1)代碼中dataList數(shù)據(jù)為模擬的各個(gè)省市的疫情數(shù)據(jù),
(2)id為"main"的div塊為存放地圖的容器(echarts的相關(guān)學(xué)習(xí)可以去官網(wǎng)查看)。
<template>
<div class="home">
<!-- 放地圖的容器-->
<div id='main' ref='chart' style='width: 100%;height:600px;'></div>
</div>
</template>
<script>
import echarts from 'echarts'
import china from 'echarts/map/js/china'
export default {
name: 'ChinaMap',
data() {
return {
// 地圖上顯示的疫情數(shù)據(jù)
dataList : [
{ name: '南海諸島', value: 0 },
{ name: '北京', value: 54 },
{ name: '天津', value: 13 },
{ name: '上海', value: 40 },
{ name: '重慶', value: 75 },
{ name: '河北', value: 13 },
{ name: '河南', value: 83 },
{ name: '云南', value: 11 },
{ name: '遼寧', value: 19 },
{ name: '黑龍江', value: 15 },
{ name: '湖南', value: 69 },
{ name: '安徽', value: 60 },
{ name: '山東', value: 39 },
{ name: '新疆', value: 2 },
{ name: '江蘇', value: 31 },
{ name: '浙江', value: 104 },
{ name: '江西', value: 36 },
{ name: '湖北', value: 1052 },
{ name: '廣西', value: 33 },
{ name: '甘肅', value: 7 },
{ name: '山西', value: 9 },
{ name: '內(nèi)蒙古', value: 7 },
{ name: '陜西', value: 22 },
{ name: '吉林', value: 4 },
{ name: '福建', value: 18 },
{ name: '貴州', value: 5 },
{ name: '廣東', value: 98 },
{ name: '青海', value: 1 },
{ name: '西藏', value: 0 },
{ name: '四川', value: 44 },
{ name: '寧夏', value: 4 },
{ name: '海南', value: 22 },
{ name: '臺(tái)灣', value: 3 },
{ name: '香港', value: 5 },
{ name: '澳門', value: 5 }
]
}
},
methods: {
initChart() {
// 獲取存放地圖的dom元素
let myChart = echarts.init(this.$refs.chart);
// 指定圖表的配置項(xiàng)和數(shù)據(jù)
let option = {
// 地圖標(biāo)題
title: {
text: '中國(guó)疫情地圖',
x: 'center'
},
// 放上鼠標(biāo)后顯示的新
tooltip : {
trigger: 'item',
formatter: function(e, t, n) {
return '地區(qū):' + e.data.name + '<br/>確診:' + e.data.value
},
textStyle:{
align:'left'
}
},
// 設(shè)置地圖數(shù)據(jù)
series: [
{
type: 'map',
map: 'china',
label: {
show: true,
color: 'black',
fontsize: 12,
formatter: res=> {
return res.data.name
}
},
itemStyle: {
// borderColor: 'red',
borderWidth: .5
},
// 選中時(shí)候顯示內(nèi)容
emphasis: {
label: {
color: 'black',
fontsize:15
},
itemStyle: {
// borderColor: '#00FFFF',
areaColor: '#ADFF2F'
}
},
roam: true,
data: this.dataList,
}
]
}
// 使用剛指定的配置項(xiàng)和數(shù)據(jù)顯示圖表。
myChart.setOption(option)
}
},
mounted() {
this.initChart()
}
}
</script>
<style scoped>
</style>
??現(xiàn)在地圖已經(jīng)初步的有了樣子,如果對(duì)地圖顯示上有個(gè)性化的的設(shè)置,可以自己去官網(wǎng)查看相關(guān)屬性配置。

4.利用visualMap屬性實(shí)現(xiàn)根據(jù)疫情數(shù)據(jù)動(dòng)態(tài)的設(shè)置地圖中各省市的顏色
// 視覺(jué)映射組件,根據(jù)疫情數(shù)據(jù)的不同,地圖顯示不同的顏色
visualMap: {
type: 'piecewise',
min: 0,
max: 1000,
left: 300,
bottom: 40,
showLabel: !0,
text: ['高', '低'],
pieces: [{
gt: 100,
label: '> 100 人',
color: '#7f1100',
symbol: 'roundRect'
}, {
gte: 10,
lte: 100,
label: '10 - 100 人',
color: '#ff5428'
}, {
gte: 1,
lt: 10,
label: '1 - 9 人',
color: '#ff8c71'
}, {
value: 0,
color: '#ADFF2F',
symbol: 'roundRect'
}],
show: !0
}
??設(shè)置完這個(gè)屬性,地圖已經(jīng)初步有了百度中國(guó)疫情的樣子:

5.確診為0的省市插上小旗子的標(biāo)注
??對(duì)比下百度做的疫情地圖,清零的省地圖上標(biāo)注為小旗子,接下來(lái)實(shí)現(xiàn)這個(gè)功能:

??小旗子這個(gè)樣式百度了好久,看了好多案例,結(jié)果走錯(cuò)了路線,雖然也實(shí)現(xiàn)了該功能,但是特別繁瑣,最后發(fā)現(xiàn)使用series-map中的markPoint屬性可以輕松實(shí)現(xiàn)小旗子的功能:
??(1)繁瑣的方法思路:在中國(guó)地圖坐標(biāo)系中引入散點(diǎn)圖(series-scatter),然后找到各個(gè)省份的坐標(biāo),通過(guò)該坐標(biāo)布置散點(diǎn)圖,并通過(guò)series-scatter的symbol改變散點(diǎn)的樣式,自定義圖例,設(shè)置小旗子的標(biāo)注。該方法比較麻煩,而且對(duì)地圖縮放設(shè)置也比較復(fù)雜,不太推薦。
??(2)最終的思路:使用series-map中的markPoint屬性可以輕松實(shí)現(xiàn)該功能,之后看api應(yīng)該認(rèn)真仔細(xì),才能少走彎路。
??在地圖的series中添加markPoint屬性,并做如下設(shè)置:
markPoint: { //標(biāo)記點(diǎn)
// symbol設(shè)置的為小旗子圖片的base64嗎
symbol: 'image://data:image/png;base64,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',
symbolSize: 14, //圖形大小
label: {
normal: {
formatter: function(params) {
console.log(params);
return params.name;
},
show: false,
},
emphasis: {
show: false,
}
},
data: this.markPointData
}
??其中markPointData為需要標(biāo)注小旗子的省份地圖坐標(biāo)數(shù)組,將清零之后的省份坐標(biāo)放入markPointData中,該省份就會(huì)標(biāo)注為小紅旗。下面為操作的具體步驟:
??a.從echarts中導(dǎo)入各省的坐標(biāo)數(shù)據(jù)mapJson,對(duì)數(shù)據(jù)進(jìn)行修整后存入geoCoordMap中,數(shù)據(jù)類型為{'新疆': [X值, Y值],'北京': [X值, Y值]...};
??b.然后遍歷存放疫情數(shù)據(jù)的變量dataList,當(dāng)疫情數(shù)據(jù)value為0時(shí),根據(jù)dataList的省份名稱找出geoCoordMap對(duì)應(yīng)的坐標(biāo),按markPointData的格式存放進(jìn)去(南海諸島有些特殊,詳情看上方代碼注釋);
??c.此時(shí)關(guān)于疫情的的數(shù)據(jù)都準(zhǔn)備好了,此時(shí)可以初始化地圖了(將生命周期函數(shù)呢的初始化地圖操作this.initChart()去掉,直接調(diào)用this.getMapJson())。
import echarts from 'echarts'
import china from 'echarts/map/js/china'
import mapJson from 'echarts/map/json/china.json'
export default {
name: 'ChinaMap',
data() {
return {
dataList:[...], //疫情數(shù)據(jù)(上面寫(xiě)了,這里省略掉了。。)
markPointData: [ ], // 當(dāng)某個(gè)省清零后,為這個(gè)省標(biāo)注小紅旗,存放這個(gè)省坐標(biāo)的數(shù)據(jù)
geoCoordMap: { }, // 存放地圖中各個(gè)省的坐標(biāo)
}
}
}
methods:{
getMapJson() {
let mapXY = mapJson.features // 獲取地圖中各省的坐標(biāo)數(shù)據(jù)
// 對(duì)獲從echarts中獲取的各個(gè)省的地圖坐標(biāo)進(jìn)行修正
mapXY.forEach(res=>{
this.geoCoordMap[res.properties.name]=res.properties.cp
//旗子的位置跟省的名字重合了,縱坐標(biāo)上移1.25
this.geoCoordMap[res.properties.name][1]=this.geoCoordMap[res.properties.name][1] + 1.25
})
// 對(duì)疫情數(shù)據(jù)進(jìn)行遍歷,查找出疫情數(shù)據(jù)為0的省份,加入到markPointData
this.dataList.forEach(res=>{
if(res.value===0) {
// echarts中未提供南海諸島的坐標(biāo),此坐標(biāo)為我自己根據(jù)坐標(biāo)系推算的
if(res.name=== '南海諸島') {
this.markPointData.push({
name: '南海諸島',
coord: [130, 22],
value: 0
})
} else {
let tmp= {}
tmp.name= res.name
tmp.coord= this.geoCoordMap[res.name]
tmp.value= res.value
this.markPointData.push(tmp)
}
}
})
// 數(shù)據(jù)準(zhǔn)備完畢后,初始化地圖
this.initChart()
},
mounted() {
// this.initChart()
this.getMapJson()
}
}
6.最終仿百度中國(guó)疫情地圖就實(shí)現(xiàn)了

補(bǔ)充:關(guān)于visualMap中當(dāng)數(shù)據(jù)為0時(shí),小旗子的顯示,只需要添加symbol屬性設(shè)置為小旗子的base64碼,并設(shè)置其大小即可。