ECharts 地图实战分析:实现一个完整的地图下钻功能

2024-11-13 08:31   重庆  

点击关注公众号,“技术干货” 及时达!

一. 前言

在众多 ECharts 图表类型中,开发者始终绕不开的有各种各样的地图开发,关于地图开发,可能比其他图表相对繁琐一些,其实说简单也简单,说复杂也复杂,其中不乏有层级地图、3D 地图等,感觉地图开发已经被玩出了花。

在 ECharts 地图开发中,地图下钻功能是重要的基础功能,将来能为数据分析和展示提供更加直观和有效的方式。本篇文章,我将会介绍如何利用 ECharts 实现一个完整的地图下钻功能,让用户能够通过点击地图上的区域来实现层级的切换和数据的展示。

二. 什么是地图下钻功能?

地图下钻(Drill-down)是一种常见的高级交互功能,可以使用户能够深入地图的不同层级,查看更加详细的地理数据,帮助用户逐层深入地查看不同区域或层级的数据分布情况,极大地增强了数据可视化的深度和用户体验。

地图下钻功能是指在地图上点击某个区域后,该区域会进一步细化展示其下一级别的区域信息,例如:从省级地图下钻到市级地图,再到区县级地图,这种逐级细化的过程有助于我们更细致地分析和理解地域数据。例如下面这种效果:

地图下钻 1.gif

通过地图下钻功能,用户可以通过交互操作深入地图的不同层级,从整体的地图层级逐渐细化到更具体的区域层级,用户可以更深入地了解地理数据,探索不同区域的数据细节,并进行更精确的数据分析和决策。这种交互式的地图功能可以极大地增强用户与数据之间的互动性和可视化体验,提升数据分析和展示的效果。

在 ECharts 中实现地图下钻功能,通常需要通过配置点击事件,根据用户点击的区域进行数据更新,从而实现地图的层级切换和展示。地图下钻功能广泛应用于各种数据可视化场景,如地理信息系统区域销售分析人口统计等领域,帮助用户更好地理解和利用地理数据。

三. 如何在 ECharts 中实现地图下钻?

如何在 ECharts 中实现地图下钻?我总结为以下 4 个步骤:

  1. 准备地图数据
  2. 初始化 ECharts 地图
  3. 设置地图下钻事件监听器
  4. 实现地图下钻

在进行地图下钻功能之前,我们需要先实例化一个最基础的中国地图,为地图下钻做准备。之前我写过一篇文章,讲述如何快速的创建一个合规的中国地图。

详细了解请参考之前文章:分享 ECharts 地图合规整改经验,并实现一个最基础的中国地图

在这里,我们简单的总结一下,完成两步就可以渲染一个中国地图。

1. 准备地图数据

首先,我们需要准备多层级的地图数据,比如国家、省份、城市等各级别的地理数据,以及每个区域对应的数据指标,这些数据通常是以 JSON 格式提供的地理信息数据。同时,确保数据格式符合 ECharts 的要求,可以参考官方文档了解各种地图类型的数据格式。

我们可以在一些其他网站获取最新的 geoJson,比如:我是通过阿里云 DataV 数据可视化平台下载最新的 json 数据文件,以保证目前所有市区的数据都是最新的。

如下图所示,选择数据版本后,点击页面上的下载按钮后即可以下载 json 文件:

image.png

本地调试也可以使用在线的 JSON API 接口获取数据,不过仅限于本地测试使用!线上会 403 错误,已解决,如下,API 地址:https://geo.datav.aliyun.com/areas_v3/bound/geojson?code={adcode}_full

解决 403 问题,参考文章:巧用 meta 标签,设置 referrer 解决 403 Forbidden 问题

2. 初始化 ECharts 地图

在 ECharts 的配置项中,配置地图组件并设置合适的地图类型(如中国地图、世界地图等),以及需要展示的数据和样式,确保每个区域都有对应的数据用于显示。

还是以中国地图为例,创建一个 ECharts 地图实例,并加载最顶层(国家级)的地图数据:

