Vue3 ECharts 实现地图及下钻功能 注释详细cv可用

先看最终效果图,鼠标悬停显示乡镇数据,点击下钻到乡镇地图。

在这里插入图片描述
在这里插入图片描述

一、首先需要准备你要制作地图及其下属县市的地图json数据,可以去这里进行地图下载DataV.GeoAtlas地理小工具系列

由于阿里云数据只到县市一级,如需获取乡镇地图数据,需要另行下载

将下载好的地图数据配置到项目当中

在这里插入图片描述

二、下载ECharts

npm install echarts

三、在App.vue页面挂载到全局

import { provide,onMounted } from "vue";
import * as echarts from "echarts";
provide("echarts", echarts);

四、页面引入使用

<template>
   <div id="EchartsMap"></div>
</template>
import { inject,onMounted, ref } from "vue";
const echarts = inject("echarts");
const pointListInfo = ref<any>([]);// 所有地图点位
const polygons = ref<any>([]); // 多边形内点位
onMounted(async () => {
  // 页面初始化 引入默认json文件 xxx是城市名称
  const jsonData = await import(`../config/xxxx.json`);
  const data = await jsonData.default;
  const coordinates = data.features[0].geometry.coordinates;
  getEchartsMap(xxxx, data);
});
// 加载地图
const getEchartsMap = (mapName: any, mapJSON: any) => {
  echarts.registerMap(mapName, mapJSON);
  var myChart = echarts.getInstanceByDom(document.getElementById("EchartsMap"));
  
  // 解决 There is a chart instance already initialized on the dom. 报错问题
  if (!myChart) {
    myChart = echarts.init(document.getElementById("EchartsMap"));
  }
  
  // 配置echart
  const options = {
    geo: [
      {
        map: mapName,
        aspectScale: 1,
        top: "20%",
        bottom: "10%",
        label: {
          show: true,
          color: "#7DFCDF",
          fontSize: 14
        },
        itemStyle: {
          areaColor: "#0c443e",
          borderColor: "#20c390"
        },
        emphasis: {
          itemStyle: {
            borderWidth: 1,
            borderColor: "#23D299",
            areaColor: "#23D299"
          },
          label: {
            color: "#fff"
          }
        }
      }
    ],
    series: [
      {
        type: "scatter",
        animationDurationUpdate: 1000,
        zlevel: 2,
        coordinateSystem: "geo",
        data: pointListInfo.value, // 点位数据不需要可不配置
        emphasis: {               // 点位样式
          label: {
            borderColor: "#777",
            borderWidth: 1,
            offset: [150, -90],
            show: type == "01" ? true : false,
            borderRadius: 5,
            backgroundColor: "#033639",
            formatter: (params: any) => {
              var res = [`{title|${params.data.name}}`] as any;
                res = [
                  `{title|${params.data.name}}`,
                  `{text|种植面积}{yield|${params.data.plant_area}}{unit|万亩} {text|水产面积}{yield|${params.data.aquatic_area}}{unit|万亩}`,
                  `{text|种植产量}{yield|${params.data.plant_production}}{unit|万吨} {text|水产产量}{yield|${params.data.aquatic_production}}{unit|万吨}`,
                  `{text|种植产值}{yield|${params.data.plant_output}}{unit|万元} {text|水产产值}{yield|${params.data.aquatic_output}}{unit|万元}`
                ].join("\n");

              return res;
            },
            rich: {
              title: {
                color: "#fff",
                align: "left",
                fontWeight: 800,
                padding: [0, 0, 0, 10],
                backgroundColor: "#001b19",
                width: "100%",
                height: 40,
                lineHeight: 40,
                fontSize: 18
              },
              text: {
                width: "25%",
                align: "left",
                height: 30,
                lineHeight: 30,
                padding: [20, 0, 0, 10]
              },
              yield: {
                align: "left",
                padding: [20, 0, 0, 10],
                color: "#23D299",
                fontSize: 16
              },
              unit: {
                width: "12.5%",
                align: "left",
                padding: [20, 0, 0, 5]
              }
            },
            width: 300,
            height: 150,
            color: "#fff",
            fontSize: 14,
            verticalAlign: "middle",
            lineHeight: 16
          }
        }
      }
    ]
  };

  myChart.setOption(options, true);
  window.addEventListener("resize", myChart.resize());

  myChart.off("click");
  // 地图点击事件
  myChart.on("click", async (params: any) => {
    polygons.value = [];
    // 动态引入地图json文件
    const jsonData = await import(`../config/${params.name}.json`);
    const data = await jsonData.default;
    const coordinates = data.features[0].geometry.coordinates;

    // 查询城镇级别点位信息(根据需求自行添加)
    const paramsdata = {
      areaId: params.name
    };
    const res = await pointList(paramsdata);
    
    // 设置图标
    res.result.forEach((item: any) => {
      item.symbol = "image://" + require("@/assets/industry_location.png");
      item.symbolSize = [18, 23]; // 图标大小
    });
    pointListInfo.value = res.result;
    
    // 通过turf来判断点是否在多边形内
    if (coordinates.length > 1) {
      //解决'Each LinearRing of a Polygon must have 4 or more Positions.'错误
      polygons.value.push(turf.multiPolygon(coordinates));
    } else {
      polygons.value.push(turf.polygon(coordinates));
    }
    pointListInfo.value = pointListInfo.value.filter((item: any) => {
      return polygons.value.some((item1: any) => {
        return turf.booleanPointInPolygon(
          turf.point([item.value[0], item.value[1]]),
          item1
        );
      });
    });
    
    // 重新加载地图
    getEchartsMap(params.name, data);
  });
};

下载turf npm install @turf/boolean-point-in-polygon turf官方文档

页面引入import * as turf from "@turf/turf"

以上顺序写完之后,地图即可渲染完成,下钻功能也基本实现,之后再根据自己的需求可以根据官方文档(Documentation - Apache ECharts)进行完善。

  • 22
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值