当前位置: 首页 > news >正文

使用 ECharts GL 实现 3D 中国地图点位飞线效果

前言

在现代数据可视化领域,3D 地图飞线效果是一种非常吸引人的展示方式,特别适合展示地理空间关系和数据流动。本文将详细解析如何使用 ECharts GL 在 Vue 项目中实现一个 3D 中国地图飞线效果。

技术栈

  • Vue.js 2.x/3.x

  • ECharts 5.x

  • ECharts GL 2.x

核心实现步骤

1. 准备工作

首先需要安装必要的依赖:

npm install echarts echarts-gl --save

2. 基础地图配置

import * as echarts from 'echarts'
import "echarts-gl";
import chinaJson from '@/utils/chinaOutline.json'export default {mounted() {this.initChart()},methods: {initChart() {const dom = this.$refs.chartRef;this.myChart = echarts.init(dom);echarts.registerMap('china', chinaJson);// ...其他配置}}
}

3. 数据处理

我们需要准备两类数据:

  1. 城市点位数据 - 用于在地图上显示城市位置

  2. 飞线数据 - 用于显示从起点到各城市的连线

const FROMCITY = [113.28064, 23.125177]  // 起点坐标(深圳)
const FROMCITYCOORD = [113.28064, 23.125177]// 处理飞线数据
const linesData = this.cityList.map(city => ({fromName: FROMCITY,toName: city.city,coords: [[FROMCITYCOORD[0], FROMCITYCOORD[1], 1], [city.provinceCapitalX, city.provinceCapitalY, 1]],
}));// 处理散点数据
const scatterData = this.cityList.map(city => ({name: city.city.replace('市', ''),value: [city.provinceCapitalX, city.provinceCapitalY, 1],
}));

4. 3D 地图核心配置

geo3D: {map: 'china',regionHeight: 8,  // 区域高度itemStyle: {color: 'RGBA(153, 249, 235, 1)',  // 地图基础颜色borderWidth: 1.5},viewControl: {distance: 110,  // 观察距离alpha: 60,      // 上下旋转角度beta: 0         // 左右旋转角度},// ...其他配置
}

5. 飞线系列配置

{type: 'lines3D',effect: {show: true,period: 4,            // 动画周期trailWidth: 4,        // 尾迹宽度symbol: 'arrow',      // 箭头符号color: 'rgba(255,255,255, 1)'},lineStyle: {width: 1.5,color: '#1AD9FF',     // 飞线颜色opacity: 0.8},data: linesData         // 飞线数据
}

6. 城市点位配置

{type: 'scatter3D',symbol: 'circle',symbolSize: 14,label: {show: true,formatter: '{b}',     // 显示城市名称color: '#FFF'},itemStyle: {color: '#FFA601'      // 点颜色},data: scatterData       // 散点数据
}

完整代码解析

setChartInit() {const dom = this.$refs.chartRef;this.myChart = this.myChart || echarts.init(dom);// 注册地图echarts.registerMap('china', chinaJson);// 准备数据const linesData = this.cityList.map(city => ({fromName: FROMCITY,toName: city.city,coords: [[FROMCITYCOORD[0], FROMCITYCOORD[1], 1], [city.provinceCapitalX, city.provinceCapitalY, 1]],}));const scatterData = this.cityList.map(city => ({name: city.city.replace('市', ''),value: [city.provinceCapitalX, city.provinceCapitalY, 1],}));// 配置项const option = {// 3D地图配置geo3D: {map: 'china',regionHeight: 8,// ...其他geo3D配置},series: [// 飞线系列{type: 'lines3D',// ...飞线配置data: linesData},// 点位系列{type: 'scatter3D',// ...点位配置data: scatterData}]};this.myChart.setOption(option);
}

完整代码

<template><div class="chartRef" ref="chartRef" style="height: 100%;width: 100%" />
</template>
<script>import * as echarts from 'echarts'
import '@/utils/chinaMap'
import "echarts-gl";
import chinaJson from '@/utils/chinaOutline.json'const FROMCITY = [113.28064, 23.125177]
const FROMCITYCOORD = [113.28064, 23.125177]export default {name: 'Demo',data() {return {cityList:[{"id": 0,"city": "绍兴市","provinceCapitalX": "120.15358","provinceCapitalY": "30.287458","num": 200},{"id": 1,"city": "北京市","provinceCapitalX": "116.405289","provinceCapitalY": "39.904987","num": 200},{"id": 2,"city": "嘉兴市","provinceCapitalX": "120.15358","provinceCapitalY": "30.287458","num": 200},{"id": 3,"city": "锦州市","provinceCapitalX": "118.76741","provinceCapitalY": "41.796768","num": 200},{"id": 4,"city": "临沂市","provinceCapitalX": "120.15358","provinceCapitalY": "30.287458","num": 200},{"id": 5,"city": "深圳市","provinceCapitalX": "113.28064","provinceCapitalY": "23.125177","num": 200}
],}},mounted() {this.getData()},watch: {},methods: {// 地图组件初始加载setChartInit() {const dom = this.$refs.chartRef;this.myChart = this.myChart || echarts.init(dom);echarts.registerMap('china', chinaJson);const linesData = this.cityList.map(city => ({fromName: FROMCITY,toName: city.city,coords: [[FROMCITYCOORD[0], FROMCITYCOORD[1], 1], [city.provinceCapitalX, city.provinceCapitalY, 1]],}));const scatterData = this.cityList.map(city => ({name: city.city.replace('市', ''),value: [city.provinceCapitalX, city.provinceCapitalY, 1],}));const option = {tooltip: {trigger: 'axis',axisPointer: {type: 'shadow'}},backgroundColor: 'transparent',geo3D: {zlevel: 1,type: 'geo3D',coordinateSystem: 'geo3D',map: 'china',regionHeight: 8,roam: false,silent: false, select: {disabled: false},itemStyle: {borderColor: 'RGBA(37, 182, 144, 0)',color: 'RGBA(153, 249, 235, 1)',borderWidth: 1.5},shading: "realistic",realisticMaterial: {detailTexture: "./bg.png",textureTiling: 1,blendMode: 'Additive', // 可选值:Additive / Subtractive / Multiply 等},light: {main: {intensity: 1.2,shadow: true,shadowQuality: 'high'},ambient: {intensity: 0.3}},viewControl: {distance: 110,alpha: 60,beta: 0,autoRotate: false,rotateSensitivity: 1,zoomSensitivity: 1,panSensitivity: 1},emphasis: {label: {show: true,color: 'RGBA(255, 255, 255, 1)',fontSize: 14,},itemStyle: {color: 'RGBA(255, 255, 255, 1)',borderWidth: 4,borderColor: "RGBA(255,255,255, 1)",regionHeight: 25,opacity: 1,shadowColor: 'RGBA(153, 249, 235, 1)'}},},series: [// 飞线系列{type: 'lines3D',coordinateSystem: 'geo3D',zlevel: 2,silent: true,effect: {show: true,period: 4,trailWidth: 4,trailLength: 0.4,symbol: 'arrow',symbolSize: 16,color: 'rgba(255,255,255, 1)'},lineStyle: {width: 1.5,color: '#1AD9FF',opacity: 0.8},data: linesData},// 点位系列{type: 'scatter3D',coordinateSystem: 'geo3D',zlevel: 3,symbol: 'circle',symbolSize: 14,silent: false,label: {show: true,position: 'right',formatter: '{b}',textStyle: {color: '#FFF',fontSize: 14}},itemStyle: {color: '#FFA601'},emphasis: {label: {show: false},itemStyle: {color: '#1AD9FF'}},data: scatterData}]}this.myChart.setOption(option);}}
}
</script><style scoped lang="scss"></style>

效果优化技巧

  1. 动画效果:通过调整 effect.period 可以改变飞线动画速度

  2. 视觉层次:使用 zlevel 控制不同图层的叠加顺序

  3. 光照效果:调整 light 配置可以改变地图的明暗效果

  4. 交互体验:配置 viewControl 可以控制地图的旋转、缩放等交互行为

常见问题解决

  1. 地图不显示

    • 确保正确注册了地图 JSON 数据

    • 检查容器是否有固定宽高

  2. 飞线不显示

    • 检查坐标数据格式是否正确

    • 确保 lines3D 系列被正确添加到 series 中

  3. 性能问题

    • 数据量过大时考虑简化或聚合数据

    • 使用 silent: true 减少不必要的交互检测

总结

通过 ECharts GL 实现 3D 地图飞线效果,可以为地理空间数据提供更加直观的展示方式。本文详细介绍了从数据准备到最终实现的完整流程,以及各种配置项的用途和优化技巧。这种可视化方式特别适合展示城市间的关联关系、物流路线、人口迁移等场景。

希望这篇技术解析能帮助你在项目中实现类似的效果。如果有任何问题,欢迎在评论区讨论。

http://www.dtcms.com/a/320985.html

相关文章:

  • GoLand 项目从 0 到 1:第六天 —— 权限接口开发与问题攻坚
  • 笔试——Day32
  • pycharm常见环境配置和快捷键
  • 微软XBOX游戏部门大裁员
  • vue项目常见BUG和优化注意事项
  • HTTP 请求返回状态码和具体含义?200、400、403、404、502、503、504等
  • OpenBMC中libgpio架构与驱动交互全解析:从硬件映射到应用控制
  • 智能厨具机器人的革命性升级:Deepoc具身模型外拓板技术解析
  • 【Rust】多级目录模块化集成测试——以Cucumber为例
  • 服务器登上去,显示 failed to send WATCHDOG 重启有效吗?
  • 当服务器多了时,如何管理?
  • 机柜内部除了服务器还有哪些组件?
  • 防火墙概述
  • 手动开发一个TCP服务器调试工具(四):构建完整的UI与功能联合的TCP服务器应用
  • 脚本统计MongoDB集合结构信息
  • 从0开始的中后台管理系统-5(userList动态展示以及上传图片和弹出创建用户表单)
  • 【MongoDB学习笔记1】MongoDB的常用命令介绍-数据库操作、集合操作、文档操作、文档分页查询、高级查询
  • 操作系统: 线程(Thread)
  • Lazada东南亚矩阵营销破局:指纹手机如何以“批量智控+数据中枢”重构运营生态
  • Android 之 OOM的产生和解决办法
  • Android 之 ANR问题的全面解析与优化方案
  • 综合项目记录:自动化备份全网服务器数据平台
  • 日本站群服务器与普通日本服务器对比
  • 深入解析C++流运算符(>>和<<)重载:为何必须使用全局函数与友元机制
  • [论文阅读] 人工智能 + 软件工程 | LLM协作新突破:用多智能体强化学习实现高效协同——解析MAGRPO算法
  • 在发布应用程序内测时如何选择合适的分发上架方式?
  • Vite 深度解析:现代前端开发引擎
  • 瑞利杂波背景下不同环境的虚警概率与目标检测概率仿真
  • C# 异步编程(GUI程序中的异步操作)
  • 日常开发-5,工具使用。datagrip mysql 写查询语句 数据库表名和字段 无法提示