其他分享
首页 > 其他分享> > vue 项目中使用 echarts 实现市区地图(带标注)?

vue 项目中使用 echarts 实现市区地图(带标注)?

作者:互联网

安装依赖

安装 echarts 和 echarts-gl 依赖包 。

npm i echarts echarts-gl -S

assets 下新增 mapdata 资源包(中国各省市 json 文件)

可以在网上自行查找下载,也可通过本文案例链接,在码云上拉取获得 。 完整示例链接icon-default.png?t=L892https://gitee.com/wu241617/echarts-map

assets 下新增 config 目录,下新建 map.json 文件

我这里案例中只做了抚州市和荆州市的配置,后续有其他区域需要,新增添加即可 。文件中 coord 字段是对应 name 子区域的经纬度,可以在网上搜索查询,后续这里要进行微调,控制标注的位置 。
区域经纬度icon-default.png?t=L892https://max.book118.com/html/2021/0507/6030102121003144.shtm

{
  "抚州市": {
    "geoJson": "/geometryCouties/361000.json",
    "qxwz": [
      {
        "name": "东乡区",
        "coord": [116.6, 28.18]
      },
      {
        "name": "临川区",
        "coord": [116.35, 27.98]
      },
      {
        "name": "金溪县",
        "coord": [116.75, 28]
      },
      {
        "name": "崇仁县",
        "coord": [116.05, 27.79]
      },
      {
        "name": "宜黄县",
        "coord": [116.25, 27.5]
      },
      {
        "name": "南城县",
        "coord": [116.66, 27.65]
      },
      {
        "name": "资溪县",
        "coord": [117.05, 27.8]
      },
      {
        "name": "乐安县",
        "coord": [115.83, 27.47]
      },
      {
        "name": "南丰县",
        "coord": [116.45, 27.24]
      },
      {
        "name": "黎川县",
        "coord": [116.85, 27.2]
      },
      {
        "name": "广昌县",
        "coord": [116.35, 26.87]
      }
    ]
  },
  "荆州市": {
    "geoJson": "/geometryCouties/421000.json",
    "qxwz": [
      {
        "name": "洪湖市",
        "coord": [113.59, 30.02]
      },
      {
        "name": "江陵县",
        "coord": [112.49, 30.01]
      },
      {
        "name": "荆州区",
        "coord": [112.08, 30.49]
      },
      {
        "name": "沙市区",
        "coord": [112.35, 30.41]
      },
      {
        "name": "松滋市",
        "coord": [111.62, 30.03]
      },
      {
        "name": "公安县",
        "coord": [112.12, 29.87]
      },
      {
        "name": "监利县",
        "coord": [112.96, 29.91]
      },
      {
        "name": "石首市",
        "coord": [112.51, 29.82]
      }
    ]
  }
}

组件中使用案例

<template>
  <div>
    <select v-model="selectCity"
      @change="cityChange"
      class="select">
      <option :label='item.name'
        :value="item.value"
        v-for="item in options"
        :key="item.value"></option>
    </select>
    <div class="selectedText">{{selectedText}}</div>
    <div class="mapMain"
      id="mapMain"></div>
  </div>
</template>

地图配置中, geo 数组中有两个子项,渲染两个地图,通过控制 center 属性值配置,形成微错位,视觉上立体, 注意 center 值要处于当前区域经纬度之间,需要微调否则看不到地图渲染 ,其他具体配置请查看官方文档配置项。
官方文档icon-default.png?t=L892https://echarts.apache.org/zh/option.html#title

import * as echarts from 'echarts';
import 'echarts-gl';
import { mapState } from 'vuex'

