Echarts仿百度中國(guó)疫情地圖實(shí)現(xiàn)(Vue)

??近期做了一些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è)置其大小即可。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容