效果:
一、获取GeoJson地图数据:
DataV.GeoAtlas 地理工具https://datav.aliyun.com/portal/school/atlas/area_selector
这里只下载了是省、市的数据,要下载县/区的话需要指定市单独下载(或者直接找网上资源),然后放在本地目录下:
二、核心代码:
1.注册地图数据:
const initMap = (fileName) => {
// JSON文件(地图数据)路径
let dataURL = `GeoJSON/${fileName}.json`;
fetch(dataURL).then((res) => res.json()).then((geoJson) => {
// 如果是下钻到市级,则注册的registerGeoJSON为当前省下面的所有市级数据范围
let registerGeoJSON = fileName === 'city' ? getCitys(geoJson) : geoJson;
// 注册地图名字(fileName)和数据(registerGeoJSON)
echarts.registerMap(fileName, registerGeoJSON);
//配置echarts
let options = {
series: [{
type: 'map3D',
map: fileName,// 注册的地图名字
...
}]
}
options && chartDom.value.setOption(options);
})
}
// 获取当前省的市级数据
const getCitys = (geoJson) => {
let cityArr = geoJson.features.filter(feature => {
return feature.properties?.parent?.adcode === curProvince.adcode;
});
return {
features: cityArr
}
}
2.阻止右键,返回到省层级:
<div id="echartsDom" @contextmenu.prevent="initMap('province')"></div>
三、完整代码:
<template>
<div id="echartsDom" @contextmenu.prevent="initMap('province')"></div>
</template>
<script setup>
import { onMounted, ref, shallowRef } from "vue"
//echarts
import * as echarts from 'echarts'
import 'echarts-gl'
import { message } from 'ant-design-vue'
let curProvince = { //当前省数据
name: '',
adcode: null,
}
const chartDom = shallowRef();
const echartsRef = ref();
onMounted(() => {
initEcharts();
initMap('province');
})
const initEcharts = () => {
chartDom.value = echarts.init(document.getElementById('echartsDom'));
chartDom.value.on('click',function (params) {
console.log('点击',params)
// 点击省区域,下钻
if(params.data.level === 'province') {
curProvince = {
name: params.name,
adcode: params.value
}
initMap('city');
return;
}
message.warning('已经是最后一层');
})
}
// 初始化地图
const initMap = (fileName) => {
// JSON文件(地图数据)路径
let dataURL = `GeoJSON/${fileName}.json`;
// 引入JSON文件
fetch(dataURL).then((res) => res.json()).then((geoJson) => {
chartDom.value.clear();
let registerGeoJSON = fileName === 'city' ? getCitys(geoJson) : geoJson;
// 注册地图名字(fileName)和数据(registerGeoJSON)
echarts.registerMap(fileName, registerGeoJSON);
let regions = dataFormat(registerGeoJSON);
console.log('regions',regions);
if(!regions) return;
let colorOptions = {
environment: '#ccc', // 环境背景颜色
borderColor: '#787c80', // 区域边界颜色
labelColor: '#000', // 区域名称颜色
hoverLabelColor: '#6c6f73' // 鼠标划入区域高亮颜色
}
let options = {
series: [
{
type: 'map3D',
map: fileName,// 注册的地图名字
shading: 'realistic',
environment: colorOptions.environment,
itemStyle: {
borderColor: colorOptions.borderColor,
borderWidth: 1
},
label: {
show: true,
formatter: '{b} ', // 加个空格,否则不会直接显示name
textStyle: {
color: colorOptions.labelColor
}
},
emphasis: { // 鼠标hover高亮时区域颜色
itemStyle: {
color: colorOptions.hoverLabelColor,
opacity: .8
}
},
viewControl: { // 视角距离主体的距离
distance: fileName == 'city' ? 200 : 100
},
instancing: true,
boxWidth: 200,
boxHeight: 1,
data: regions
}
]
}
options && chartDom.value.setOption(options);
})
}
// 返回echarts展示数据格式
const dataFormat = (geoJson) => {
return (geoJson.features || []).map((feature) => {
return {
name: feature.properties.name,
value: feature.properties.adcode,
level: feature.properties.level //自定义层级标识
};
});
}
// 获取当前省的市级数据
const getCitys = (geoJson) => {
let cityArr = geoJson.features.filter(feature => {
return feature.properties?.parent?.adcode === curProvince.adcode;
});
return {
features: cityArr
}
}
</script>
<style lang="less" scoped>
#echartsDom {
width: 100%;
height: 100%;
}
</style>
四、补充H5无法点击的Bug:
问题描述:
关于H5端无法触发点击事件的问题,在github上查阅了相关问题,发现是普遍存在的,源码上的缺陷。
解决方案:
github关于此问题的讨论https://github.com/apache/echarts/issues/9906
修改源码,将文件 node_modules\zrender\lib\dom\HandlerProxy.js 中的一行代码注释掉:
H5端即可实现正常点击: