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

一. 前言

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

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

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

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

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

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

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

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

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

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

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

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

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

1. 准备地图数据

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

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

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

本地调试也可以使用在线的 JSON API 接口获取数据,不过仅限于本地测试使用!线上会 403 错误,API 地址:geo.datav.aliyun.com/areas_v3/bo...

2. 初始化 ECharts 地图

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

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

javascript 复制代码
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. 获取区域编码

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

javascript 复制代码
myChart.on("click", function (params) {
  if (params.data) {
    const { adcode, name, level } = params.data;
  }
});

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

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

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

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

javascript 复制代码
// 根据 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);
});

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

3. 渲染区域地图

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

javascript 复制代码
// 渲染地图
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);
});

五. 完善交互和效果

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

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

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

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

1. 处理递归下钻

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

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

javascript 复制代码
// 设置地图点击事件
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);
    });
  }
});

2. 返回上一级地图

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

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

返回按钮的显示和隐藏

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

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

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

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

记录地图的层级数据

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

javascript 复制代码
// 点击地图下钻时记录name和adcode
mapList.push({ name, adcode });

// 点击返回时删除对应的name和adcode
mapList.splice(-2, 2);

返回上一级

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

javascript 复制代码
// 点击返回,地图返回上一级
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);
    });
  }
}

3. 自定义 tooltip

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

javascript 复制代码
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 配置项

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

六. 总结

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

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

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

七. 资源链接

  1. 代码演示地址:地图下钻示例演示:仅支持山东省下钻演示

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

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

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

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

相关推荐
想退休的搬砖人20 分钟前
axios请求中的data和params的区别
前端
前端李易安21 分钟前
如何封装一个axios,封装axios有哪些好处
前端·vue.js·axios
sky.fly37 分钟前
HTML5+css3(伪类,动态伪类,结构伪类,否定伪类,UI伪类,语言伪类,link,hover,active,visited,focus)
开发语言·前端·css3·html5
沈询-阿里43 分钟前
spring ai 入门 之 结构化输出 - 把大模型llm返回的内容转换成java bean
前端·javascript·easyui
ormcc2 小时前
layui tree customSelet选中的内容重写,查找父级
前端·javascript·layui·tree·customselect
野槐3 小时前
前端Nginx的安装与应用
前端
高申航3 小时前
前端与后端长连接 方法
前端
Suncsf3 小时前
JavaFX WebView + Vue初始化加载数据解决方案
前端·javascript·vue.js·javafx
魏大帅。3 小时前
Webpack入门教程:从基本概念到优化技巧
前端·webpack·node.js
前端拾光者3 小时前
前端项目配置文件的各种配置
前端·配置