echarts 绘制3D中国地图
一、项目背景
本项目基于 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 实例:
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贴合实现,散点效果
geo3D: {map: 'china',regionHeight: 2.1,shading: 'color',colorMaterial: {detailTexture: mapBg, // 纹理贴图textureTiling: 1},// ... 视角、边界等配置
}
(3)下层地图与分层效果
通过 series 添加 map3D 类型,设置不同的 regionHeight,实现地图分层立体感。
(4)2D地图贴图生成
LoadMapping 方法生成2D地图配置,主要用于生成纹理贴图。
贴图采用 SVG 图像,提升地图的美观度和辨识度。
itemStyle: {areaColor: {type: 'pattern',image: require('../assets/images/map.svg'),repeat: 'no-repeat',},
}
(5)涟漪散点与飞线
使用 effectScatter 实现城市位置的涟漪散点动画。
使用 lines 实现城市之间的动态飞线,模拟流向效果。
{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)完整代码
<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 的配置项和资源管理,可以高效实现复杂的可视化需求。