const myChart = echarts.init(document.getElementById("main"));
function setOption(name, data) { const option = { geo: { // 使用 registerMap 注册的地图名称。 map: name, roam: true, }, series: [ { type: "map", map: name, // 地图名称 geoIndex: 0, roam: true, data: data, // 地图数据 }, ], }; myChart.setOption(option, true);}
const data = chinaGeoJson; // 第一步所准备的地图 json 数据setOption("china", data);

完成以上两个步骤就可以实现中国地图的正常展示了,以上为简洁版的中国地图,如果想要添加更多的地图属性,可以根据 ECharts 官方配置项手册文档进行配置,这里就不再详细说明了。

ECharts 地图配置项手册

接下来我们要进行的是如何在用户点击地图省、市、区的时候进行下探地图显示!

四. 实现地图下钻

实现地图下钻的关键逻辑在于:为地图添加点击事件监听器,当用户点击地图上的某个区域时,触发相应的事件处理函数,根据点击的区域获取下一级别的地图数据并更新图表。

实例场景:比如,我点击山东省,可以查看山东省下各市级地图,点击青岛市,进而查看青岛市下各区级地图。

实现逻辑

  • 当用户点击某个区域时,例如:山东省,获取到该区域对应的编码。

  • 通过该区域对应的编码,获取到该区域的 geoJson 数据。

  • 通过该区域的 geoJson 数据,渲染到 ECharts 地图组件上。

接下来我们一步一步进行分析。

1. 获取区域编码

首先需要给地图添加点击事件监听器,当用户点击地图时,获取到用户点击该区域对应的编码。

myChart.on("click", function (params) {  if (params.data) {    const { adcode, name, level } = params.data;  }});
地图下钻 3.gif

如图所示,通过上述的操作,我们能够轻松的获取到该区域的地理编码 adcode 和名称。

2. 获取点击区域地图 JSON 数据

获取到地理编码 adcode 和名称之后,接下来需要通过 adcode 来获取子区域的 geoJson,以下的代码是通过调用阿里云 DataV 在线的 JSON API 接口获取到的数据。

注意:过调用阿里云 DataV 在线的 JSON API 接口获取到的数据,仅限于调试!线上会 403 错误,如果要上线,需要将各个区域的数据下载到本地加载。

// 根据 adcode 获取原始地图json数据function getJSON(adcode, callback) {  $.getJSON(    `https://geo.datav.aliyun.com/areas_v3/bound/geojson?code=${adcode}_full`,    function (data) {      callback(data);    }  );}// 例如:根据 adcode 获取省市区的 json 数据// 获取山东省下的所有市的数据getJSON("370000", function (data) {  console.log("山东省子区域地图数据:", data);});
// 获取青岛市下的所有区级数据getJSON("370200", function (data) { console.log("青岛市子区域地图数据:", data);});
地图下钻 4.gif

通过上图所示,用户点击某个省份,获取到该省份的 adcode,根据 adcode 获取该省份下所有市对应的 geoJson 数据。

3. 渲染区域地图

通过上述操作,我们成功的获取到了点击区域的子区域地图 JSON 数据,通过 JSON 数据,我们就可以动态的渲染区域地图了,如下代码所示:

// 渲染地图function renderChart(name, data) {  // 注册地图  echarts.registerMap(name, data);  // 根据 json 数据拼装 mapdata, 用于地图点击下钻时传递数据,主要有adcode、name  const mapdata = data.features.map((item) => {    return item.properties;  });  // 配置option  setOption(name, mapdata);}
// 根据adcode区域编码获取地图数据,例如:根据山东省的区域编码:370000,获取市区geoJson数据getJSON("370000", function (data) { console.log("山东省子区域地图数据:", data); renderChart("山东省", data);});
地图下钻 2.gif

五. 完善交互和效果

为提升用户体验,可以添加一些校验,避免在下钻过程中出现一些异常情况。比如:

  • 在地图下钻的最后一层,如何判断处理该地图是否还有下级区域,简单说就是是否还允许地图继续下钻?

  • 地图下钻过程过程中,我需要返回上一级地图,该如何实现?

以上这两个问题是在地图开发中必须要考虑的基础问题,下面我来分析一下如何优化这两种问题,提升用户体验。

1. 处理递归下钻

在事件处理函数中,根据用户点击的区域信息,判断是否需要进行下钻操作。如果需要下钻,才可以展示子区域的地图信息。如果已经到了地图最末端,无法再进行下钻,应该相应提示用户。

例如,当用户点击到区县级地图且无法再下钻时,可以考虑弹窗显示详细信息或者返回至上一级别。

// 设置地图点击事件myChart.on("click", function (params) {  if (params.data) {    const { adcode, name, level } = params.data;    // 判断如果是 district 层级,则提示用户已经为最底级了    if (level === "district") {      alert("无此区域地图显示!");      initChinaMap(); // 重新渲染中国地图或其他逻辑处理      return;    }    // 继续进行下钻    getJSON({ name, adcode }, function (data) {      renderChart(name, data);    });  }});
地图下钻 5.gif

2. 返回上一级地图

在用户点击地图进行下钻的过程中,难免会返回上一层进行重新点击的需求,这种需求应该怎么实现呢?下面我来具体分析一下:

  • 添加返回按钮,返回按钮显示隐藏逻辑处理,比如:仅当可以返回上一层地图级别的时候才显示返回
  • 记录地图下钻过程中的地图层级数据,比如:山东省 -> 青岛市 -> 崂山区
  • 根据记录的层级数据实现返回上一级操作

返回按钮的显示和隐藏

关于返回按钮的显示和隐藏,可以有多种判断方式,可以根据是否为初始化地图来判断,只有当前渲染为初始地图时,隐藏返回按钮,也可以根据记录地图的层级数据数组判断是否显示返回按钮。

下述代码是根据 adcode 来判断是否为初始地图,因为我是以中国地图为初始化地图,所以判断 adcode 是否等于 100000 来判断是否显示,如下代码所示:

// 设置返回策略,根据 adcode 区域编码判断是否需要返回function setBackbtn({ name, adcode }) {  // 如果为初始化的中国地图,则不显示返回  if (adcode === 100000) {    // 显示返回按钮    $("#back").hide();  } else {    // 隐藏返回按钮    $("#back").show();  }}

以上只是一种思路,你可以考虑其他方式判断,合理即可!

记录地图的层级数据

需要定义一个变量 mapList 数组,主要用于返回时可以根据 adcode 获取上一级的地图数据。当用户点击地图进行下钻时,记录地图的名称、级别和编码。当用户返回上一级的时候,需要删除记录数组中对应的数据。

// 点击地图下钻时记录name和adcodemapList.push({ name, adcode });
// 点击返回时删除对应的name和adcodemapList.splice(-2, 2);

返回上一级

根据 mapList 数组中记录的层级数据实现返回上一级操作,点击返回时取出记录 name 和 adcode,获取上一级地图数据,返回成功后删除对应的 name 和 adcode

// 点击返回,地图返回上一级function goBack() {  if (mapList.length >= 2) {    const { name, adcode } = mapList[mapList.length - 2];    mapList.splice(-2, 2);    getJSON({ name, adcode }, function (data) {      renderChart(name, data);    });  }}
地图下钻 6.gif

3. 自定义 tooltip

加一些指向 tooltip 提示,当用用鼠标指向省市区时,显示省市区的名称、编码及层级数据,如下代码实现:

option = {  // tooltip 提示配置项  tooltip: {    formatter: function (params) {      // 根据需要进行数据处理或格式化操作      const { adcode, name, level } = params.data;      // 返回自定义的tooltip内容      return `adcode: ${adcode}<br>name: ${name}<br>level: ${level}`;    },  },};

更多配置请查看 tooltip 相关文档:ECharts geo.tooltip 配置项

完成以上所有的操作后,最终的效果图如下所示:

地图下钻7.gif

六. 总结

通过本篇文章的详细讲述,我们应该都有了一个明确的思路,可以借助 ECharts 快速地实现地图下钻功能。当然,本文完成的是核心下钻逻辑,而且也没有对地图的样式进行一些复杂的样式配置,在实际应用中可能还需要对颜色映射、数据标注等方面进行个性化定制,但这些并不是难点,相信参考 ECharts 配置项手册来进行配置地图属性,也是非常容易实现的。

因此,开发地图的关键点在于开发地图的过程中,我们始终要有一个清晰明了的开发思路和步骤,才能保证按部就班的实现功能,并且避免一些不必要的 BUG 产生。

比如:关于使用 ECharts 的图表渲染造成的内存溢出,导致浏览器崩溃问题,最终一步一步复盘代码才能解决问题。本文在这方面没有详细说明,如果想要详细查看参考之前文章:分析 ECharts 图表渲染导致的内存泄漏问题 - 附解决方案

七. 资源链接

  1. 代码演示地址:中国地图下钻示例演示:支持所有省市下钻演示

  2. 源码地址:ECharts 地图下钻源码地址

  3. geoJson 文件下载:全国地图下钻 geoJson 完整版下载 20240312.zip

  4. 官方文档:ECharts 地图配置项手册

由于时间原因,目前我只导入了山东省的地图,其他各个省市区的地图数据大家可以按需下载导入!后面我会都导入到本地。感谢您的阅读!

最新更新,已经支持中国所有省市下钻!

推荐文章

关于 ECharts 的系列文章,大家可以点解查看以下文章进行了解:

  • ECharts-GL 实战分享:教你轻松实现 3D 地图下钻功能

  • 使用 ECharts-GL 实现世界级、国家级、省市级 3D 地图

  • ECharts-GL 实战:轻松实现 3D 旋转地球

如果您感觉文章还不错,点个赞再走吧!

点击关注公众号,“技术干货” 及时达!

稀土掘金技术社区
掘金,一个帮助开发者成长的技术社区
 最新文章