vue 数据大屏项目开发中,有时候会需要实现3d地图下钻效果,这里我们使用echarts-gl来实现3d地图。今天的3d地图是从中国->省->市三级下钻实例。除了使用echarts实现3d地图下钻,我们还可以使用threejs来实现下钻效果,threejs 3d地图实现省份下钻实例.
渲染流程
首先渲染中国地图,点击任意省份切换到省级地图,点击省级下的任意市级切换到市级地图,右上角增加了一个返回按钮,点击后可以切换到上一级地图。
3d中国地图
3d省级地图
3d市级地图
首先要适配页面
首先要监听页面大小变化,当页面变化时,从新绘制地图
mounted() {
var that = this;
const viewElem = document.body;
// 监听窗口变化,重绘echarts
const resizeObserver = new ResizeObserver(() => {
setTimeout(() => {
that.drawEcharts();
}, 300)
});
resizeObserver.observe(viewElem);
},
加载地图数据
import dataMap from '../data/100000.json'
import data410000 from '../data/410000.json'
import data440000 from '../data/440000.json'
import data150000 from '../data/150000.json'
import data230000 from '../data/230000.json'
import data650000 from '../data/650000.json'
import data420000 from '../data/420000.json'
import data210000 from '../data/210000.json'
import data370000 from '../data/370000.json'
import data610000 from '../data/610000.json'
import data310000 from '../data/310000.json'
import data520000 from '../data/520000.json'
import data500000 from '../data/500000.json'
import data540000 from '../data/540000.json'
import data340000 from '../data/340000.json'
import data350000 from '../data/350000.json'
import data430000 from '../data/430000.json'
import data460000 from '../data/460000.json'
import data320000 from '../data/320000.json'
import data630000 from '../data/630000.json'
import data450000 from '../data/450000.json'
import data640000 from '../data/640000.json'
import data330000 from '../data/330000.json'
import data130000 from '../data/130000.json'
import data620000 from '../data/620000.json'
import data510000 from '../data/510000.json'
import data120000 from '../data/120000.json'
import data110000 from '../data/110000.json'
import data220000 from '../data/220000.json'
import data530000 from '../data/530000.json'
import data360000 from '../data/360000.json'
import data140000 from '../data/140000.json'
我们的地图数据存储到listCode中,每选中一级地图,我们就将数据加入到listCode中,listCode数组最后一级数据就是当前展示的地图。我们想返回上一级,就移出数组中最后一级的地图数据即可。
data() {
return {
listCode: [
{
code: 100000,
name: '中国',
data: dataMap
}
],
myChart: null,
areaName: '',
list: [
{
"name": "河南省",
"code": "410000",
"data": data410000
},
{
"name": "广东省",
"code": "440000",
"data": data440000
},
{
"name": "内蒙古自治区",
"code": "150000",
"data": data150000
},
{
"name": "黑龙江省",
"code": "230000",
"data": data230000
},
{
"name": "新疆维吾尔自治区",
"code": "650000",
"data": data650000
},
{
"name": "湖北省",
"code": "420000",
"data": data420000
},
{
"name": "辽宁省",
"code": "210000",
"data": data210000
},
{
"name": "山东省",
"code": "370000",
"data": data370000
},
{
"name": "陕西省",
"code": "610000",
"data": data610000
},
{
"name": "上海市",
"code": "310000",
"data": data310000
},
{
"name": "贵州省",
"code": "520000",
"data": data520000
},
{
"name": "重庆市",
"code": "500000",
"data": data500000
},
{
"name": "西藏自治区",
"code": "540000",
"data": data540000
},
{
"name": "安徽省",
"code": "340000",
"data": data340000
},
{
"name": "福建省",
"code": "350000",
"data": data350000
},
{
"name": "湖南省",
"code": "430000",
"data": data430000
},
{
"name": "海南省",
"code": "460000",
"data": data460000
},
{
"name": "江苏省",
"code": "320000",
"data": data320000
},
{
"name": "青海省",
"code": "630000",
"data": data630000
},
{
"name": "广西壮族自治区",
"code": "450000",
"data": data450000
},
{
"name": "宁夏回族自治区",
"code": "640000",
"data": data640000
},
{
"name": "浙江省",
"code": "330000",
"data": data330000
},
{
"name": "河北省",
"code": "130000",
"data": data130000
},
{
"name": "甘肃省",
"code": "620000",
"data": data620000
},
{
"name": "四川省",
"code": "510000",
"data": data510000
},
{
"name": "天津市",
"code": "120000",
"data": data120000
},
{
"name": "北京市",
"code": "110000",
"data": data110000
},
{
"name": "吉林省",
"code": "220000",
"data": data220000
},
{
"name": "云南省",
"code": "530000",
"data": data530000
},
{
"name": "江西省",
"code": "360000",
"data": data360000
},
{
"name": "山西省",
"code": "140000",
"data": data140000
}
]
}
},
监听数据变化
监听listCode的数据变化,每次数据变化后,就会将数据返回给父组件,让父组件知道当前渲染的地图,父组件可以根据当前渲染的地图做一些相关操作。
返回处理
goback() {
var that = this;
that.listCode.splice(that.listCode.length - 1, 1)
console.log(that.listCode)
that.drawEcharts()
},
每次返回我们都需要删除数组中的最后一条数据,然后重新渲染地图。
然后使用属性计算获取当前应该显示的地图数据
computed: {
mapData: function () {
return this.listCode[this.listCode.length - 1].data
}
},
市级地图数据处理
因为当前地图数据要下钻到市,目前没有准备专门的市级数据,所以我们从省级地图中取出对应的市级数据单独显示。
getMapData(datas) {
var that = this;
// 如果有addressName则只显示addressName信息
var typeData = {
name: '',
code: '',
data: {}
}
var data = {
"type": "FeatureCollection",
"features": []
}
datas.features.forEach((type) => {
if (type.properties.name == that.areaName) {
console.log('有数据')
data.features.push(type)
typeData.name = type.properties.name
typeData.code = type.properties.code
typeData.data = data
}
});
return typeData
},
点击下钻数据处理
当我们点击下钻的时候,我们需要将数据插入到列表中,为了避免重复点击导致数据重复,我们在加入数据的时候需要判断当前列表中是否包含了此数据,如果包含了,则不加入数据。
getCode() {
var that = this;
// 当数据小于2级时
console.log(that.listCode)
if (that.listCode.length <= 1) {
that.list.forEach((type) => {
if (type.name == that.areaName) {
var isHas = 0
that.listCode.forEach((type2) => {
if (type2.name == that.areaName) {
isHas = 1
}
});
if (!isHas) {
that.listCode.push(type)
}
}
});
} else {
that.listCode.push(this.getMapData(that.listCode[that.listCode.length - 1].data))
}
// 当数据大于2级时,则是地图的子地图
that.drawEcharts()
},
渲染地图
渲染地图,监听点击事件,渲染前,如果有地图则先销毁一下。避免内存泄露导致地图崩溃,或者内存占用过多,导致地图渲染卡顿。
drawEcharts() {
var that = this;
if(this.myChart){
this.myChart.dispose()
}
var chartDom = that.$refs.centerMap;
this.$emit('getData', this.listCode[this.listCode.length - 1].code)
var myChart = this.myChart = echarts.init(chartDom);
myChart.clear()
myChart.resize()
var nameMap = '地图数据';
// 图标数据
echarts.registerMap(nameMap, this.mapData);
var optionMap = {
series: [{
map: nameMap,
type: "map3D",
roam: true,
itemStyle: {
color: '#6089d1',
borderWidth: 0.8,
borderColor: '#a9dbff'
},
emphasis: {
itemStyle: {
color: '#ddb84c'
},
},
label: {
show: true,
color: '#fff', //地图初始化区域字体颜色
fontSize: 14,
opacity: 1,
},
}]
};
myChart.clear()
myChart.resize()
myChart.setOption(optionMap);
myChart.on('click', params => {
console.log('params------', params)
console.log(that.areaName)
that.areaName = params.name
that.getCode()
})
}
更多echarts 3d地图
更新
2023年10月14日
增加vue2版本
vue echarts-gl 3d地图从中国下钻到市级完整实例代码下载
当前完整演示实例代码下载
项目包含两个版本一个vue2版本一个vue3版本可以按需下载