vue中Echarts地图下钻实现方案-从零开始实现省市县三级下钻

vue中Echarts地图下钻最优雅实现方案-从零开始实现省市县三级下钻

最近在网上搜Echarts地图下钻的实现方案,发现各种方案层出不穷,几乎都是一大堆的冗余代码,或者是包含各种业务代码,很难找到通俗易懂的实现方案,所以决定写这篇文章记录下来,方便大家查阅。

实现效果

在这里插入图片描述

数据准备

1. 地图数据获取

2. 地图json文件存储目录

地图json文件的存储目录,采用分层存储策略,将不同级别(全国、省、市、县)的地图数据分开存储,这样便于管理。目录结构如下:

src/
└── assets/
    └── map-json/
        ├── chinaNew.json          # 全国地图数据
        ├── province/              # 省级地图数据
        │   ├── 110000.json       # 北京
        │   ├── 120000.json       # 天津
        │   └── ...
        ├── citys/                 # 市级地图数据
        │   ├── 110100.json       # 北京市
        │   ├── 120100.json       # 天津市
        │   └── ...
        └── county/               # 区县级地图数据
            ├── 110101.json      # 东城区
            ├── 110102.json      # 西城区
            └── ...
            

在这里插入图片描述

其次,再查看其他人的文章时,发现很多人都喜欢一次性把所有能用到的json文件全部导入,这样虽然也可以,但是要导入大量的json文件,代码不够优雅,并且大量的json文件会导致加载缓慢,按需加载可以显著提升首屏加载速度。我这里地图json文件的获取,采用import()动态获取的方式,通过点击地图上的不同区域,动态获取对应的地图json文件,然后注册到echarts中。

实现代码

附上完整代码,整体功能实现只有几十行代码,通俗易懂,所有注释都写的很清楚,不懂的可以直接看注释,创建一个vue单文件,然后复制粘贴即可使用。这里直接使用的是vue-echarts,所以项目要先安装vue-echarts和echarts。

npm install --save vue-echarts echarts
<template>
  <div>
    <button @click="handleBack">返回上一级</button>
    <v-chart :option="mapOption" class="map-chart" @click="handleMapClick" />  <!-- 通过v-chart组件渲染地图 -->
  </div>
</template>

<script setup>
import { ref, provide, onMounted } from 'vue'
import VChart, { THEME_KEY } from 'vue-echarts' // 引入v-chart组件
import * as echarts from 'echarts' // 引入echarts
import ChinaGroJson from '@/assets/map-json/china.json' // 引入全国地图json文件,这里只引入全国地图json文件即可
provide(THEME_KEY, 'light') // 提供主题
const mapOption = ref() // 地图配置
const geoJson = { // 地图json数据 只初始化全国地图json文件,其他省市县地图json文件在下面代码里动态获取,例如:当前地图切换为北京,则geoJson.province存储的就是北京市的地图json数据,切换为天津,则geoJson.province存储的就是天津市的地图json数据
  china: ChinaGroJson,
  province: null,   // 省
  city: null,       // 市
  county: null      // 县
}
const currentLevel = ref('china') // 当前地图级别,默认为全国

const levelConfig = { // 地图层级配置,用于描述地图的层级关系
  china: {
    nextLevel: 'province', // 下一级,表示点击地图后,地图要跳转到的下一级
    geoKey: 'china',       // 地图key,表示地图的层级名称
    jsonPath: 'province'  // 地图json路径,表示地图json文件的存储路径
  },
  province: {
    nextLevel: 'city',
    geoKey: 'province',
    jsonPath: 'citys'
  },
  city: {
    nextLevel: 'county',
    geoKey: 'city',
    jsonPath: 'county'
  }
}
/**
 * 设置地图option,这里直接使用最基础的地图配置,可以根据需求自行修改
 * @param {Array} mapData 地图要用的data数据
 * @param {String} mapName 地图名称
 */
const setMapOption = (mapData, mapName = 'china') => {
  mapOption.value = {
    series: [
      {
        type: 'map',
        map: mapName,
        label: {
          show: true
        },
        data: mapData
      }
    ]
  }
}

const handleMapClick = async event => { // 地图点击事件
  const currentConfig = levelConfig[currentLevel.value]   // 获取当前地图层级配置
  if (currentConfig) {
    currentLevel.value = currentConfig.nextLevel // 更新当前层级,把下一级作为当前层级存储到currentLevel中
    const adcode = geoJson[currentConfig.geoKey].features.find(item => item.properties.name === event.name).properties.adcode // 获取地区编码,从geoJson中对应层级存储的json文件中获取
    try {
      const newGeoJson = await import(`@/assets/map-json/${currentConfig.jsonPath}/${adcode}.json`) // 动态获取下一级地图json文件, 例如:@/assets/map-json/citys/110100.json
      geoJson[currentConfig.nextLevel] = newGeoJson // 将获取到的地图json数据赋值到geoJson里对应的层级
      echarts.registerMap(event.name, geoJson[currentConfig.nextLevel]) // 注册新地图
      setMapOption(['地图数据'], event.name) // 设置新地图配置
    } catch (error) {
      console.log('地图数据加载失败', error)
      handleBack() // 如果加载失败,则返回上一级
    }
  }
}
// 返回上一级
const handleBack = () => {
  if (currentLevel.value === 'china') return // 如果已经是最顶层则不处理
  const prevLevels = {
    province: 'china',
    city: 'province',
    county: 'city'
  }
  const prevLevel = prevLevels[currentLevel.value] // 获取上一级配置
  currentLevel.value = prevLevel // 返回上一级
  echarts.registerMap(prevLevel, geoJson[prevLevel]) // 重新注册上一级地图,例如我们当前层级是青岛市地图,geoJson.province依然存储着山东省的地图,此时我们直接使用即可
  setMapOption(['地图数据'], prevLevel) // 设置新地图配置
}
// 组件挂载初始化全国地图
onMounted(() => {
  echarts.registerMap('china', geoJson.china)
  setMapOption(['地图数据'], 'china')
})
</script>

<style lang="scss" scoped>
.map-chart {
  width: 800px;
  height: 800px;
}
</style>

注意事项

  • 一定要使用行政区划代码作为文件名,并保持目录结构清晰,例如:北京市的行政区划代码是110000,所以北京市的地图json文件名必须是110000.json,上面github仓库里提供的node脚本可以批量下载以行政区划代码命名的地图json文件。
  • 必须使用areas_v3版本的json地图数据,否则再获取行政区划代码的时候会出现问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值