Vue项目echarts地图标记点

效果展示

需求

最近遇到一个展示某个地区以及其下级地区并且在地区上标注点的需求。要求是:

  • 默认展示全部地区地图,点击地区中的下级地区,切换成下级地区的地图。
  • 地图能够缩放,地图中需要标记点位。
  • 地图需要与外部联动,分为三个层级:全部地区、下级地区、具体点位,点击这三个层级在外部的响应事件不一样。

技术选型

由于需求中并不需要展示比较精细的地图内容,所以针对该需求,采用echarts地图来实现而未采用百度地图、高德地图等。

结构目录

  • components文件夹用来管理子组件
  • map文件夹用来管理地图JSON
  • set.js是地图配置文件

构建地图步骤

  1. 注册地图

echart使用定制地图,需要进行注册,使用echarts.registerMap来进行注册,有三种注册的方式,方法详情如下:

js 复制代码
( mapName: string,
  opt:{
      geoJSON: Object | string; specialAreas?: Object;
  }
) |
( mapName: string,
  opt:{
      svg: Object | string;
  }
) |
( mapName: string, geoJSON: Object | string, specialAreas?: Object )

注册可用的地图,只在 geo 组件或者 map 图表类型中使用。 使用方法见 option.geo

参数:

  • mapName 地图名称,在 geo 组件或者 map 图表类型中设置的 map 对应的就是该值。

  • opt

    • geoJSON 可选。GeoJson 格式的数据,具体格式见 geojson.org/。可以是 JSON 字符串,也可以是解析得到的对象。这个参数也可以写为 geoJson,效果相同。
    • svg 可选。从 v5.1.0 开始支持SVG 格式的数据。可以是字符串,也可以是解析得到的 SVG DOM 对象。更多信息参见 SVG 底图
    • specialAreas 可选。将地图中的部分区域缩放到合适的位置,可以使得整个地图的显示更加好看。只在 geoJSON 中生效,svg 中不生效。

在这里我们使用echarts.registerMap(mapName: string, geoJSON: Object)来进行注册地图。

1.1. 获取定制地图的JSON

这里我们借助阿里云数据可视化平台-DATAV来进行JSON的获取。

整体界面的右侧是使用方式,根据使用步骤进行操作,本次实例最后使用其他类型,直接将其下载下来。

JSON文件下载下来之后,整理到map文件夹中。

  1. 初始化echarts容器
html 复制代码
<div class="settlement-content-item-top">
    <!-- <echarts-map /> -->
    <div class="map">
      <div ref="content" class="map-content"></div>
      <div class="back" @click="goBack">全部区域</div>
      <div class="map-title">{{ chartName }}</div>
    </div>
</div>
js 复制代码
   init() {
      ......
      // 初始化容器
      this.myChart = echarts.init(this.$refs.content);
      // loading
      this.myChart.showLoading();
      // 设置地图
      this.setMap();
      this.option && this.myChart.setOption(this.option);
      window.addEventListener("resize", this.myChart.resize);
      // 注册事件,便于后续发送地图信息给别的组件
      this.myChart.on("click", ({ name, data }) => {
        // 点击了点
        if (data) {
          ......
        } else {
          // 点击了区域
          ......
        }
      });
    },
  1. 设置地图方法
  • 点击地图会调用该方法,根据层级来判断加载哪个JSON地图数据,以展示不同的地图
  • 然后设置地图的数据以加载图中的点。
js 复制代码
// chartName不传就使用默认值
setMap(chartName = "xxx", medicalInstitutionCode = "") {
      // 注册地图,第一个参数是名称,第二个参数是对应的地图JSON值
      echarts.registerMap(chartName, this.chartMap.get(chartName).json);
      // 隐藏loading效果
      this.myChart.hideLoading();
      // 设置echarts options
      this.myChart.setOption(
      // 赋值操作也是有返回值的,这里赋值完成之后,把结果给了this.myChart.setOption方法
      // setOption方法来自于set.js文件
        (this.option = setOption(
          chartName,
          this.hospitalOptionMap.get(medicalInstitutionCode),
          this.chartMap.get(chartName).center
        ))
      );
    }
  1. 设置option方法「核心」
