封装echarts china map geo实现dispatch触发geoSelect事件高亮显示某个省份和城市,并定义复杂样式

简介: 封装echarts china map geo实现dispatch触发geoSelect事件高亮显示某个省份和城市,并定义复杂样式

实现如下效果

 


用echarts geo类型的中国地图封装vue组件,具体的地图信息china.json传送门Echarts中国地图china.json_zh1230928_你挚爱的强哥的博客-CSDN博客

<!--强哥的自定义组件:高级封装Echarts之chart-->
<template>
  <div ref="sgChinaMapChart" class="sg-china-map-chart"></div>
</template>
<script>
import china from "./china.json";
export default {
  data() {
    return {
      componentName: "sg-china-map-chart", //组件名称
      chart: null,
      provinces: [],
    };
  },
  props: ["data"],
  beforeDestroy() {
    this.chart && this.chart.off("click");
    this.chart && this.chart.clear();
    this.chart && this.chart.dispose(); //不进行手动销毁echarts,你会卡的要死!!!
  },
  mounted() {
    setTimeout(() => {
      this.init(this.data);
      addEventListener("resize", () => {
        this.chart && this.chart.resize(); //当页面大小变化→图标对应变化
      });
    }, 108); //延时加载只为别太卡!
  },
  methods: {
    showProvinces(provinces) {
      this.provinces = provinces;
      var aa = provinces || [];
      for (var i = 0, l = aa.length; i < l; i++) {
        var a = aa[i];
        this.showProvince(a); //调用高亮显示某个省份
      }
    },
    showProvince(name) {
      // console.log(name);
      this.chart &&
        this.chart.dispatchAction({
          type: "geoSelect",
          // 可选,系列 index,可以是一个数组指定多个系列
          // seriesIndex: 0,
          // 可选,系列名称,可以是一个数组指定多个系列
          // seriesName: string|Array,
          // 数据的 index,如果不指定也可以通过 name 属性根据名称指定数据
          // dataIndex: 1,
          // 可选,数据名称,在有 dataIndex 的时候忽略
          name, //省份的名称(不含“省”)
        });
    },
    hideProvince(name) {
      this.chart &&
        this.chart.dispatchAction({
          type: "geoUnSelect",
          name, //省份的名称(不含“省”)
        });
    },
    init(data) {
      if (!data)
        return this.$message({
          message: `您的组件${this.componentName}没有传参data`,
          type: "error",
        });
      this.$echarts.registerMap("china", china); //这句必须要否则地图不会出现
      // 基于DOM,初始化echarts实例(注意!Vue的DOM日怪的很,一般要腾个1秒才加载完)
      this.chart = this.$echarts.init(this.$refs.sgChinaMapChart);
      // 转换属性为本地■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
      var highlight = data.highlight || {};
      var target = data.target || {};
      var data = data.data || {};
      // series ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
      const dotColor = "white"; //地图上的标记点颜色
      // const dotColor = "#087fd8", //地图上的标记点颜色
      const lineColor = ["#067DD6", "#067dd6"]; //地图省边框线、迁徙轨迹线条颜色(线性渐变:上,下)
      const selectedBorderColor = "#067DD6"; //被选中地图省份边框颜色
      const borderColor = "#A4D9FF"; //地图省份边框颜色
      const selectedAreaColor = ["#1D99F5", "#1D99F5"]; //被选中地图省份填充色(径向渐变:内,外)
      const areaColor = ["#d6edff", "#d6edff"]; //地图省份填充色(径向渐变:内,外)
      const emphasisAreaColor = ["#1D99F5 ", "#1D99F5 "]; //移入地图省份时的填充色(径向渐变:内,外)
      const targetName = target.name;
      const targetCoordinate = target.coordinate;
      var citys = [];
      var moveLines = [];
      var arr = data;
      for (var i = 0, len = arr.length; i < len; i++) {
        var a = arr[i];
        var city = {
          name: a.from,
          value: a.coordinate,
          itemStyle: { normal: { color: lineColor } },
        };
        var moveline = {
          fromName: a.from,
          toName: targetName,
          coords: [a.coordinate, targetCoordinate],
        };
        citys.push(city);
        moveLines.push(moveline);
      }
      targetName &&
        citys.push({
          name: targetName,
          value: targetCoordinate,
          symbolSize: 10, //聚焦的城市点点大小
          itemStyle: { normal: { color: dotColor } },
        });
      this.chart.clear();
      this.chart.setOption({
        //animation: false, //太卡了
        geo: {
          // ----------------------------------------
          // silent: true, //禁止用鼠标点击触发高亮
          selectedMode: "multiple", //⚠⚠⚠这个必须要设置(否则地图不能接受dispatch的geoSelect事件用代码触发选中高亮某个省份)
          // ----------------------------------------
          map: "china",
          zoom: 1.2, //中国地图默认缩放大小
          roam: true,
          // 移入状态高亮情况下的样式
          emphasis: {
            label: {
              show: true, //移入的时候显示文本
              color: "white",
              textBorderColor: selectedBorderColor,
              textBorderWidth: 1,
            },
          },
          // 普通状态下的地图省份样式
          itemStyle: {
            normal: {
              // areaColor: areaColor,
              // 径向渐变,前三个参数分别是圆心 x, y 和半径,取值同线性渐变
              areaColor: {
                type: "radial",
                x: 0.5,
                y: 0.5,
                r: 1.5,
                colorStops: [
                  {
                    offset: 0,
                    color: areaColor[0], // 0% 处的颜色
                  },
                  {
                    offset: 1,
                    color: areaColor[1], // 100% 处的颜色
                  },
                ],
                global: false, // 缺省为 false
              },
              borderColor,
              borderWidth: 1,
            },
            emphasis: {
              // areaColor: emphasisAreaColor, //鼠标指上时的颜色
              // 径向渐变,前三个参数分别是圆心 x, y 和半径,取值同线性渐变
              areaColor: {
                type: "radial",
                x: 0.5,
                y: 0.5,
                r: 1.5,
                colorStops: [
                  {
                    offset: 0,
                    color: selectedBorderColor, // 0% 处的颜色
                  },
                  {
                    offset: 1,
                    color: selectedBorderColor, // 100% 处的颜色
                  },
                ],
                global: false, // 缺省为 false
              },
              borderColor: selectedBorderColor,
              borderWidth: 2,
            },
          },
          // 被选中状态下的地图省份样式
          select: {
            label: {
              show: false, //1.国内业务布局:地图上省份的文字 最好不显示 和设计稿一致
              color: "white",
              textBorderColor: selectedBorderColor,
              textBorderWidth: 1,
            },
            itemStyle: {
              // areaColor: areaColor,
              // 径向渐变,前三个参数分别是圆心 x, y 和半径,取值同线性渐变
              areaColor: {
                type: "radial",
                x: 0.5,
                y: 0.5,
                r: 1.5,
                colorStops: [
                  {
                    offset: 0,
                    color: selectedAreaColor[0], // 0% 处的颜色
                  },
                  {
                    offset: 1,
                    color: selectedAreaColor[1], // 100% 处的颜色
                  },
                ],
                global: false, // 缺省为 false
              },
              borderColor: selectedBorderColor,
              borderWidth: 2,
            },
          },
        },
        series: [
          {
            name: "地点",
            type: "effectScatter",
            coordinateSystem: "geo",
            zlevel: 2,
            rippleEffect: {
              brushType: "stroke",
            },
            label: {
              show: true,
              emphasis: {
                show: true,
                textStyle: {
                  color: dotColor,
                  textBorderColor: selectedBorderColor,
                  textBorderWidth: 1,
                }, //移入地点显示名称样式
                position: "right",
                formatter: "{b}",
              },
            },
            symbolSize: 1, //迁徙轨迹出发点大小
            showEffectOn: "render",
            itemStyle: {
              normal: {
                color: lineColor,
              },
            },
            data: citys,
          },
          {
            name: "线路",
            type: "lines",
            coordinateSystem: "geo",
            zlevel: 2,
            large: true,
            effect: {
              show: true,
              constantSpeed: 30,
              symbol: "pin",
              symbolSize: 5, //迁徙轨迹上面移动的小点点大小
              trailLength: 0,
            },
            lineStyle: {
              normal: {
                // 线性渐变,前四个参数分别是 x0, y0, x2, y2, 范围从 0 - 1,相当于在图形包围盒中的百分比,如果 globalCoord 为 `true`,则该四个值是绝对的像素位置
                color: new this.$echarts.graphic.LinearGradient(
                  0,
                  0,
                  0,
                  1,
                  [
                    {
                      offset: 0,
                      color: lineColor[0],
                    },
                    {
                      offset: 1,
                      color: lineColor[1],
                    },
                  ],
                  false
                ),
                width: 1, //迁徙轨迹线条粗细
                opacity: 0.5, //迁徙轨迹线条透明度
                curveness: 0.1, //迁徙轨迹线条弧度
              },
            },
            data: moveLines,
          },
        ],
      });
      //点击事件,根据点击某个省份计算出这个省份的数据
      this.chart && this.chart.off("click");
      this.chart.on("click", (params) => {
        // ba(params);
        console.log(
          "点击的省份名称:",
          params.name,
          this.provinces,
          this.provinces.includes(params.name)
        );
        this.provinces.includes(params.name)
          ? this.showProvince(params.name)
          : this.hideProvince(params.name);
      });
      // console.log(highlight);
      var aa = highlight.provinces || [];
      for (var i = 0, l = aa.length; i < l; i++) {
        var a = aa[i];
        this.showProvince(a); //调用高亮显示某个省份
      }
    },
  },
};
</script>
<style lang="scss" scoped>
@import "~@/css/sg";
.sg-china-map-chart {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
}
</style>

