详解vue中使用echarts地图实现上钻下钻的可视化 三级下钻 省>市>县

简述功能概要

最近有需求作一个数据可视化的功能 会具体显示全国各地区的买家分布状况 javascript

鼠标放置在地图上会显示当前城市的分布人数 点击当前省份会下钻到城市地图 会显示当前省市下各个城市的买家数和分布状况html

若是遇到没有下一级再次点击会进行返回到国家地图(目前该示例图是两级下钻 省>区市 )(还能够实现点击按钮返回到上一级)vue

右侧数据表会跟随城市的切换而进行动态切换(无视数据的准确性) java

准备工做

首先须要全部城市地图的json文件和一个城市行政区域划代码的js文件(本文件请求使用)(若有须要可跟与我联系) ios

 

获取到当前json和js文件以后须要把json文件放置在服务器中 进行请求回去当前某个城市的json地图文件,亦可放置在static中进行axios请求获取,js文件放置在本地的assets中进行获取json

准备好这两项工做后 咱们能够开始进行书写代码 生成echarts地图图表axios

生成地图图表

import cityMap from "../../../assets/map/china-main-city-map.js";
import echarts from "echarts";

首先在vue文件中引入echarts和区域代码js文件.服务器

//中国地图(第一级地图)的ID、Name、Json数据
var chinaId = 100000;
var chinaName = "china";
var chinaJson = null;
//Echarts地图全局变量,主要是在返回上级地图的方法中会用到
var myChart = null;
var cityId = null;

定义变量使用echarts

具体实现代码(以及实现步骤)

<div id="mapChart" class="chart"></div>

 

