ECharts - 地图三级下钻
前言
最近项目中用到了地图下钻
功能,GitHub上找到了一个轮子 - echarts3-chinese-map-drill-down,启动项目看了一下Demo,动画衔接的很流畅,膜拜大佬🙏🙏🙏
我用 VScode 打开这个项目的时候,发现注册地图用的部分原始 JSON数据乱码了,但不影响项目运行。粗略看了一下源码,技术栈用的是jQuery + EChars
,本着与时俱进的想法,打算用Vue + EChars
写一个新轮子,哈哈哈哈,其实是我不太想在项目中用 JQuery 这种远古时代的 JavaScript 库,傲娇脸😕
此篇文章用于记录柏成从零开发一个地图三级下钻Demo
的历程,最终效果如下:
初始化地图实例
初始化香港18区人口密度
由于之前没有接触过 ECharts 的地理坐标/地图,本着官网是第一手学习资料原则,柏成首先初始化了一个官网示例 - 香港18区人口密度,并根据 文档配置项手册 自定义了地图样式,注册地图用到了一个方法:registerMap
registerMap(mapName: string, geoJson: Object)
-
mapName
-
geoJson
GeoJson 格式的数据,具体格式见 https://geojson.org,ECharts 使用 geoJSON格式的数据作为地图的轮廓
初始化中国地图
通过官网示例柏成了解了地图相关的属性及API,对 ECharts 地图有了一个大概认知,接下来我们初始化一个中国地图,此时我们需要中国地图的 geoJSON格式的数据,通过ECharts官网得知 地图下载
ECharts 之前提供下载的矢量地图数据来自第三方,由于部分数据不符合国家《测绘法》规定,目前暂时停止下载服务。
好家伙,看到官网通告我差点嗝屁了😱,最终在 github 上找到了 中国省市区县geoJSON格式地图数据✨
![](https://img2020.cnblogs.com/blog/2180164/202103/2180164-20210315170854604-423983337.png)
注册渲染地图之后发现文本标签位置并不理想,部分标签偏移到了地图之外,例如内蒙古,部分标签揉挤作一团,例如北京天津河北,此时我们需要修改 china.json 原始 geoJSON数据,给每个省份的properties
属性下新增cp
属性,即文字居中位置,例如新疆维吾尔自治区数据,详细 china.json 数据请移步 vue-map-drilling 查看
{
"type": "Feature",
"properties": {
"adcode": 650000,
"name": "新疆",
"cp": [86.9023, 41.148],
...
},
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[79.039649, 34.33427],
[78.958961, 34.386132],
[78.878273, 34.391563],
...
]
]
]
}
},
}
噔噔噔噔😎,这样看着就舒服多了
![](https://img2020.cnblogs.com/blog/2180164/202103/2180164-20210315171155063-618322477.png)
自定义鼠标事件
自定义单击事件
查阅 ECharts 官方API文档 ECharts / API / 鼠标事件 得知左击事件为:myChart.on('click', (e) => {})
,我们需要在此处实现下钻进入下一级地图的逻辑
点击某个区域高亮,鼠标移出地图后高亮并没有消失,将 ECharts 版本降级为 v4 即可 npm i echarts@4 -S
// 绑定自定义单击事件
bindClickChart () {
this.myChart.on('click', e => {
console.log(e)
})
},
自定义右击事件
首先要阻止默认右击事件上下文菜单【图片另存为,复制图片 ... 】
然后再自定义右击事件,查阅 ECharts 官方API文档 ECharts / API / 鼠标事件 得知右击事件为:myChart.on('contextmenu', (e) => {})
,我们需要在此处实现返回上一级地图的逻辑
// 绑定自定义右击事件
bindContextmenuChart () {
// 取消右击默认事件
const container = document.getElementById('chart')
container.oncontextmenu = e => e.preventDefault()
// 绑定自定义右击事件
this.myChart.on('contextmenu', e => {
console.log(e)
})
},
下钻思路
地图下钻用到了栈先入后出的思想
大体思路:左击地图进入下一级时,获取注册渲染下一级地图所需的 geoJSON数据 和 seriesData数据,然后注册渲染下一级地图。并把当前地图数据入栈;右击返回地图上一级,数据出栈并注册渲染地图
如果按照此思路严格执行的话,会发现我们需要创建一个额外的变量去存储当前的地图数据,用以左击地图入栈使用
优化:始终保持栈中最顶层的数据即是当前渲染的地图数据。只要地图渲染完毕,立即把当前地图数据入栈(若栈中无此地图数据),而不是左击地图时才进行入栈操作。当我们右击返回上一级时,需要先把最顶层数据pop出栈,然后再渲染栈顶地图数据
我们将地图数据入栈前,需要先判断下栈中是否已经存在此数据。若存在,则不入栈;若不存在,则入栈
下钻动效
开发前的预期效果:当我重新注册并渲染地图时,想当然的认为 ECharts 会自动处理地图上下级关系并注入切换动效,毕竟官网对setOption
方法的介绍:
设置图表实例的配置项以及数据,万能接口,所有参数和数据的修改都可以通过
setOption
完成,ECharts 会合并新的参数和数据,然后刷新图表。如果开启动画的话,ECharts 找到两组数据之间的差异然后通过合适的动画去表现数据的变化。
当我使用 ECharts v4.9.0 实际操作时发现,地图层级之间毫无过渡动画,生硬至极,what❓,难道地图注册registerMap
不兼容setOption
动画❗,不应该吧❓,马上就薅成👴时,我隐隐感觉可能是ECharts版本的锅
于是我更新了 Echarts 最新版本 v5 npm i echarts@latest -S
,重启项目发现还是不行!重来,之后我又将 Echarts 降级到了 v3 版本 npm i echarts@3 -S
,大功告成👌
经亲自尝试,只要ECharts版本 <= v4.3.0,即自带下钻动效✨✨✨
为什么版本更新会把地图下钻的动效给去掉呢?很是不能理解,也可能是我太菜了,没找到 Echarts 最新版本开启地图下钻动效的正确方式,如有大佬知道,请指点一二
源码
地图下钻demo代码:vue-map-drilling