调用

import sgChinaMapChart from "@/vue/components/sg-charts/sg-china-map-chart"; //引入强哥中国地图
<!-- 强哥的中国地图 -->
<sg-china-map-chart
  ref="chinaMap"
  :data="chinaMapData"
  style="width: 100%; height: 100%"
/>
//在script的data里面加入↓
chinaMapData: {
  highlight: {
    province: "四川",//高亮显示省份
  },
  target: {
    name: "九寨沟",//聚焦的城市名称
    coordinate: [100.301299,31.688516],
  },
  data: [
    //迁徙轨迹
    // { from: "河池", coordinate: [108.08526, 24.69293], count: 1 },
  ],
},


相关文章
|
6月前
|
编译器 C++ 容器
【C++学习手札】基于红黑树封装模拟实现map和set
【C++学习手札】基于红黑树封装模拟实现map和set
|
1月前
|
资源调度 JavaScript API
vue-element-admin 综合开发五:引入 echarts,封装echarts 组件
这篇文章介绍了如何在vue-element-admin项目中引入并封装ECharts组件,以及如何实现折线图、柱状图和饼图的展示。
79 4
vue-element-admin 综合开发五:引入 echarts,封装echarts 组件
|
1月前
|
JavaScript API
Echarts中单独为每个legend图例设置样式-根据数据正负显示不同样式
通过上述方法,我们便能够在ECharts中根据数据的正负为每个图例项设置不同的样式,增强了图表的可读性和表现力。这种方法虽然略显间接,但不失为一种灵活的解决方案。
63 2
|
2月前
|
存储 前端开发 JavaScript
node中循环异步的问题[‘解决方案‘]_源于map循环和for循环对异步事件配合async、await的支持
本文探讨了在Node.js中处理循环异步操作的问题,比较了使用map和for循环结合async/await处理异步事件的差异,并提供了解决方案。
35 0
|
3月前
|
JavaScript
Echarts——VUE中如何给echarts绑定click事件
Echarts——VUE中如何给echarts绑定click事件
184 1
|
5月前
|
JavaScript 开发工具 git
大事件项目17----Vue项目引入Echarts
大事件项目17----Vue项目引入Echarts
大事件项目17----Vue项目引入Echarts
|
4月前
|
C++ 容器
【C++】map和set封装
【C++】map和set封装
38 2
|
4月前
|
存储 C++ 容器
【C++】开散列实现unordered_map与unordered_set的封装
【C++】开散列实现unordered_map与unordered_set的封装
52 0
|
4月前
echarts 报错 —— Component series.map not exists. Load it first
echarts 报错 —— Component series.map not exists. Load it first
133 0
|
6月前
|
存储 C语言 C++
从C语言到C++_31(unordered_set和unordered_map介绍+哈希桶封装)(上)
从C语言到C++_31(unordered_set和unordered_map介绍+哈希桶封装)
56 3