使用Vue3+Echarts实现加载中国地图,点击省份地图下钻(完整教程)
一. 前言
在众多 ECharts 图表类型中,开发者始终绕不开的有各种各样的地图开发,关于地图开发,可能比其他图表相对繁琐一些,其实说简单也简单,说复杂也复杂,其中不乏有层级地图、3D 地图等,感觉地图开发已经被玩出了花。
在 ECharts 地图开发中,地图下钻功能是重要的基础功能,将来能为数据分析和展示提供更加直观和有效的方式。本篇文章,我将会介绍如何利用 ECharts 实现一个完整的地图下钻功能,让用户能够通过点击地图上的区域来实现层级的切换和数据的展示。
二. 什么是地图下钻功能?
地图下钻(Drill-down)是一种常见的高级交互功能,可以使用户能够深入地图的不同层级,查看更加详细的地理数据,帮助用户逐层深入地查看不同区域或层级的数据分布情况,极大地增强了数据可视化的深度和用户体验。
地图下钻功能是指在地图上点击某个区域后,该区域会进一步细化展示其下一级别的区域信息,例如:从省级地图下钻到市级地图,再到区县级地图,这种逐级细化的过程有助于我们更细致地分析和理解地域数据。例如下面这种效果:

通过地图下钻功能,用户可以通过交互操作深入地图的不同层级,从整体的地图层级逐渐细化到更具体的区域层级,用户可以更深入地了解地理数据,探索不同区域的数据细节,并进行更精确的数据分析和决策。这种交互式的地图功能可以极大地增强用户与数据之间的互动性和可视化体验,提升数据分析和展示的效果。
在 ECharts 中实现地图下钻功能,通常需要通过配置点击事件,根据用户点击的区域进行数据更新,从而实现地图的层级切换和展示。地图下钻功能广泛应用于各种数据可视化场景,如地理信息系统、区域销售分析、人口统计等领域,帮助用户更好地理解和利用地理数据。
三. 如何在 ECharts 中实现地图下钻?
如何在 ECharts 中实现地图下钻?我总结为以下 4 个步骤:
- 准备地图数据
- 初始化 ECharts 地图
- 设置地图下钻事件监听器
- 实现地图下钻
在进行地图下钻功能之前,我们需要先实例化一个最基础的中国地图,为地图下钻做准备。之前我写过一篇文章,讲述如何快速的创建一个合规的中国地图。
在这里,我们简单的总结一下,完成两步就可以渲染一个中国地图。
1. 准备地图数据
首先,我们需要准备多层级的地图数据,比如国家、省份、城市等各级别的地理数据,以及每个区域对应的数据指标,这些数据通常是以 JSON 格式提供的地理信息数据。同时,确保数据格式符合 ECharts 的要求,可以参考官方文档了解各种地图类型的数据格式。
我们可以在一些其他网站获取最新的 geoJson,比如:我是通过阿里云 DataV 数据可视化平台下载最新的 json 数据文件,以保证目前所有市区的数据都是最新的。
如下图所示,选择数据版本后,点击页面上的下载按钮后即可以下载 json 文件:

本地调试也可以使用在线的 JSON API 接口获取数据,不过仅限于本地测试使用!线上会 403 错误
解决 403 问题,参考文章:巧用 meta 标签,设置 referrer 解决 403 Forbidden 问题
2. 初始化 ECharts 地图
在 ECharts 的配置项中,配置地图组件并设置合适的地图类型(如中国地图、世界地图等),以及需要展示的数据和样式,确保每个区域都有对应的数据用于显示。
四. 实现地图下钻
实现地图下钻的关键逻辑在于:为地图添加点击事件监听器,当用户点击地图上的某个区域时,触发相应的事件处理函数,根据点击的区域获取下一级别的地图数据并更新图表。
实例场景:比如,我点击山东省,可以查看山东省下各市级地图,点击青岛市,进而查看青岛市下各区级地图。
实现逻辑:
-
当用户点击某个区域时,例如:山东省,获取到该区域对应的编码。
-
通过该区域对应的编码,获取到该区域的 geoJson 数据。
-
通过该区域的 geoJson 数据,渲染到 ECharts 地图组件上。
接下来我们一步一步进行分析。
1. 获取区域编码
首先需要给地图添加点击事件监听器,当用户点击地图时,获取到用户点击该区域对应的编码。

