vue 数据大屏项目开发中,需要实现3d地图下钻效果,这里我们使用echarts-gl来实现3d地图。
渲染地图首先要安装依赖
使用echarts实现3d地图,我们需要安装依赖,echarts
和echarts-gl
的版本是一一对应的,版本差别很大可能会报错,这里我们使用的是echarts 5.2.0
和 echarts-gl 2.0.8
"echarts": "^5.2.0",
"echarts-gl": "^2.0.8",
引入地图数据
要实现下钻实例,我们需要先把对应的地图数据加载出来。
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'
地图渲染
接下来我们完成地图的初步渲染。
点击事件监听
通过myChart.on
方法我们可以获取到点击事件信息,如果你的click监听获取不到数据的话,可以通过这里解决vue echarts-gl 3d 点击地图无法获取监听事件.
myChart.on('click', params => {
console.log('params------', params)
console.log(that.areaName)
that.areaName = params.name
that.getCode()
})
销毁事件
当3d地图执行多次返回下钻后,就会非常卡顿,甚至卡死,为了避免这种情况的出现,我们需要每次重绘地图前先销毁当前的地图。我们通过dispose()
来实现。
if(this.myChart){
this.myChart.dispose()
}
实例代码
<template>
<div class="item1">
<div class="back" v-if="listCode.length>0" @click="goback">返回</div>
<div class="centerMap" ref="centerMap">
</div>
</div>
</template>
<script>
import * as echarts from "echarts"
import 'echarts-gl'
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'
export default {
name: "item1",
data() {
return {
listCode: [],
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
}
]
}
},
components: {},
watch: {},
computed: {
mapData: function () {
var data = []
if (this.listCode.length > 0) {
data = this.listCode[this.listCode.length - 1].data
} else {
data = dataMap
}
return data
}
},
mounted() {
var that = this;
const viewElem = document.body;
// 监听窗口变化,重绘echarts
const resizeObserver = new ResizeObserver(() => {
setTimeout(() => {
that.drawEcharts();
}, 300)
});
resizeObserver.observe(viewElem);
},
methods: {
goback() {
var that = this;
that.listCode.splice(that.listCode.length - 1, 1)
console.log(that.listCode)
that.drawEcharts()
},
getCode() {
var that = this;
// 如果code不存在,则说明
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)
}
}
});
console.log(that.listCode)
that.drawEcharts()
},
drawEcharts() {
var that = this;
if (this.myChart) {
this.myChart.dispose()
}
var chartDom = that.$refs.centerMap;
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()
})
}
},
}
</script>
<style lang="scss" scoped>
.item1 {
position: relative;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
flex-wrap: nowrap;
flex-direction: row;
align-content: flex-start;
}
.map {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
flex-wrap: nowrap;
flex-direction: row;
align-content: flex-start;
margin: 0 auto;
position: absolute;
z-index: 0;
img {
height: 100%;
max-width: 100%;
max-height: 100%;
}
}
.centerMap {
width: 100%;
height: 100%;
position: relative;
z-index: 1;
top: 0;
}
.back {
position: absolute;
right: 20px;
top: 20px;
color: red;
font-size: 14px;
cursor: pointer;
z-index: 100;
}
</style>
更多echarts 3d地图
更新日志
2023年09月10日
移除node-sass组件
vue echarts-gl 3d地图实现下钻完整实例代码下载
当前完整演示实例代码下载
项目基于Vue3 vite js实现