Echarts 地图如何点击定位到自己的家乡城市区县

科技   2024-11-26 09:15   广东  

Echarts 地图如何点击定位到自己的家乡城市区县

前言

大家好,我是林三心,用最通俗易懂的话讲最难的知识点是我的座右铭,基础是进阶的前提是我的初心~

最近实现了通过Echarts地图,定位到自己的家乡,觉得挺有趣的,所以分享给大家,希望大家也可以实现一遍,在Echarts上定位到自己的家乡看一看~





地图的绘制

地图数据

地图的数据我们可以通过网上提供的 API 来进行获取

API URL:https://geo.datav.aliyun.com/areas_v3/bound/{mapCode}.json


绘制地图

首先需要一个 DOM 节点来进行 Echarts 的绘制


接着需要初始化 Echarts 实例,并进行配置,完成渲染


这样就能把地图渲染出来了


往下和往上定位

实现完整个地图的渲染,我们还需要实现:

  • 点击某个地区,进行往下定位
  • 点击按钮,进行往上定位

所以我们首先需要增加一个按钮





接着我们需要:

  • 1、监听 Echarts 的点击事件
  • 2、获取点击的是哪个地区,进行数据获取并渲染
  • 3、维护一个地区数组,记录点击的链路


最终可以实现效果




完整源码

<template>
  <Button @click="back" type="primary" :loading="loading">返回上一级</Button>
  <Spin :spinning="loading">
    <div class="container" ref="echartsRef"></div>
  </Spin>
</template>

<script setup lang="ts">
import * as echarts from 'echarts';
import { ref, onMounted } from 'vue';
import { Button, Spin } from 'ant-design-vue';

// 最顶层地图的代号
const ROOR_MAP_CODE = '100000_full';
const echartsRef = ref<HTMLDivElement | null>(null);
const echartInstance = ref<echarts.ECharts | null>(null);
const loading = ref(false);

// 请求地图数据
const fetchMapJson = async (mapCode: string) => {
  const response = await fetch(`https://geo.datav.aliyun.com/areas_v3/bound/${mapCode}.json`);
  const result = await response.json();
  return result;
};

// 记录点击链路
const mapCodes: string[] = [];
// 初始化 Echarts 实例
const initInstance = () => {
  if (!echartsRef.value) return;
  echartInstance.value = echarts.init(echartsRef.value);
  echartInstance.value.on('click', params => {
    if (params.seriesType === 'map') {
      const { adcode, level } = params.data;
      const mapCode = level === 'district' ? adcode : adcode + '_full';
      // 防止重复点击最后一层
      if (mapCodes[mapCodes.length - 1] === mapCode) return;
      mapCodes.push(mapCode);
      updateOptions(mapCode);
    }
  });
};

// 返回上一级
const back = () => {
  //   无法再往上了
  if (!mapCodes.length) return;

  mapCodes.pop();
  if (mapCodes.length) {
    // 取最后一个去渲染数据
    updateOptions(mapCodes[mapCodes.length - 1]);
  } else {
    // 没了说明需要渲染最顶层了
    updateOptions(ROOR_MAP_CODE);
  }
};

// 生成 Echarts 配置
const generateOptions = (mapCode: string, mapData: any): echarts.EChartsCoreOption => {
  return {
    tooltip: {
      showtrue,
      //   格式化 tooltip 信息
      formatterfunction (params: any{
        if (params && params.data) {
          const { name } = params.data;
          return name;
        }
      },
    },
    geo: {
      // 传进来 code,echarts 会去读取已注册的地图数据
      map: mapCode,
      label: {
        showtrue,
      },
    },
    series: [
      // 传进来 code,echarts 会去读取已注册的地图数据
      {
        type'map',
        map: mapCode,
        roamtrue,
        geoIndex0,
        selectfalse,
        data: mapData,
      },
    ],
  };
};

// 更新地图 Echarts 配置
const updateOptions = async (mapCode: string) => {
  if (!echartInstance.value) return;
  loading.value = true;
  const mapResult = await fetchMapJson(mapCode);
  echarts.registerMap(mapCode, mapResult);
  const mapdata = mapResult.features.map((item: any) => {
    const { name, adcode, level } = item.properties;
    return {
      name, // 地名
      adcode, // 区域编码
      level, // 层级
    };
  });
  const options = generateOptions(mapCode, mapdata);
  //   配置 Echarts
  echartInstance.value.setOption(options);
  loading.value = false;
};

onMounted(() => {
  // 初始化
  initInstance();
  updateOptions(ROOR_MAP_CODE);
});
</script>

<style scoped lang="less">
.container {
  width800px;
  height800px;
}
</style>


结语

我是林三心,感谢您的阅读~

前端之神
一位前端小菜鸡,写过400多篇原创文章,全网有6w+个前端朋友,梦想是成为”前端之神“~
 最新文章