export default {
  name: 'Main',
  data() {
    return {
      selectCity: '361000',
      mapConfigJson: require("../../assets/config/map.json"),
      map: '',
      mapLoadCity: '',
      cityName: [],
      mapdataJson: [],
      selectedText: ''
    }
  },
  mounted() {
    this.cityChange();
  },
  computed: {
    ...mapState(['JZtestData', 'FZtestData', 'options'])
  },
  methods: {
    // 下拉框城市区域切换  
    cityChange() {
      this.selectedText = ''
      this.cityName = []
      this.options.map(item => {
        if (item.value === this.selectCity) {
          this.mapLoadCity = item.name
          this.cityName.push(item.name)
        }
      })
      this.mapChart();
    },
    //显示地图
    mapChart() {
      this.map = echarts.init(document.getElementById('mapMain'));
      this.initMenu();
      this.map.on("click", this.mapClick);
    },
    //地图点击事件
    mapClick(param) {
      this.selectedText = `当前选中区域为: ${this.mapLoadCity}--${param.name}`;
    },
    initMenu() {
      this.loadMap(this.mapLoadCity, this.loadData(this.mapLoadCity));
    },
    loadData(mapLoadCity) {
      if (mapLoadCity === '荆州市') {
        return this.JZtestData;
      }
      if (mapLoadCity === '抚州市') {
        return this.FZtestData;
      }
    },
    /**
      * 加载地图
      * @param name
    */
    loadMap(name, mapdataJson) {
      let markPointData = this.mapConfigJson[name]["qxwz"];
      if (!this.mapConfigJson[name].geoJson) {
        return;
      }
      let geoJson = require("../../assets/mapdata" + this.mapConfigJson[name].geoJson);
      echarts.registerMap(name, geoJson);
      let dataColor = () => {
        let colorlist = [];
        for (let i = 0; i < mapdataJson.length; i++) {
          if (mapdataJson[i].value < 1000) {
            colorlist.push("rgb(207,234,254)");
          } else if (mapdataJson[i].value >= 1000 && mapdataJson[i].value < 2000) {
            colorlist.push("rgb(138,184,252)");
          } else if (mapdataJson[i].value >= 2000 && mapdataJson[i].value < 3000) {
            colorlist.push("rgb(101,162,249)");
          } else if (mapdataJson[i].value >= 3000) {
            colorlist.push("rgb(79,132,235)");
          }
        }
        return colorlist;
      }
      let option = {
        // backgroundColor: '#000f1e',
        geo: [
          {
            geoIndex: 0,
            z: 1,
            type: 'map',
            map: name,
            center: [116.38, 27.56],
            // roam: true,
            zoom: 1,
            aspectScale: 1.3, //长宽比
            scaleLimit: {
              "min": 1.1,
              "max": 15
            },
            label: { //标签样式设置
              show: true,
              fontSize: 14,
              color: 'rgba(255,255,255)',
            },
            itemStyle: {
              normal: {
                borderColor: "#fff",
                borderWidth: 1,
                areaColor: 'rgb(207,234,254)',
                fontWeightL: 700,
              },
              emphasis: {
                areaColor: 'rgb(243,215,115)',
                borderWidth: 0
              }
            },
            select: {
              itemStyle: {
                areaColor: 'rgb(243,215,115)',
                // color:  ,
                borderColor: '#fff',
                borderWidth: 3,
                shadowOffsetX: 0,
                shadowOffsetY: 0,
                opacity: 1,
              }
            },
            selectedMode: 'multiple',
          },
          {
            geoIndex: 0,
            map: name,
            z: 0,
            zoom: 1,
            // roam: true,
            center: [116.348, 27.58],
            aspectScale: 1.3, //长宽比
            scaleLimit: {
              "min": 1.1,
              "max": 15
            },
            label: { //标签样式设置
              show: true,
              fontSize: 14,
              color: 'rgba(150,181,246,0)',
            },
            itemStyle: {
              normal: {
                shadowColor: '#ececec',
                shadowOffsetX: 5,
                shadowOffsetY: 5,
                // borderColor: 'rgb(58,82,154)',
                borderColor: "#fff",
                borderWidth: 1,
                areaColor: 'rgb(187,217,253)',
              },
              emphasis: {
                areaColor: 'rgb(187,217,253)',
                borderWidth: 0
              },
            }
          },
        ],
        visualMap: [{
          min: 0,
          max: 10,
          left: 'left',
          top: 'bottom',
          text: ['高', '低'],
          calculable: true,
          show: false,
          inRange: {
            color: dataColor()
          }
        }],
        color: ['white'],
        series: [
          {
            name: "热力图",
            type: "heatmap",
            coordinateSystem: "geo",
            geoIndex: 0,
            markPoint: { //标记点
              // symbol: 'image://' + require("../../assets/img/mapIndex/dhk.png"),
              // symbol: "<div style='width: 0.5rem; height: 0.03rem; background-color: #fff; border-radius: 50% 0;'></div>",
              symbol: 'roundRect',
              // symbol: 'path://m 0,0 h 48 v 20 h -30 l -6,10 l -6,-10 h -6 z',
              symbolKeepAspect: true,
              symbolSize: [35, 15], //图形大小
              label: {
                width: 100,
                height: 50,
                normal: {
                  color: '#000',
                  formatter: function (params) {
                    for (let i = 0; i < mapdataJson.length; i++) {
                      if (mapdataJson[i].name == params.name) {
                        return mapdataJson[i].value;
                      }
                    }
                  },
                  show: true,
                },
                emphasis: {
                  show: true,
                }
              },
              itemStyle: {
                color: '#fff',
              },
              data: markPointData
            }
          },
          {
            name: '地市',
            type: 'map',
            geoIndex: 0,
            data: this.getMapColor(geoJson)
          }
        ]
      };
      if (this.mapLoadCity === '荆州市') {
        option.geo[0].center = [112.71, 29.71];
        option.geo[0].zoom = 1.2;
        option.geo[1].center = [112.73, 29.73];
        option.geo[1].zoom = 1.2;
      }
      this.map.setOption(option, true);
    },
    /**
     * 生成地图颜色
     * @param geoJson
     * @returns {Array}
     */
    getMapColor(geoJson) {
      let list = [];
      for (let i in geoJson.features) {
        let feature = geoJson.features[i];
        let name = feature.properties.name;
        let json = {};
        json.name = name;
        json.value = i % 11;
        if (this.cityName.length == 2) {
          if (this.cityName[1] == name) {
            json.selected = true;
          }
        }
        list.push(json);
      }
      return list;
    },
  }
}