js 复制代码
// 参数:地图名、数据、地图中心经纬度
export const setOption = (map, data, center) => {
  return {
    tooltip: {
      trigger: "item",
      formatter: "{b}"
    },
    visualMap: {
      show: false, //显示数据区间查看器
      inRange: {
        color: ["#48b2fd"]
      }
    },
    // 写入经纬度标注点所需
    geo: {
      map,
      center,
      roam: true,
      zoom: 1,
      label: {
        normal: {
          // 显示省份标签
          show: false,
          textStyle: {
            color: "#fff",
            fontSize: 10
          }
        }
      },
      itemStyle: {
        color: "#ddb926",
        normal: {
          // 地图区域颜色
          areaColor: "#1a456b",
          // 地图描边颜色
          borderColor: "#1BB0D4",
          // 地图描边大小
          borderWidth: 1
        },
        // 高亮时的样式
        emphasis: {
          areaColor: "#1BB0D4",
          borderColor: "#1BB0D4",
          borderWidth: 1
        }
      }
    },
    // 两种方式:
    // 1、geo
    // 2、series的type=map,这个不能在地图上标点,只能是tooltip
    series: [
      // {
      //   name: map,
      //   type: "map",
      //   map,
      //   zoom: 1.2,
      //   label: {
      //     show: true,
      //     color: "#fff"
      //   },
      //   itemStyle: {
      //     normal: {
      //       borderColor: "#2ab8ff",
      //       borderWidth: 1.5,
      //       areaColor: "#12235c"
      //     },
      //     emphasis: {
      //       areaColor: "#2AB8FF",
      //       borderWidth: 0,
      //       color: "green"
      //     }
      //   },
      //   selectedMode: false
      // },
      {
        type: "effectScatter",
        coordinateSystem: "geo",
        showEffectOn: "render",
        // 涟漪特效相关配置
        rippleEffect: {
          // 动画的周期(秒数)
          period: 15,
          // 动画中波纹的最大缩放比例
          scale: 2,
          // 波纹的绘制方式
          brushType: "fill"
        },
        hoverAnimation: true,
        itemStyle: {
          shadowBlur: 10,
          shadowColor: "#333"
          // normal: {
          //   color: "#000"
          // }
        },
        data,
        selectedMode: false
        // 模拟数据
        // data: [
        //   { name: "医院2", value: [86.165967, 41.749112, 10] },
        //   { name: "医院3", value: [84.261084, 41.783598, 50] },
        //   { name: "医院4", value: [86.263739, 41.350774, 100] },
        //   { name: "医院5", value: [88.175899, 39.029217, 150] },
        //   { name: "医院7", value: [86.571444, 42.066777, 400] },
        //   { name: "医院8", value: [86.3904, 42.330431, 500] },
        //   { name: "医院9", value: [86.883112, 42.287424, 600] },
        //   { name: "医院10", value: [86.883112, 42.287424, 70] },
        // ],
      }
    ]
  };
};
  1. 传递地图控件数据,联动外部组件
js 复制代码
// 发送数据出去
sendData(chartName = "巴音郭勒蒙古自治州", medicalInstitutionCode) {
  // 防抖
  clearTimeout(this.timeId);
  this.timeId = setTimeout(() => {
    let [
      { regionCode, regionName, medicalInstitutionName } = {
        regionCode: this.chartMap.get(chartName).regionCode,
        regionName: chartName,
        medicalInstitutionName: ""
      }
    ] = this.hospitalOptionMap.get(this.formData.hospital);
    if (this.chartLevel === "all") {
      regionCode = "";
      regionName = "";
      medicalInstitutionName = "";
    }
    // 自定义发送数据
    this.reqParams = {
      // 地区编码
      regionCode,
      // 地区名称
      regionName,
      // 医院编码
      medicalInstitutionCode,
      // 医院名称
      medicalInstitutionName,
      // 开始时间
      startDate: this.formData.time[0],
      // 结束时间
      endDate: this.formData.time[1],
      // 整个州、整个县/市、整个医院
      type: this.getType(regionCode, medicalInstitutionCode)
    };
  }, 500);
},

页面联动逻辑

地图控件单独做一个单元,带动其他控件;地图控件变化会传递参数,其他组件监听到参数改变,随之改变。

总结

本文记录使用echarts地图geo功能的应用实例,遇到相同需求的朋友可以参考。

相关推荐
Book_熬夜!16 小时前
Python基础(六)——PyEcharts数据可视化初级版
开发语言·python·信息可视化·echarts·数据可视化
范特西是只猫2 天前
echarts 自定义标注样式&自定义tooltip弹窗样式
前端·javascript·echarts
范特西是只猫2 天前
echarts map地图动态下钻,自定义标注,自定义tooltip弹窗【完整demo版本】
前端·javascript·echarts
人工智能的苟富贵2 天前
微信小程序中实现类似于 ECharts 的图表渲染及优化
微信小程序·小程序·echarts
GHUIJS3 天前
【Echarts】vue3打开echarts的正确方式
前端·vue.js·echarts·数据可视化
Peanuts.3 天前
VUE使用echarts编写甘特图(组件)
开发语言·javascript·echarts
GHUIJS6 天前
【Echarts】使用多横坐标轴展示近十五天天气预报
javascript·echarts
暖锋丫7 天前
echarts实现湖南省地图并且定时轮询
前端·javascript·echarts
时光匆匆岁月荏苒,转眼我们已不是当年7 天前
【前端echarts】echarts双饼图与easyui列表联动
前端·echarts·easyui
SnowMan19938 天前
高级 ECharts 技巧:自定义图表主题与样式
信息可视化·数据分析·echarts