一、项目背景
本项目基于 ECharts 和 ECharts-GL 实现了一个3D中国地图的可视化页面,支持地图区域高亮、涟漪散点、动态飞线等效果,适用于地理数据展示、流向分析等场景。
二、效果图
- 3D中国地图,带有地形贴图和立体边界。
- 主要城市以涟漪散点高亮显示。
- 城市间流向以动态飞线展示,直观表现数据流动。

三、实现过程
1. 技术选型
- ECharts:强大的数据可视化库,支持丰富的图表类型和地理可视化。
- ECharts-GL:ECharts 的 3D 扩展,支持三维地图、三维柱状图等高级可视化效果。
- Vue.js:前端主流框架,负责页面结构和生命周期管理。
2. 地图数据准备
使用了 china.json 作为中国地图的 GeoJSON 数据源,放置于 src/utils/china.json。 贴图采用了 map.svg,增强地图的地形感和美观度。 点击这里获取中国地图json
3. 主要实现步骤
(1)地图注册与初始化
在 mounted 钩子中,注册中国地图并初始化 ECharts 实例:
javascript
import * as echarts from 'echarts'
import "echarts-gl";
import geoJson from '@/utils/china.json'
mounted() {
//点击散点城市坐标位置
const chinaData = [
{ name: '北京市', value: [116.405285, 39.904989] },
{ name: '成都', value: [104.0657, 30.6598] },
{ name: '上海', value: [121.4737, 31.2304] },
{ name: '拉萨', value: [91.11, 29.97] }
];
const myChart = echarts.init(document.getElementById('mapContainer'));
this.initChart('china', chinaData, myChart)
}
(2)3D地图与贴图
使用 geo3D 配置项实现三维地图。 通过 colorMaterial.detailTexture 属性,将2D地图渲染为纹理贴图,贴在3D地图表面,提升真实感。
因3d地图无法实现散点效果,故此采用3d和2d贴合实现,散点效果
javascript
geo3D: {
map: 'china',
regionHeight: 2.1,
shading: 'color',
colorMaterial: {
detailTexture: mapBg, // 纹理贴图
textureTiling: 1
},
// ... 视角、边界等配置
}
(3)下层地图与分层效果
通过 series 添加 map3D 类型,设置不同的 regionHeight,实现地图分层立体感。
(4)2D地图贴图生成
LoadMapping 方法生成2D地图配置,主要用于生成纹理贴图。 贴图采用 SVG 图像,提升地图的美观度和辨识度。
javascript
itemStyle: {
areaColor: {
type: 'pattern',
image: require('../assets/images/map.svg'),
repeat: 'no-repeat',
},
}
(5)涟漪散点与飞线
使用 effectScatter 实现城市位置的涟漪散点动画。 使用 lines 实现城市之间的动态飞线,模拟流向效果。
javascript
{
type: `effectScatter`,
coordinateSystem: `geo`,
rippleEffect: { period: 5, scale: 4, brushType: 'fill' },
itemStyle: { normal: { color: 'yellow', shadowBlur: 10, shadowColor: '#333' } },
symbolSize: 16,
data: [ ... ]
},
{
type: 'lines',
effect: { show: true, period: 4, trailLength: 0.4, symbol: 'arrow', symbolSize: 7 },
lineStyle: { normal: { color:'#1DE9B6', width: 3, opacity: 0.6, curveness: .3 } },
data: [ ... ]
}
(6)完整代码
html
<template>
<div>
<div style="width: 100%; height: 100%;">
<div class="contanier"></div>
<div ref="mapContainer" id="mapContainer" style="width: 100%; height: 100vh;"></div>
</div>
</div>
</template>
<script>
import * as echarts from 'echarts'
import "echarts-gl";
import geoJson from '@/utils/china.json'
export default {
data() {
},
mounted() {
const chinaName = 'china';
const chinaData = [{ name: '北京市', value: [116.405285, 39.904989] },{ name: '成都', value: [104.0657, 30.6598] },{ name: '上海', value: [121.4737, 31.2304] },{ name: '拉萨', value: [91.11, 29.97] }];
const myChart = echarts.init(document.getElementById('mapContainer'));
this.initChart('china', chinaData, myChart)
},
methods: {
initChart(name, data, myChart) {
// const myChart = echarts.init(this.$refs.mapContainer);
echarts.registerMap("china", geoJson); // 注册地图
const canvas = document.createElement(`canvas`);
var mapBg = echarts.init(canvas, null, {
width: 1024,
height: 1024,
});
const chartOption = this.LoadMapping(name);
mapBg.setOption(chartOption);
let option = {
backgroundColor: '#000000',
// 上层
geo3D: {
map: 'china',
regionHeight: 2.1, //地图厚度
label: {
show: false,
color: '#fff',
},
itemStyle: {
borderWidth: 1, //分界线宽度
borderColor: '#fff', //分界线颜色
},
emphasis: {
label: {
show: false,
},
},
shading: 'color', // lambert color realistic 只有为color时,可以设置colorMaterial,实现将平面地图贴在3D地图上
colorMaterial: {
detailTexture: mapBg, // 纹理贴图
textureTiling: 1 // 纹理平铺,1是拉伸,数字表示纹理平铺次数
},
viewControl: {
distance: 90, // 地图视角 控制初始大小
beta: 0, //旋转视角
alpha: 90, //视角
center: [0, 0, 0],
},
},
series: [
// 下层
{
type: "map3D",
map: "china",
regionHeight: 2, //地图厚度
label: {
show: false,
color: '#ff000000',
},
itemStyle: {
normal: {
color: "rgba(52, 299, 218, 1)",
}
},
viewControl: {
distance: 90, // 地图视角 控制初始大小
beta: 0, //旋转视角
alpha: 90, //视角
center: [0, 0, 0],
},
},
],
}
myChart.setOption(option, true);
},
// 2D地图
LoadMapping(name) {
var chartOption = {
geo: {
show: true,
map: name,
top: '0',
width: 1024,
label: {
position: 'top',
distance: 4,
normal: {
show: true,
textStyle: {
color: '#fff'
}
},
},
itemStyle: {
areaColor: {
type: 'pattern',
image: require('../assets/images/map.svg'), // 贴图(山形地貌图)
repeat: 'no-repeat',
},
},
},
series: [
{
type: `effectScatter`, // 散点, scatter不能实现涟漪效果
coordinateSystem: `geo`,
showEffectOn: 'render',
zlevel: 5,
rippleEffect: {
period: 5,
scale: 4,
brushType: 'fill'
},
hoverAnimation: true,
itemStyle: {
normal: {
color: 'yellow',
shadowBlur: 10,
shadowColor: '#333'
}
},
symbolSize: 16,
data: [{ name: '北京市', value: [116.405285, 39.904989] },
{ name: '成都', value: [104.0657, 30.6598] },
{ name: '上海', value: [121.4737, 31.2304] },
{ name: '拉萨', value: [91.11, 29.97] },
]
},
{
type: 'lines',
zlevel: 6,
effect: {
show: true,
period: 4, //箭头指向速度,值越小速度越快
trailLength: 0.4, //特效尾迹长度[0,1]值越大,尾迹越长重
symbol: 'arrow', //箭头图标
symbolSize: 7, //图标大小
},
lineStyle: {
normal: {
color:'#1DE9B6', //尾迹线条颜色
width: 3,
opacity: 0.6,
// opacity: 0.2, //尾迹线条透明度
curveness: .3 //尾迹线条曲直度
}
},
data: [
{coords: [[104.0657, 30.6598],[116.405285, 39.904989]]}
, {coords: [[121.4737, 31.2304],[116.405285, 39.904989]]}
, {coords: [[91.11, 29.97],[116.405285, 39.904989]]}
]
}
]
}
return chartOption;
}
}
}
</script>
六、总结
本项目通过 ECharts-GL 实现了高质量的3D中国地图可视化,集成了贴图、分层、动画等多种高级效果,适合用于地理数据分析、流向展示等多种场景。开发过程中,合理利用 ECharts 的配置项和资源管理,可以高效实现复杂的可视化需求。