前言
在現代數據可視化領域,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. 數據處理
我們需要準備兩類數據:
城市點位數據?- 用于在地圖上顯示城市位置
飛線數據?- 用于顯示從起點到各城市的連線
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>
效果優化技巧
動畫效果:通過調整?
effect.period
?可以改變飛線動畫速度視覺層次:使用?
zlevel
?控制不同圖層的疊加順序光照效果:調整?
light
?配置可以改變地圖的明暗效果交互體驗:配置?
viewControl
?可以控制地圖的旋轉、縮放等交互行為
常見問題解決
地圖不顯示:
確保正確注冊了地圖 JSON 數據
檢查容器是否有固定寬高
飛線不顯示:
檢查坐標數據格式是否正確
確保 lines3D 系列被正確添加到 series 中
性能問題:
數據量過大時考慮簡化或聚合數據
使用?
silent: true
?減少不必要的交互檢測
總結
通過 ECharts GL 實現 3D 地圖飛線效果,可以為地理空間數據提供更加直觀的展示方式。本文詳細介紹了從數據準備到最終實現的完整流程,以及各種配置項的用途和優化技巧。這種可視化方式特別適合展示城市間的關聯關系、物流路線、人口遷移等場景。
希望這篇技術解析能幫助你在項目中實現類似的效果。如果有任何問題,歡迎在評論區討論。