组件内

.mapMain {
  width: 1000px;
  height: 750px;
}

全局(在 assets 下新建 CSS 目录,下新增 common.css 文件)

* {
    margin: 0;
    padding: 0;
}

html,
body {
    font-size: 20px;
    font-family: '楷体' !important;
    width: 100%;
    height: 100%;
    box-sizing: border-box;
}

.home {
    width: 1000px;
    height: 800px;
    border: 1px solid black;
    padding: 10px;
    margin: 0 auto;
}

.header {
    width: 100%;
    height: 50px;
    text-align: center;
    line-height: 50px;
    color: white;
    background: black;
}

.main {
    width: 100%;
    height: 750px;
    background: lavender;
    position: relative;
    z-index: 1;
}

.select {
    position: absolute;
    top: 20px;
    left: 20px;
    width: 80px;
    height: 30px;
    border: 1px solid rgba(0, 0, 0, .4);
    cursor: pointer;
    text-align: center;
    line-height: 30px;
    z-index: 999;
}

.selectedText {
    border-bottom: 2px solid lightblue;
    position: absolute;
    top: 20px;
    right: 20px;
    font-size: 15px;
    z-index: 999;
}

模拟后端请求到的地图数据,存放在 store 下的 index.js 文件中的 state 内 。

/*
 * @Descripttion: 
 * @version: 1.0
 * @Author: wuhao
 * @Date: 2021-09-16 09:18:42
 * @LastEditors: wuhao
 * @LastEditTime: 2021-09-18 11:13:44
 */
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
    state: {
        JZtestData: [{
                name: "洪湖市",
                qxdm: "421083",
                value: 654
            },
            {
                name: "江陵县",
                qxdm: "421024",
                value: 13
            },
            {
                name: "荆州区",
                qxdm: "421003",
                value: 4222
            },
            {
                name: "沙市区",
                qxdm: "421002",
                value: 1854
            },
            {
                name: "松滋市",
                qxdm: "421087",
                value: 1023
            },
            {
                name: "公安县",
                qxdm: "421022",
                value: 10
            },
            {
                name: "监利县",
                qxdm: "421023",
                value: 2183
            },
            {
                name: "石首市",
                qxdm: "421081",
                value: 12
            }
        ],
        FZtestData: [{
                name: "东乡区",
                qxdm: "361029",
                value: 654
            },
            {
                name: "临川区",
                qxdm: "361002",
                value: 13
            },
            {
                name: "金溪县",
                qxdm: "361027",
                value: 4222
            },
            {
                name: "崇仁县",
                qxdm: "361024",
                value: 1854
            },
            {
                name: "宜黄县",
                qxdm: "361026",
                value: 1023
            },
            {
                name: "南城县",
                qxdm: "361021",
                value: 10
            },
            {
                name: "资溪县",
                qxdm: "361028",
                value: 2183
            },
            {
                name: "乐安县",
                qxdm: "361025",
                value: 12
            },
            {
                name: "南丰县",
                qxdm: "361023",
                value: 10
            },
            {
                name: "黎川县",
                qxdm: "361022",
                value: 2183
            },
            {
                name: "广昌县",
                qxdm: "361030",
                value: 12
            }
        ],
         options: [{
             name: '荆州市',
             value: '421000'
         }, {
             name: '抚州市',
             value: '361000'
         }]
    },
    mutations: {},
    actions: {},
    modules: {}
})

完整示例链接icon-default.png?t=L892https://gitee.com/wu241617/echarts-map

标签:map,vue,name,qxdm,value,coord,echarts,标注
来源: https://blog.csdn.net/qq_44722915/article/details/120364450