- 地图JSON数据下载
- 注册地图
echarts.registerMap:
- 使用该函数注册地图
- type: echarts 方法(不是实例的方法)
- 参数
- name (string): 注册地图的名字
- object:
- geoJson: 注册地图的geoJson数据
- 注册完成后,便可使用该地图
- 使用地图
使用地图有两种方式:
-
- object:
- map (string): 注册地图的名字
- show (boolean): 是否显示地理坐标系组件
- roam (boolean):缩放、平移
- .....
- object:
-
使用 serires 注册 地图主要用于地理区域数据的可视化,配合 visualMap 组件用于展示不同区域的人口分布密度等数据
-
- object
- type (string): 'map' 地图组件
- map (string): 注册的地图的名字
- ......
- object
- 地图上下钻
思路: 监听 echarts 的点击事件,获取点击的地点名与geojson,之后再使用registerMap方法重新注册地图
- 自动获取所有geoJson数据(vite)
// 自动导入geoJson数据
const modules = import.meta.glob("@/geoJson/*.json", { eager: true });
const pattern = /(?<=geoJson\/).*(?=\.json)/;
const geoJson = {};
Object.keys(modules).forEach(async (item) => {
const name = item.match(pattern)[0];
const data = modules[item];
geoJson[name] = data.default;
});
export default geoJson;
数据如下形式:
geoJson = {
全国: {
geoJson: [... ],
info: {
name: ' ... ',
level: '...',
adcode: ...
}
},
江西省:{
geoJson: {...},
info: {...}
}
...
}
- 初始化地图 我们使用 historyList 存储每个层级的数据,index存储地图层级,如初始进入 index 为 0,historyList存入 全国数据:
// 历史列表
const historyList = reactive([]);
// 层级
const index = ref();
onMounted(() => {
myEchart.value = useEcharts(main.value, null, {
width: "auto",
height: "auto",
});
pushHistory(historyList, mapData.info);
index.value = 0
})
向 historyList 添加记录: 当 info 的 level 为同一级则不添加到历史列表中,如两次都点击为 省,表明没有下钻,则不需要添加至记录中
export const pushHistory = (list, info) => {
if (list.length === 0) {
list.push(info);
return;
}
const index = list.length - 1;
if (list[index].level === info.level) {
list[index] = info;
} else {
list.push(info);
}
};
注册 map 组件: 我们使用 watch 监听层级 index 的变化,当层级变化就说明进行了下钻回或上钻,此时我们只需要重新注册地图,并且我们将 index 初始值赋值为空,初始化地图时我们 赋予 index 为 0,也会触发 watch,进行地图的初始化注册
watch(index, (newv) => {
let name = historyList[newv].name;
const geoJson = map.value[name].geoJson;
registerMap(name, { geoJson });
myEchart.value.setOption({
// 标题组件,包含主标题和副标题。
title: {
show: true,
// 主题文字内容
text: "全国经济情况(假)",
// 主标题文字样式
textStyle: {
color: "red",
fontStyle: "italic",
textBorderColor: "#000",
textBorderWidth: 1,
width: 100,
textShadowColor: "red",
textShadowBlur: 3,
textShadowOffsetY: 3,
},
subtext: "2022-10-11(数据随机)",
subtextStyle: {
color: "red",
fontStyle: "italic",
},
left: "center",
},
// 地理坐标系组件用于地图的绘制,支持在地理坐标系上绘制散点图,线集
geo: {
map: name,
show: false,
},
// 提示框组件。
tooltip: {
show: true,
trigger: "item",
// 提示框浮层内容格式器,支持字符串模板和回调函数两种形式。
formatter(params) {
return `${params.name}: ${params.value}`;
},
backgroundColor: "rgba(0, 0, 0, 0.7)",
textStyle: {
color: "#fff",
},
},
series: [
// 地图组件
{
name: "经济",
type: "map",
// 使用 registerMap 注册的地图名称。
map: name,
// 是否显示地理坐标系组件。
show: true,
// 是否开启鼠标缩放和平移漫游。默认不开启。如果只想要开启缩放或者平移,可以设置成 'scale' 或者 'move'。设置成 true 为都开启
roam: true,
label: {
show: true,
color: "#fff",
},
itemStyle: {
// 地图整体颜色
areaColor: "#fff",
// 地图线条颜色
borderColor: "#1773c3",
// 阴影颜色
shadowColor: "#1773c3",
// 阴影大小
shadowBlur: 4,
shadowOffsetY: 1,
// 图形颜色,与areaColor颜色一致,优先级若于areaColor
color: "#000",
//描边线宽
borderWidth: 0,
//描边类型。
borderType: [5, 10],
borderDashOffset: 130,
},
//高亮状态下的多边形和标签样式。
emphasis: {
disabled: false,
focus: "none",
label: {
color: "red",
fontWeight: "bolder",
},
// 地图区域的多边形 图形样式。
itemStyle: {
areaColor: "#1773c3",
},
},
//选中状态下的多边形和标签样式。
select: {
label: {
fontWeight: "bolder",
color: "#fff",
},
itemStyle: {
areaColor: "#000",
},
},
// regions: [
// {
// name: "江西省",
// itemStyle: {
// areaColor: "red",
// color: "red",
// },
// },
// ],
},
],
});
});
- 监听 echarts 点击事件 实现地图上下钻
地图下钻 点击地图时,监听 ecarts 点击事件,可以获取到 地图名称,我们只需要将层级 index 加一 ,并且将地图的info添加至记录(historyList),触发 watch 进行地图的重新注册,实现地图下钻
myEchart.value.on("click", (params) => {
console.log("params", params.name);
const name = params.name;
if (!map.value[name]) return;
index.value = index.value + 1;
pushHistory(historyList, map.value[name].info);
});
地图上钻 当点击空白处,没有点击地图时,我们将层级 index 减一,将记录(historyList)最后的info删除,index 变化会触发 watch 进行地图重新注册
// 点击空白处时,返回地图的上一级
myEchart.value.getZr().on("click", async (event) => {
if (!event.target) {
console.log("点击了空白处");
popHistiry(historyList)
.then(() => {
index.value = index.value - 1;
})
.catch((err) => {
console.log("不能再返回了");
});
}
});
监听“空白处”的事件 直达: 有时候,开发者需要监听画布的“空白处”所触发的事件。比如,当需要在用户点击“空白处”的时候重置图表时。
在讨论这个功能之前,我们需要先明确两种事件。zrender 事件和 echarts 事件。
myChart.getZr().on('click', function(event) {
// 该监听器正在监听一个`zrender 事件`。
});
myChart.on('click', function(event) {
// 该监听器正在监听一个`echarts 事件`。
});
zrender 事件与 echarts 事件不同。前者是当鼠标在任何地方都会被触发,而后者是只有当鼠标在图形元素上时才能被触发。事实上,echarts 事件是在 zrender 事件的基础上实现的,也就是说,当一个 zrender 事件在图形元素上被触发时,echarts 将触发一个 echarts 事件给开发者。
有了 zrender 事件,我们就可以实现监听空白处的事件,具体如下:
myChart.getZr().on('click', function(event) {
// 没有 target 意味着鼠标/指针不在任何一个图形元素上,它是从“空白处”触发的。
if (!event.target) {
// 点击在了空白处,做些什么。
}
});
完整代码
<script setup>
import mapGeoJson from "../geoJson";
import { ref, shallowRef, onMounted, watch, reactive, watchEffect } from "vue";
import { registerMap, useEcharts } from "../utils/echarts";
import { pushHistory, popHistiry } from "../utils/mapHistory.js";
import mapData from "../geoJson/全国.json";
const map = shallowRef(mapGeoJson);
const main = ref(null);
const myEchart = shallowRef(null);
const historyList = reactive([]);
const index = ref();
onMounted(() => {
myEchart.value = useEcharts(main.value, null, {
width: "auto",
height: "auto",
});
pushHistory(historyList, mapData.info);
index.value = 0;
// 点击地图下钻
myEchart.value.on("click", (params) => {
console.log("params", params.name);
const name = params.name;
if (!map.value[name]) return;
index.value = index.value + 1;
pushHistory(historyList, map.value[name].info);
});
// 点击空白处时,返回地图的上一级
myEchart.value.getZr().on("click", async (event) => {
if (!event.target) {
console.log("点击了空白处");
popHistiry(historyList)
.then(() => {
index.value = index.value - 1;
})
.catch((err) => {
console.log("不能再返回了");
});
}
});
});
watch(index, (newv) => {
// 清空当前实例,会移除实例中所有的组件和图表。
let name = historyList[newv].name;
const geoJson = map.value[name].geoJson;
registerMap(name, { geoJson });
myEchart.value.setOption({
// 标题组件,包含主标题和副标题。
title: {
show: true,
// 主题文字内容
text: "全国经济情况(假)",
// 主标题文字样式
textStyle: {
color: "red",
fontStyle: "italic",
textBorderColor: "#000",
textBorderWidth: 1,
width: 100,
textShadowColor: "red",
textShadowBlur: 3,
textShadowOffsetY: 3,
},
subtext: "2022-10-11(数据随机)",
subtextStyle: {
color: "red",
fontStyle: "italic",
},
left: "center",
},
// 地理坐标系组件用于地图的绘制,支持在地理坐标系上绘制散点图,线集
geo: {
map: name,
// 不显示组件,如果 series 注册了地图,geo也注册可,会显示两个地图组件(重叠)
show: false,
},
// 提示框组件。
tooltip: {
show: true,
trigger: "item",
// 提示框浮层内容格式器,支持字符串模板和回调函数两种形式。
formatter(params) {
return `${params.name}: ${params.value}`;
},
backgroundColor: "rgba(0, 0, 0, 0.7)",
textStyle: {
color: "#fff",
},
},
series: [
{
name: "经济",
type: "map",
// 使用 registerMap 注册的地图名称。
map: name,
// 是否显示地理坐标系组件。
show: true,
// 是否开启鼠标缩放和平移漫游。默认不开启。如果只想要开启缩放或者平移,可以设置成 'scale' 或者 'move'。设置成 true 为都开启
roam: true,
label: {
show: true,
color: "#fff",
},
itemStyle: {
// 地图整体颜色
areaColor: "#fff",
// 地图线条颜色
borderColor: "#1773c3",
// 阴影颜色
shadowColor: "#1773c3",
// 阴影大小
shadowBlur: 4,
shadowOffsetY: 1,
// 图形颜色,与areaColor颜色一致,优先级若于areaColor
color: "#000",
//描边线宽
borderWidth: 0,
//描边类型。
borderType: [5, 10],
borderDashOffset: 130,
},
//高亮状态下的多边形和标签样式。
emphasis: {
disabled: false,
focus: "none",
label: {
color: "red",
fontWeight: "bolder",
},
// 地图区域的多边形 图形样式。
itemStyle: {
areaColor: "#1773c3",
},
},
//选中状态下的多边形和标签样式。
select: {
label: {
fontWeight: "bolder",
color: "#fff",
},
itemStyle: {
areaColor: "#000",
},
},
// regions: [
// {
// name: "江西省",
// itemStyle: {
// areaColor: "red",
// color: "red",
// },
// },
// ],
},
],
});
});
</script>
<template>
<div class="main" ref="main"></div>
</template>
<style lang="scss" scoped>
.main {
width: 1400px;
height: 900px;
}
</style>