前三篇回顾:
第一篇:Vue3.0按需引入vue-echarts6.x版本—0.1-绘制中国地图
第二篇:Vue3.0按需引入vue-echarts6.x版本—0.2-Echarts5.x地图点击选中样式修改
第三篇:Vue3.0按需引入vue-echarts6.x版本—0.3-Echarts5.x地图自动轮播数据
时隔差不多一个半月再来更新这个系列,我可真是……虽迟但到??!!
我接受吐槽~
言归正传,本片讲的是:“地图下钻”,具体的下钻之前有一篇文章(vue-echarts-v3——浙江省地图下钻(eg:浙江省-嘉兴市-嘉善县))是有讲过的,对echarts5.0版本来说,下钻的逻辑和之前的没什么变化,但是在一些属性的使用上,我进行了修改,主要也是对 echarts5.x 版本中地图的 select 属性有新增,具体如下:
地图下钻解析
- 首先有所有地图的json数据包,这个可以在阿里的DATAV.GeoAtlas下载;
- 在组件中引入地图数据,但我们总不能全量引入吧,这就有点粗糙了,那我们可以用axios的get请求方法进行地图数据包的加载,所以,提前安装 axios,并引入axios。
- 前两步应该是准备工作,所以,接下来开始 echarts 的属性配置,在本次使用echarts 和 vue-echarts 还是采用了按需引入(CanvasRenderer,TooltipComponent)的方式,按需引入在之前的3篇中有讲解,详细可点击查阅本篇文章的开头几篇。
- TooltipComponent 用来展示每个区域块展示信息;CanvasRenderer 表示最终绘制以canvas呈现,可以使用 SVGRenderer,最终呈现就会是SVG 格式的图。
- 在 series 属性配置中,type:map,map 的名字确实要动态给的,所以,我们先来确定有几个函数方法:
- mapChart --> 用来绘制地图
- registerAndsetOption --> 用来动态 注册地图并赋值 option 属性
- onClick --> 地图区域点击后 操作
- onBack --> 返回上一级
文件结构
先来说一下,下载下来后,我写的源码中,代码结构是什么;
public/mapJson:
这个是下载后的 每个市/区/县的地图json数据包;
每个json的命名是 该地区的 地区编码,可以修改。
src/assets/js/zhejiang-main-city-map.js
这个js文件是为了将 地区 和 地区编码一一对应起来,在改变json地区包的名称时,一定要在这里做一次更新。
代码块注释
mapChart ()
在mapJson地图包的命名上,我们可以看出来,前两位都是 33 表示“浙江省”,中间两位是 01/ 02/03/04……表示“市级”,最后的两位表示的是“区/县”。
有了这个命名规律,那在用axios请求地图包的json数据时,可以先对已有的地区ID做处理,这里需要说明的是,地区ID 也就是刚才我们一一对应的js中的id值,具体代码如下:
// geoJSON 绘制 地图
const mapChart = () => {
let numId = Number(cityMap[mapData.ZJName]);
if (numId.toString().slice(-2) == "00") {
mapData.ZJId = 330000;
} else {
mapData.ZJId = Number("33" + numId.toString().slice(2, 4) + "00");
}
axios.get("/mapJson/" + mapData.ZJId + ".json").then((res) => {
mapData.mapJson = res.data;
registerAndsetOption(mapData.ZJName, mapData.mapJson);
});
};
registerAndsetOption ()
这个方法主要用来 刷新当前展示的地图,重点方法可看注释;
/**
*
* @param {*} name 省市县名称
* @param {*} mapJson 地图Json数据
*/
const registerAndsetOption = (name, mapJson) => {
registerMap(name, mapJson); // 根据传来的地区名称和 地图包数据,重新注册 更新地图
mapData.mapZJOption = {
//配置属性
series: [
{
name: "浙江-地图",
type: "map",
map: name, // 动态赋值 地图名称
zlevel: 2,
roam: false,
silent: false,
selectedMode: "single",
itemStyle: { // 地图无交互状态下 属性
areaColor: "#0f89d9",
borderColor: "rgba(255,255,255,0.2)",
borderWidth: 1,
},
label: { // 地图文本
show: true,
fontSize: 20,
color: "#fff",
},
emphasis: { // 地图 鼠标滑过 属性
label: {
show: true,
fontSize: 20,
color: "#fff",
},
itemStyle: {
areaColor: "rgba(7, 103, 218)",
},
},
select: { // 地图 鼠标点击选中 属性,
label: {
show: true,
fontSize: 20,
color: "#fff",
},
itemStyle: {
areaColor: "#0f89d9",
},
},
},
],
};
};
onClick ()
这个是地图区域点击后的行为;地图下钻嘛,肯定是 点击后,下钻到当前地区的下一级,那onClick方法就是来解决这个,在点击后,可以获取到三个属性(event),如下:
如上图,我们只需要拿到“name”,然后跟cityMap中匹配查找到对应的地区ID,在进行该地区的地图json包请求就可以啦。
const onClick = (event) => {
// console.log(event);
let cityId = cityMap[event.name];
if (cityId) {
mapData.isShowBack = true;
//代表有下级地图
mapData.ZJId = Number(cityId);
mapData.ZJName = event.name;
emit("getCityNameData", event);
axios.get("/mapJson/" + mapData.ZJId + ".json").then((res) => {
mapData.mapJson = res.data;
registerAndsetOption(mapData.ZJName, mapData.mapJson);
});
} else {
console.log("没有下一级");
}
};
onBack ()
这个方法用来返回到上一级,难点有两个:
- “返回上级”这个该不该展示,在省级就不用展示,在市级/区/县就得展示,如何判断这个;
- 应该返回的上一级 是哪一级?是哪个地区?
这两个问题,其实本质上是一个问题,就用到了刚才我们提到的
判断“返回上级”是否应该显示,可以判断 当前地区ID 的最后两位是不是“00”,是的话就是当前展示的是省级地图,就不用展示“返回上级”,反之同解。
如果当前是在区/县级,可以对当前地区ID进行字符串截取,截取中间两位,然后通过拼接,在用axios进行请求。
//点击返回按钮--》返回上层
const onBack = () => {
if (mapData.ZJId.toString().slice(-2) == "00") {
mapData.isShowBack = false;
} else {
mapData.isShowBack = true;
}
if (mapData.ZJId.toString().slice(-2) == "00") {
mapData.ZJId = 330000;
} else {
mapData.ZJId = Number("33" + mapData.ZJId.toString().slice(2, 4) + "00");
}
for (let key in cityMap) {
if (cityMap[key] == mapData.ZJId) {
mapData.ZJName = key;
}
}
emit("getCityNameData", { name: mapData.ZJName });
axios.get("/mapJson/" + mapData.ZJId + ".json").then((res) => {
mapData.mapJson = res.data;
registerAndsetOption(mapData.ZJName, mapData.mapJson);
});
};
基本上,代码的讲解已经结束了。
之前在第一篇承诺的关于 echarts5.x 和 vue-echarts6.x 的讲解,在这几篇中基本都有了体现,基本可以结束这个更新了,接下来我会投入到D3的更新中,大家一起加油呀。
老规矩:文章会同步更新到微信公众号 “DataShow Charts”,可以扫码关注下,源码的链接会发在公众号的文章里,希望多多关注,谢谢你呀~