如图所示,通过上述的操作,我们能够轻松的获取到该区域的地理编码 adcode 和名称。
2. 获取点击区域地图 JSON 数据
获取到地理编码 adcode 和名称之后,接下来需要通过 adcode 来获取子区域的 geoJson,以下的代码是通过调用阿里云 DataV 在线的 JSON API 接口获取到的数据。
注意:过调用阿里云 DataV 在线的 JSON API 接口获取到的数据,仅限于调试!线上会 403 错误,如果要上线,需要将各个区域的数据下载到本地加载。
3. 渲染区域地图
通过上述操作,我们成功的获取到了点击区域的子区域地图 JSON 数据,通过 JSON 数据,我们就可以动态的渲染区域地图了
五. 完善交互和效果
为提升用户体验,可以添加一些校验,避免在下钻过程中出现一些异常情况。比如:
-
在地图下钻的最后一层,如何判断处理该地图是否还有下级区域,简单说就是是否还允许地图继续下钻?
-
地图下钻过程过程中,我需要返回上一级地图,该如何实现?
以上这两个问题是在地图开发中必须要考虑的基础问题,下面我来分析一下如何优化这两种问题,提升用户体验。
1. 处理递归下钻
在事件处理函数中,根据用户点击的区域信息,判断是否需要进行下钻操作。如果需要下钻,才可以展示子区域的地图信息。如果已经到了地图最末端,无法再进行下钻,应该相应提示用户。
例如,当用户点击到区县级地图且无法再下钻时,可以考虑弹窗显示详细信息或者返回至上一级别。
2. 返回上一级地图
在用户点击地图进行下钻的过程中,难免会返回上一层进行重新点击的需求,这种需求应该怎么实现呢?下面我来具体分析一下:
- 添加返回按钮,返回按钮显示隐藏逻辑处理,比如:仅当可以返回上一层地图级别的时候才显示返回
- 记录地图下钻过程中的地图层级数据,比如:山东省 -> 青岛市 -> 崂山区
- 根据记录的层级数据实现返回上一级操作
返回按钮的显示和隐藏
关于返回按钮的显示和隐藏,可以有多种判断方式,可以根据是否为初始化地图来判断,只有当前渲染为初始地图时,隐藏返回按钮,也可以根据记录地图的层级数据数组判断是否显示返回按钮。
下述代码是根据 adcode 来判断是否为初始地图,因为我是以中国地图为初始化地图,所以判断 adcode 是否等于 100000 来判断是否显示
以上只是一种思路,你可以考虑其他方式判断,合理即可!
3. 自定义 tooltip
加一些指向 tooltip 提示,当用用鼠标指向省市区时,显示省市区的名称、编码及层级数据。
完整代码:
<!--* @Author: 彭麒* @Date: 2024/12/5* @Email: 1062470959@qq.com* @Description: 此源码版权归吉檀迦俐所有,可供学习和借鉴或商用。-->
<template><div><h3>地图下钻演示:<span style="font-size: 20px;color: red;">目前仅支持四川省!!!</span></h3><a id="back" href="javascript:;" v-show="showBackButton" @click="goBack">返回</a><div id="main" style="height: 800px"></div></div>
</template><script setup>
import { ref, onMounted } from 'vue';
import * as echarts from 'echarts';
const showBackButton = ref(false);
const myChart = ref(null);
const mapList = ref([]);
//各省份的数据
const allData = [{name: '北京'
}, {name: '天津'
}, {name: '上海'
}, {name: '重庆'
}, {name: '河北'
}, {name: '河南'
}, {name: '云南'
}, {name: '辽宁'
}, {name: '黑龙江'
}, {name: '湖南'
}, {name: '安徽'
}, {name: '山东'
}, {name: '新疆'
}, {name: '江苏'
}, {name: '浙江'
}, {name: '江西'
}, {name: '湖北'
}, {name: '广西'
}, {name: '甘肃'
}, {name: '山西'
}, {name: '内蒙古'
}, {name: '陕西'
}, {name: '吉林'
}, {name: '福建'
}, {name: '贵州'
}, {name: '广东'
}, {name: '青海'
}, {name: '西藏'
}, {name: '四川'
}, {name: '宁夏'
}, {name: '海南'
}, {name: '台湾'
}, {name: '香港'
}, {name: '澳门'
}];
for (var i = 0; i < allData.length; i++) {allData[i].value = Math.round(Math.random() * 100);
}
const getJSON = async ({ name }, callback) => {console.log(name);const url = `/map/${name}.json`;try {const response = await fetch(url);if (!response.ok) {throw new Error('Network response was not ok');}const data = await response.json();callback(data);setBackbtn({ name });} catch (error) {alert('无此区域地图显示,请查看其他区域!');}
};const setBackbtn = ({ name }) => {mapList.value.push({ name });showBackButton.value = name !== 'china';console.log(JSON.stringify(mapList.value));
};const goBack = () => {if (mapList.value.length >= 2) {const { name } = mapList.value[mapList.value.length - 2];mapList.value.splice(-2, 2);getJSON({ name }, (data) => {renderChart(name, data);});}
};const initChinaMap = () => {mapList.value = [];getJSON({ name: 'china' }, (data) => {renderChart('china', data);});
};const renderChart = (name, data) => {echarts.registerMap(name, data);setOption(name, allData);
};const setOption = (name, data) => {const option = {tooltip: {show: true,formatter: function(params) {if (params.data) return params.name + ':' + params.data['value']},},visualMap: {type: 'continuous',text: ['', ''],showLabel: true,left: '50',min: 0,max: 100,inRange: {color: ['#edfbfb', '#b7d6f3', '#40a9ed', '#3598c1', '#215096', ]},splitNumber: 0},series: [{name: 'MAP',type: 'map',mapType: name,selectedMode: 'false',//是否允许选中多个区域label: {normal: {show: true},emphasis: {show: true}},data: data}]};myChart.value.setOption(option, true);
};onMounted(() => {myChart.value = echarts.init(document.getElementById('main'));myChart.value.on('click', (params) => {if (params.data) {const { name, level } = params.data;if (level === 'district') {alert('无此区域地图显示!');initChinaMap();return;}getJSON({ name }, (data) => {renderChart(name, data);});}});initChinaMap();
});
</script><style>
body {text-align: center;
}
</style>
六. 总结
通过本篇文章的详细讲述,我们应该都有了一个明确的思路,可以借助 ECharts 快速地实现地图下钻功能。当然,本文完成的是核心下钻逻辑,而且也没有对地图的样式进行一些复杂的样式配置,在实际应用中可能还需要对颜色映射、数据标注等方面进行个性化定制,但这些并不是难点,相信参考 ECharts 配置项手册来进行配置地图属性,也是非常容易实现的。
因此,开发地图的关键点在于开发地图的过程中,我们始终要有一个清晰明了的开发思路和步骤,才能保证按部就班的实现功能,并且避免一些不必要的 BUG 产生。
比如:关于使用 ECharts 的图表渲染造成的内存溢出,导致浏览器崩溃问题,最终一步一步复盘代码才能解决问题。
七. 资源链接
-
代码演示地址:中国地图下钻示例演示:支持所有省市下钻演示
-
源码地址:ECharts 地图下钻源码地址
-
geoJson 文件下载:全国地图下钻 geoJson 完整版下载 20240312.zip
-
官方文档:ECharts 地图配置项手册
由于时间原因,目前我只导入了四川省的地图,其他各个省市区的地图数据大家可以按需下载导入!后面我会都导入到本地。感谢您的阅读!
推荐文章
关于 ECharts 的系列文章,大家可以点解查看以下文章进行了解:
-
ECharts-GL 实战分享:教你轻松实现 3D 地图下钻功能
-
使用 ECharts-GL 实现世界级、国家级、省市级 3D 地图
-
ECharts-GL 实战:轻松实现 3D 旋转地球
相关文章:
使用Vue3+Echarts实现加载中国地图,点击省份地图下钻(完整教程)
一. 前言 在众多 ECharts 图表类型中,开发者始终绕不开的有各种各样的地图开发,关于地图开发,可能比其他图表相对繁琐一些,其实说简单也简单,说复杂也复杂,其中不乏有层级地图、3D 地图等,感觉…...
NUMA-非统一内存访问架构
NUMA(Non-Uniform Memory Access) 是一种计算机内存架构,主要用于多处理器系统。NUMA架构中的每个处理器都连接到自己的本地内存,并且可以访问其他处理器的内存,但访问其他处理器的内存速度较慢。 内核通过调度优化进…...
初识交换机和路由器
目录 初识交换机和路由器交换机路由器主要区别工作流程如果是交换机:如果是路由器 初识交换机和路由器 左为路由器,右为交换机 交换机 交换机的前身是集线器,集线器是物理层的设备,有很多接口,当一台计算机A想发消息…...
SQL面试题——滴滴SQL面试题 取出累计值与1000差值最小的记录
滴滴SQL面试题 取出累计值与1000差值最小的记录 今天的题目来自滴滴出行 已知有表cost_detail包含id和money两列,id为自增,请累加计算money值,并求出累加值与1000差值最小的记录。 +-----+--------+ | id | money | +-----+--------+ | 1 | 200 | | 2 | 300 …...
openEuler 22.03 使用cephadm安装部署ceph集群
目录 目的步骤规格步骤ceph部署前准备工作安装部署ceph集群ceph集群添加node与osdceph集群一些操作组件服务操作集群进程操作 目的 使用ceph官网的cephadm无法正常安装,会报错ERROR: Distro openeuler version 22.03 not supported 在openEuler上实现以cephadm安装部…...
C++哈希(一)
1.底层结构 顺序结构以及平衡中,元素关键码与其存储位置之间没有相对应的关系,因此在查找一个元素时,要经过关键码的多次比较。顺序查找的时间复杂度为O(N)。 理想的搜索方法:可以不经过比较,依次直接从表中直接搜索…...
阿拉丁论文助手:一键点亮学术之路
在学术研究的海洋中,每一位学者都渴望拥有一盏能够照亮前行道路的神灯。阿拉丁论文助手,正是这样一盏神奇的灯,它以其先进的人工智能技术和丰富的学术资源,为学者们的学术写作提供了全方位的支持。 一、阿拉丁论文助手简介 阿拉丁…...
视频码率到底是什么?详细说明
视频码率(Video Bitrate)是指在单位时间内(通常是每秒)传输或处理的视频数据量,用比特(bit)表示。它通常用来衡量视频文件的压缩程度和质量,码率越高,视频质量越好&#…...
嵌入式学习(17)-stm32F407串口使用注意事项
一、概述 配置串口时串口的接收一直不好使,对比例程发现了问题: 在网上也找了一些资料供参考“STM32F4的串口RX引脚不能被设置为输入是因为串口的接收(RX)功能是由硬件电路实现的,无法通过软件配置来控制。串口接收功…...
汽车48V电气系统
汽车48V电气系统 汽车48V电气系统汽车48V电气系统设计汽车48V电气系统测试汽车48V系统是48V供电和12V供电共存的么?48V供电系统是如何与12V供电系统共存的?48V电气系统测试的难点有哪些?在汽车48V电气系统通信测试中,如何向12V的控制器和48V的控制器供电?汽车48V电气系统通…...
【人工智能基础05】决策树模型习题
文章目录 1. 归一化对决策树的影响2. 选择决策树模型3. 决策树计算4. 基尼系数的优势5. 在叶子上使用线性模型的优缺点 1. 归一化对决策树的影响 题目:对于一些机器学习模型(例如,神经网络),对特征进行归一化(normaliz…...
rockit 学习、开发笔记(六)(VENC)
前言 上节我们讲到了VDEC解码模块,那当然少不了VENC编码模块了,一般有编解码的需求都是为了压缩视频的大小,方便减少传输所占用的带宽。 概述 VENC 模块,即视频编码模块。本模块支持多路实时编码,且每路编码独立&am…...
spring技术点
引入对象 Autowired 和 Resource的区别 Autowired 和 Resource的区别 valid 参数校验 jarkata进行SpringMVC校验 常规当前进行校验的配置操作,参考文档如下进行操作。 SpringMVC校验注解不生效 List类型参数校验 由于list类型默认不能进行标注校验实现&#x…...
R语言使用“纽约市数据集中的优步皮卡”数据创建不同年度时间范围的可视化
一、项目背景 为了分析纽约市优步(https://baike.baidu.com/item/Uber/14900884)皮卡在不同年度的使用情况,需要利用R语言进行数据可视化。通过对比不同年度的数据,可以揭示出优步皮卡使用的趋势和变化。 二、数据准备 数据集&a…...
电阻计RM3544、RM3545的使用
目录: 一、电阻计与PC通讯 1、硬件连接 2、RmLogger.exe的使用 二、RM3545测量35uΩ电阻 一、电阻计与PC通讯 1、硬件连接 可以设置USB或COM口(串口)连接PC,也可以设置为“打印”输出。 1)使用USB连接PC 2)使用串口连接PC …...
Unity 策略游戏地图上的网格是如何实现的
在Unity中实现策略游戏地图上的网格,主要涉及到地图数据的处理、地图的加载与渲染、以及玩家在地图上的移动与碰撞检测等关键步骤。以下是对这些步骤的详细解释: 一、地图数据的处理 收集地图数据:这包括地形高度、地形纹理、建筑物、树木等…...
《鸟哥的Linux私房菜基础篇》---4 Linux档案的压缩与打包
目录 一、常见的压缩包的扩展名 二、常见的压缩和解压指令 1、tar 2、tar gzip(.tar.gz) (或 .tgz) 3、tar bzip2(.tar.bz2) 4、zip 5、gzip 6、bzip2 7、xz 8、rar 9、7z 三、安装解压工具 一、常见的压缩包的扩展…...
Springboot 2.7+解决跨域问题,到底是在SpringBoot中添加拦截器还是修改Nginx配置
文章目录 1摘要2 核心代码2.1 SpringBoot 全局跨域拦截器2.2 Nginx 配置跨域处理2.3 Nginx 和 SpringBoot 同时添加允许跨域处理会怎么样? 3 推荐参考资料 1摘要 跨域问题报错信息: Referrer Policy:strict-origin-when-cross-origin跨域问题是在前后端分离的情况…...
Spring中Bean的作用域深入剖析与技术实践
前言 Spring框架作为Java企业级应用开发中的中流砥柱,提供了强大的依赖注入(DI)和面向切面编程(AOP)等功能。在Spring框架中,Bean的作用域(Scope)是一个非常重要的概念,…...
Python爬虫实战:抓取拼多多商品详情数据(基于pdd.item_get接口)
在当前的电商市场中,拼多多以其独特的拼团模式和优惠价格吸引了大量用户,成为继淘宝、京东之后的又一大电商平台。对于数据分析和市场研究者来说,获取拼多多的商品详情数据显得尤为重要。本文将介绍如何使用Python爬虫技术,通过调…...
挑战杯推荐项目
“人工智能”创意赛 - 智能艺术创作助手:借助大模型技术,开发能根据用户输入的主题、风格等要求,生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用,帮助艺术家和创意爱好者激发创意、提高创作效率。 - 个性化梦境…...
Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...
第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...