mapChart(divid) {
      this.mapData = [];
      var that = this;
        //chinaId 为上边定义的变量 值为100000
      Vue.axios({
        url:
          "https://gdsoft-/echart/map/" +
          chinaId +
          ".json",
        withCredentials: false,
      }).then((response) => {
        //进入页面后 传递的参数为全国的id 而后向json文件发起请求 找到文件名为100000的json文件
         //获取到全国的地图文件 渲染出来
        const mapJson = response.data;
        //调用数据获取省份数据
        let data = {
          from: this.allStartDate,
          to: this.allEndDate,
          areaCode: chinaId,
        };

        Vue.axios({
          method: "POST",
          serviceId: "mall",
          url: "123456789",
          data,
        }).then((res) => {
        //这里为右侧的table数据展现   
        //发起请求 获取到全国的省市的json数据
          this.mapChinaOptions = res.result;
          for (var i = 0; i < mapJson.features.length; i++) {
             //mapData为定义的变量  获取到当前因此省份地图json文件中的省份名和区域划代码
            this.mapData.push({
              name: mapJson.features[i].properties.name,
              id: mapJson.features[i].id,
              value: 0,
            });
          }
            //让json地图文件中的区域划代码和请求返回的行政编码做比较 若是相等 
            // 进获取数据进行赋值
          this.mapData.forEach((item) => {
            this.mapChinaOptions.forEach((item1) => {
              if (item.id == item1.areaCode) {
                item.value = item1.buyerCount;
              }
            });
          });
        });

        //省份的json数据赋值
        chinaJson = mapJson;
        //生成图表
        myChart = echarts.init(document.getElementById(divid));
        //把上边的数据 都当作参数传递给 函数中
        this.registerAndsetOption(myChart, chinaName, mapJson);
        this.mapChartOption.series[0].data = this.mapData;

        //这里为当点击某个省份或城市的时候的点击事件
        myChart.on("click", function (param) {
          that.show = 0;
          that.mapData2 = [];
          cityId = cityMap[param.name];
          // 获取到当前点击的这个城市的 code
          //若是有这个城市的id 就能够请求json 获取子级地图信息
          if (cityId) {
            //表明有下级地图
            Vue.axios({
              url:
                "https://gds/echart/map/" +
                cityId +
                ".json",
              withCredentials: false,
            }).then((response) => {
              // 获取到城市新的json数据
              const mapJson = response.data || response;
              this.getCityData = response.data || response;

              let data = {
                from: that.allStartDate,
                to: that.allEndDate,
                areaCode: cityId,
              };
              Vue.axios({
                method: "POST",
                serviceId: "mall",
                url: "123456789",
                data,
              })
                .then((res) => {
                  if (res.success) {
                    that.mapData2 = [];
                    this.mapCityOptions = res.result;
                    that.payDataList = res.result;
                    //从新获取相同的数据 给 that.mapData2赋值
                    for (var i = 0; i < this.getCityData.features.length; i++) {
                      that.mapData2.push({
                        name: this.getCityData.features[i].properties.name,
                        id: this.getCityData.features[i].id,
                        value: 0,
                      });
                    }
                    that.mapData2.forEach((item) => {
                      this.mapCityOptions.forEach((item1) => {
                        if (item.id == item1.areaCode) {
                          item.value = item1.buyerCount;
                        }
                      });
                    });

                    //从新调用 生成新的地图
                    that.registerAndsetOption(myChart, param.name, mapJson);
                    //把数据传递给图表data
                    that.mapChartOption.series[0].data = that.mapData2;
                  } else {
                    Message.error("获取买家地域分布数据失败,请稍后重试!");
                  }
                })
                .catch((err) => {
                  Message.error("获取买家地域分布数据失败,请稍后重试!");
                });
            });
          } else {
            that.show = 1;
            // 若是没有就在最后一级 再次点击返回中国地图
            //把上边的数据 都当作参数传递给 函数中
            that.registerAndsetOption(myChart, chinaName, mapJson);
            //返回中国地图 而且把数据从新赋值 给data 防止返回的时候 data数据为空了
            that.mapChartOption.series[0].data = that.mapData;
          }
        });
      });
    },
    

    registerAndsetOption(myChart, name, mapJson) {
      //把获取到的城市name和 城市地图json 用来注册地图
      echarts.registerMap(name, mapJson);
      //图表的配置文件
      this.mapChartOption = {
        //鼠标放置在地图上的显示
        tooltip: {
          trigger: "item",
          formatter: (p) => {
            //这里p能够获取到全部的数据
            let val = p.value;
            if (window.isNaN(val)) {
              val = 0;
            }
            let txtCon =
              "<div style='text-align:center'>" +
              p.name +
              ":<br />地域分布数:" +
              val +
              "</div>";
            return txtCon;
          },
        },
        series: [
          {
            type: "map",
            map: name,
            itemStyle: {
              normal: {
                //未选中样式
                //背景颜色
                areaColor: "#e8effd",
                //边框颜色
                borderColor: "#fbfdfe",
                //边框宽度
                borderWidth: 1,
              },
              emphasis: {
                // 选中样式
                borderWidth: 1,
                //高亮颜色
                areaColor: "#2062e6",
                label: {
                  //显示文字
                  show: false,
                  textStyle: {
                    //鼠标移入的字体颜色
                    color: "black",
                  },
                },
              },
            },

            data: [],
          },
        ],
      };
      myChart.setOption(this.mapChartOption, true);
    },
图表宽度自适应
  mounted() {
    this.mapChart("mapChart");
    // 自适应
    window.onresize = () => {
      myChart.resize();
    };
  },
// 监听图表数据的变化
  watch: {
  
    mapChartOption: {
      handler(newVal, oldVal) {
        if (myChart) {
          // 如何有变化 就获取最新的数据 而且渲染
          myChart.setOption(newVal);
        } else {
          // 如何无变化 仍是老数据
          myChart.setOption(oldVal);
        }
      },
      deep: true,
    },
  },

具体的实现步骤能够看代码有步骤的具体实现和业务代码函数

 

简述具体思路

当前有一个本地的行政区域划代码的js文件  和 一个地图城市信息的json文件

初始化的时候会获取全国的区域代码 而后和 json文件中的区域代码匹配 而后请求匹配的json文件

会获取到全国的地图信息 经过 echarts渲染出来

当点击具体省份的时候 会获取当前省份的 区域代码 和 json文件的区域代码匹配 而后请求匹配的json文件

会获取到省市的地图信息 经过 echarts渲染出来

三级下钻同理

若是点击没有下一级城市 会从新获取全国的地图文件 至关于返回 

具体有问题能够与我联系 新人一个 勿喷