vue + echarts 实现简单中国地图

在这里插入图片描述
需求:画出全国地图,根据后台返回数据,在地图上标出对应的地点(map + 散点)

准备工作:
  • 安装依赖
npm install echarts -S
  • 在main.js中引入
import echarts from 'echarts'
Vue.prototype.$echarts = echarts;
  • 在需要画地图的页面引入地图的 js 或者 json 文件,官方已经不提供下载很久了,我自己在网上找了一份 json datas.json 点击下载 (经纬度多少有点误差,仅供参考)
    将该文件放在项目中(我放在了static目录下),引入
    import geoData from "../../../../../static/json/datas.json";
以下为代码:
<template>
<div>
  <div :id="chartId" style="height:100%;width:100%;"></div>
</div>
</template>

<script>
import geoData from "../../../../../static/json/datas.json";
export default {
  data() {
    return {
      windowSize: [0, 0],
      chartId: `map-${this.$root.UUID()}`,		//用UUID生成图表id,防止id重复
      chart: { map: null, chartData: [], },
    }
  },
  watch: { windowSize() { this.chart.map.resize() }, },		//监听页面窗口变化
  mounted() {
    this.initChart();
    this.$nextTick(() => { this.drawChart(); });
  },
  methods: {
    initChart() {
      let _this = this
      _this.windowSize = [document.body.clientWidth, document.body.clientHeight];
      window.addEventListener('resize', () => { _this.windowSize = [document.body.clientWidth, document.body.clientHeight]; });
      _this.chart.map = _this.$echarts.init(document.getElementById(_this.chartId))
    },
    drawChart() {
      let _this = this;
      let mapName = 'china'
      let geoCoordMap = {};
      let tempData = [			//模拟数据
      {city:'北京',value:'55'},
      {city:'天津',value:'20'},
      {city:'西藏',value:'100'},
      {city:'辽宁',value:'58'},
      ]

      _this.chart.map.showLoading();		//loading样式

      let mapFeatures = _this.$echarts.getMap(mapName).geoJson.features;	//获取全国地区的经纬度(只包含了一级城市、省份经纬度)
      _this.chart.map.hideLoading();			//隐藏loading样式
      mapFeatures.forEach(function (v) { //获取一级城市、省份经纬度
        let name = v.properties.name; // 地区名称
        geoCoordMap[name] = v.properties.cp; // 地区经纬度
      });

      let convertData = function (tempData) { 				//通过该方法获取自己数据中各地区的经纬度
        let tempRes = [];
        for (let i = 0; i < tempData.length; i++) {
          let geoCoord = geoCoordMap[tempData[i].name] || [];
          if (geoCoord) {
            tempRes.push({
              name: tempData[i].name,
              value: geoCoord.concat(tempData[i].value) || [],
            });
          }
        }
        for (let i = 0; i < tempRes.length; i++) {
          let tempGeoCoord = geoData.rows.filter(t => { return t.name.includes(tempRes[i].name) })
          if (tempGeoCoord && tempRes[i].value.length == 1) {
            tempRes[i].value.unshift(tempGeoCoord[0].lat)
            tempRes[i].value.unshift(tempGeoCoord[0].lng)
          }
        }
        return tempRes;
      };
      _this.chart.map.setOption({					//开始画图
        geo: {
          map: 'china',
          label: { show: false, }, 				// 是否显示对应地名
          roam: true,
          itemStyle: {
            normal: {
              borderWidth: 1, // 地图边框宽度
              borderColor: '#fff', // 地图边框颜色
              areaColor: '#0FADFF' // 地图颜色
            },
            emphasis: { areaColor: '#0FADFF', borderWidth: 2 }		//高亮时的样式
          },
          emphasis: { areaColor: '#0FADFF', borderWidth: 2, label: { show: false } }
        },
        tooltip: {
          triggerOn: 'mousemove',
          trigger: 'item',
          extraCssText: 'background:transparent;border:none;',
          formatter: function (params) {
            let count = eval(convertData(tempData).map(a => { return a.value[2] }).join('+'))
            let content = `<div class='tooltip'>${params.name}&nbsp;${params.value[2]}户&nbsp;${(params.value[2]/count*100).toFixed(2)}%`;
            return (content += `</div>`);
          }
        },
        series: [{
            name: '散点',
            type: 'scatter',
            coordinateSystem: 'geo',
            color: "#5ADD8B", 				//点的颜色
            data: convertData(tempData),
            symbolSize: 10, 				//点的大小
            symbol: "circle", 				//点的样式
            cursor: "pointer", 			//鼠标放上去的效果
            label: {
              normal: { show: false }, 		//默认展示 
              emphasis: { show: false }	 //滑过展示
            },
            itemStyle: { color: '#5ADD8B', emphasis: { borderColor: '#fff', borderWidth: 1 } }
          },
          {
            type: 'map',
            map: 'china',
            geoIndex: 0,
            silent: true,
            hoverable: false,
            aspectScale: 0.75,
            tooltip: { show: false }
          },
        ],
      });
       // 取消框架自带的高亮,只高亮散点
      // _this.chart.map.on('mouseover', (v) => {
      //   let enlarge = convertData(tempData).map(a => { return a.name })
      //   let point = enlarge.findIndex(t => { return t == v.name })
      //   if (point < 0) { _this.chart.map.dispatchAction({ type: 'downplay', dataIndex: v.dataIndex }); }
      // });
      
      // 鼠标滑动到散点外不显示tip
      _this.chart.map.on('mouseover', (v) => { 
        let enlarge = convertData(tempData).map(a => { return a.name })
        let point = enlarge.findIndex(t => { return t == v.name })
        if (point < 0) { _this.chart.map.dispatchAction({ type: 'hideTip', dataIndex: v.dataIndex }); }
      });
      _this.$nextTick(() => { _this.chart.map.resize() })
    },
  },
}
</script>

<style lang="scss">
  .tooltip {
    color: rgba(50, 50, 50, 1);
    padding: 6px 9px 11px 9px;
    background: rgba(255, 255, 255, 1);
    box-shadow: 0px 2px 10px 2px rgba(0, 0, 0, 0.1);
}
</style>

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值