当前位置:   article > 正文

echart之map地图图表使用教程_echart map

echart map

本文以echarts展示成都地图为例子。

效果展示

在这里插入图片描述
悬浮点击后高亮
在这里插入图片描述

准备阶段

获取地图geojson数据

获取所需地址的json数据

在这里插入图片描述

注意:目前成都市geojson数据没有新增的几大区(高新区,天府新区,东部新区),若需要可以在博士的资源下载,或者关注一波,私信可免费获得。

安装echarts

npm install echarts
  • 1

注意:Echarts版本号超过4.9就不能使用地图软件了,所以需要先卸载高版本再安装

// 卸载echarts运行:
npm uninstall echarts

// 安装4.9版本的echarts
npm install echarts@4.9.0 --save
  • 1
  • 2
  • 3
  • 4
  • 5

开始绘制

容器准备

//vue3+ts
 <div ref="centerChartmap" ></div>
 
//其他
<div id="centerChartmap" ></div>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

js代码

import {ref,onMounted,markRaw,defineEmits} from "vue";
import * as echarts from "echarts";
import arrMap from "./map.json"; //地图json数据

const emit = defineEmits(["clickChild"]); //地图点击后传入父组件点击数据

let chartInstance = ref();// 初始化图表对象

onMounted(() => {
    initChart();  // 图表初始化
});
const initChart = () => {
  // 定义实例 vue3用ref定义echarts要使用markRaw 后文有解释
   chartInstance.value =markRaw(echarts.init(centerChartmap.value, "myTheme")); 
   //或chartInstance.value=echarts.init(document.getElementById('centerChartmap')
   
  echarts.registerMap("china", { geoJSON: arrMap }); 
  //注册可用的地图并添加geojson数据,只在 geo组件或者 map 图表类型中使用。
  let optionMap = {
    geo: {
      map: "china",
      roam: true,
      center: [ 103.909956,30.775001], //定义中心点
      layoutSize: "100%",
      selectedMode: "single",
      regions: [ //隐藏南海诸岛
        {
          name: "南海诸岛",
          itemStyle: {
            // 隐藏地图
            normal: {
              opacity: 0, // 为 0 时不绘制该图形
            },
          },
          label: {
            show: false, // 隐藏文字
          },
        },
      ],
      zoom: 12,
      //点击后颜色样式设置
      select: {
        itemStyle: {
          borderWidth: 2.5,
          areaColor: "rgb(8, 207, 221)",
          shadowColor: "rgba(255, 255, 255, 0.3)",
          shadowBlur: 10,
          shadowOffsetX: 4,
          shadowOffsetY: 4,
        },
      },
      //图形上的文本标签,可用于说明图形的一些数据信息
      label: {
        normal: {
          show: true,
          fontSize: "10",
          color: "#fff",
        },
      },
      //地图区域的多边形 图形样式,有 normal 和 emphasis 两个状态
      itemStyle: {
        //normal 是图形在默认状态下的样式;
        normal: {
          areaColor: "rgb(5,66,200,0.8)",
          borderColor: "#26e3ff", //线
        },
        //emphasis 是图形在高亮状态下的样式,比如在鼠标悬浮或者图例联动高亮时。
        emphasis: {
          areaColor: "#26e3ff",
          shadowOffsetX: 0,
          shadowOffsetY: 0,
          shadowBlur: 20,
          borderWidth: 0,
          shadowColor: "rgba(0, 0, 0, 0.5)",
        },
      },
    },
    colorBy: "series",
    series: [
      {
        name: "信息量",
        type: "map",
        mapType: "china",
        geoIndex: 0,
        data: [], //可设置初始选中值[{ name: '武侯区', selected: true }],
      },
    ],
  };
  chartInstance.value.setOption(optionMap);
  
  chartInstance.value.on("click", function (params) {
    //将点击的区域数据传递给父组件
    emit("clickChild", params.name);
  });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94

补充事项

vue3.0 用ref定义echarts报错

Uncaught (in promise) TypeError: Cannot read properties of undefined (reading ‘type‘)
在这里插入图片描述

  • 官方解释

你可以有选择地退出默认的深度响应式/只读转换模式,并将原始的,未被代理的对象嵌入状态图中。它们可以根据情况灵活运用:
有些值不应该是响应式的,例如复杂的第三方类实例或 Vue 组件对象。(第三方实例)
当渲染具有不可变数据源的大列表时,跳过 proxy 转换可以提高性能。

  • 解决方案

在实例化echart时,将其指定为非响应式的

import { markRaw } from 'vue'
chartInstance.value = markRaw(echarts.init(centerChartmap.value, "myTheme"));
  • 1
  • 2

toRaw、markRaw 扩展

toRawmarkRaw
将一个由reactive生成的响应式对象转为普通对象。标记一个对象,使其永远不会再成为响应式对象。
用于读取响应式对象对应的普通对象,对这个普通对象的所有操作,不会引起页面更新。有些值不应被设置为响应式的,例如复杂的第三方类库等。当渲染具有不可变数据源的大列表时,跳过响应式转换可以提高性能。

echarts map扩展需求

地图隐藏南海诸岛

  • 第一种方案
 let optionMap = {
 ...
   geo: {
     ...
      regions: [
        {
          name: "南海诸岛",
          itemStyle: {
            normal: {
              opacity: 0, // 为 0 时不绘制该图形
            },
          },
          label: {
            show: false, // 隐藏文字
          },
        },
      ],
    ...
    },
    ...
   }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 第二种方案
    因为中国地图的名字叫china才会显示南海诸岛,别的名字不会显示,我们取其他名字就行啦。
    在这里插入图片描述

地图显示提示框

在这里插入图片描述

 let optionMap = {
 ...
    // 提示浮窗样式
    tooltip: {
      show: true,
      trigger: "item", //坐标轴触发,主要在柱状图,折线图等会使用类目轴的图表中使用
      axisPointer: {
        // 坐标轴指示器,坐标轴触发有效
        type: "shadow", // 默认为直线,可选为:'line' | 'shadow'
      },
      alwaysShowContent: false,
      backgroundColor: "rgba(36, 215, 209, 1)", //提示框背景色
      borderColor: "rgba(255, 255, 255, 1)",
      triggerOn: "mousemove",
      enterable: true, //鼠标是否可进入提示框浮层中
      textStyle: {
        fontSize: "12",
        overflow: "break",
      },
      formatter: function (params) {
        //提示框显示的内容
        let str = "";
        str = `<div> ` + params.name + `</div>`;
        return str;
      },
    },
    ...
   }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

地图实现下钻

下钻简而言之,在地图的点击事件回调中,加载了另一份地图的json并注册地图,然后再setOption中更改了地图名字,可以前端保存json数据,但最好还是后端返回,点击时前端请求比较好。

在这里插入图片描述

在这里插入图片描述

  chartInstance.value.on("click", function (params) {
   ...
     if (params.componentSubType == 'map') {
         goDown(params.name,optionMap)
    }
  });
 const goDown=(name,optionMap)=>{
    if (!echarts.getMap(name)) {
        const newMapJson = echarts.registerMap(name, { geoJSON: import('./map/'+name+'.json')})
         optionMap.geo.map = mapname
         optionMap.series[0].map = mapname
        chartInstance.value.setOption(optionMap);
     }
 }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

地图实现回钻

与下钻一个意思,不过回钻是往回走,我们只要把每一次地图的显示存入一个数组,回钻时取最后一个就行了。

//用来存放当前的地图名字
let currentName =ref('')
//用来存放下钻的历史记录
let history =ref([])
...
  chartInstance.value.on("click", function (params) {
   ...
     if (params.componentSubType == 'map') {
         goDown(params.name,optionMap)
    }
  });
 const goDown=(name,optionMap)=>{
    if (!echarts.getMap(name)) {
        const newMapJson = echarts.registerMap(name, { geoJSON: import('./map/'+name+'.json')})
         optionMap.geo.map = mapname
         optionMap.series[0].map = mapname
         history.push(currentName) //点击时存入
         chartInstance.value.setOption(optionMap);
         currentName = name
     }
 }

   const returnUpLevel=(optionMap)=>{
    //先判断history有没有数据,能不能返回
    if(history.length == 0){
        return false
    }
    //取出要返回的那个名字
    const name = history.pop() //pop删除数组最后一个元素并返回该元素。
    const currentJson = echarts.getMap(mapname).geoJson
    //修改地图配置重新绘制地图
    //因为之前地图是已经绘制了的,只是把后面的遮盖了,所以数据是存在的,我们不需要在重新设置数据源了
    optionMap.geo.map = mapname
    optionMap.series[0].map = mapname
    chart.setOption(optionMap)
    //修改当前的层级,名字
    currentName = name
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

地图实现给特定区域添加图标

在这里插入图片描述

let optionMap={
...
 series: [
      {
        type: "scatter",
        zoom: 1,
        coordinateSystem: "geo",
        data: [
          {
            name: "天府新区",
            value: [104.11399841308594, 30.407471430197215], //图标坐标及大小
            type: "iconData",
          },
          {
            name: "东部新区",
            value: [104.35875962495804, 30.32959455353757],
            type: "iconData",
          },
          {
            name: "高新南区",
            value: [104.04893657684326, 30.608679048796095],
            type: "iconData",
          },
        ],
        symbol:'image://data:image/png;base64,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',//图片路劲,必须用BASE64编码格式!!!!
        z: 2,
        //  symbolOffset: [0, -40], //偏移量
        symbolSize: [20, 30], // symbols图标大小
      },
...
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 也可以直接引入图片,做如下操作转化为base64

import baseBg from ‘./baseBg.jpg’
let markImg=‘image://’+baseBg
//这段代码可以分为两个部分,第一部分为统一的image:// ;第二部分为你的图片路径。

地图指定区域区域显示文字

在这里插入图片描述

let optionMap = {
 ...
   //图形上的文本标签,可用于说明图形的一些数据信息
      label: {
        normal: {
          formatter: (params) => {
            if (
              params.name == "天府新区" ||
              params.name == "高新南区" ||
              params.name == "东部新区"
            ) {
              return params.name;
            } else {
              return "";
            }
          },
          show: true,
          fontSize: "10",
          color: "#fff",
        },
      },
    ...
   }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

地图根据区域值显示指定颜色

在这里插入图片描述

let optionMap = {
 ...
 
     visualMap: {
      min: 0,
      max: 100000,
      left: 26,
      bottom: 40,
      showLabel: !0,
      textStyle: {
        color: "#fff",
      },

      pieces: [
        {
          gte: 1,
          lt: 100,
          color: "red",
        },
        {
          gte: 101,
          lt: 200,
          color: "yellow",
        },
        {
          gte: 201,
          lt: 300,
          color: "blue",
        },
        {
          gte: 301,
          lt: 400,
          color: "green",
        },
      ],
      // show: false, 是否展示左上角的图例
    },
    ...
        series: [
       {
        name: "信息量",
        type: "map",
        mapType: "china",
        geoIndex: 0,
        data: [
          { name: "天府新区",value: 10,},
          { name: "东部新区", value: 101 },
          { name: "高新南区", value: 201 },
          { name: "双流区", value: 301 },
        ],
      },
    ],
   }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/108733
推荐阅读
  

闽ICP备14008679号