最近项目里需要一个大屏可视化,要求在地图上展示城市间的数据流向。调研了一圈,发现 ECharts 的飞线图(Lines)效果简直不要太炫酷!
文章目录:
- 准备工作:项目搭建与依赖安装
- 引入 ECharts 和地图数据
- 编写 Vue 组件:HTML 结构
- 核心代码:ECharts 配置详解
- CSS 美化:让图表更精致
- 优化建议:提升用户体验
- 总结与展望
1. 准备工作:项目搭建与依赖安装
首先,确保你已经安装了 Node.js 和 npm (或 yarn)。 创建一个 Vue3 项目:
vue create echarts-flyline-demo
进入项目目录,安装 ECharts 和其他可能用到的依赖:
cd echarts-flyline-demo
npm install echarts --save
npm install @vueuse/core --save // (可选,用于响应式处理)
2. 引入 ECharts 和地图数据
为了方便管理 ECharts 实例,我们创建一个 useEcharts
hook, 放在 @/hooks/useEcharts.js
文件中:
// src/hooks/useEcharts.js
import * as echarts from 'echarts'
import { onMounted, onUnmounted, ref } from 'vue'
export { echarts }
export default function useEcharts(options) {
const container = ref(null)
let chart = null
onMounted(() => {
chart = echarts.init(container.value)
options && chart.setOption(options)
})
onUnmounted(() => {
chart && chart.dispose()
})
return {
container
}
}
接下来,我们需要中国地图的 JSON 数据。 你可以在 ECharts 官网或其他资源网站下载 china.json
, 然后放在 @/assets/map/china.json
目录。
重要提示: 地图数据一定要确保正确和完整,否则可能无法正常显示。
3. 编写 Vue 组件:HTML 结构
创建一个 Vue 组件,例如 FlylineChart.vue
,添加如下 HTML 结构:
<template>
<div class="container">
<div class="chart-container" ref="chartContainer"></div>
</div>
</template>
这里我们创建了一个容器 chart-container
,并通过 ref="chartContainer"
将其实例传递给 useEcharts
hook,以便 ECharts 在该容器中渲染图表。
4. 核心代码:ECharts 配置详解
现在是重头戏! 在 <script setup>
标签中,导入我们创建的 useEcharts
hook 和地图数据, 然后进行 ECharts 配置。
<script setup>
import useEcharts, { echarts } from '@/hooks/useEcharts'
import mapJson from '@/assets/map/china.json'
echarts.registerMap('china', mapJson)
const centerCity = [{
coord:[116.405285, 39.904989] // 北京
},{
coord:[117.190182, 39.125596] // 天津
},{
coord:[114.502461, 38.045474] // 石家庄
},{
coord:[113.429919, 23.334643] // 广州
}]
const linesData = [[{
coord:[116.405285, 39.904989]
},{
coord:[117.190182, 39.125596]
}],[{
coord:[117.190182, 39.125596]
},{
coord:[114.502461, 38.045474]
}],[{
coord:[116.405285, 39.904989]
},{
coord:[113.429919, 23.334643]
}]]
const { container: chartContainer } = useEcharts({
geo: {
map: 'china',
zoom: 1.3,
top: '30%',
left: '10%',
bottom: '10%',
},
series: [
{
type: 'lines',
coordinateSystem: 'geo',
effect: {
show: true,
symbolSize:5,
trailLength:0.1,
symbol:'arrow'
},
lineStyle:{
width:1,
opacity:1,
curveness:0.3
},
data: linesData.map(item => {
return {
coords:[item[0].coord,item[1].coord]
}
}),
},{
type:'effectScatter',
coordinateSystem:'geo',
data:centerCity.map(item => {
item.coord.push(1) // 添加一个数值,否则 effectScatter 不显示
return {
value:item.coord
}
})
}
],
})
</script>
代码解读:
echarts.registerMap('china', mapJson)
: 注册中国地图,确保 ECharts 能够识别。centerCity
: 定义中心城市的坐标数据, 模拟实际业务中的关键节点。linesData
: 定义飞线的数据,每个元素包含起点和终点的坐标。geo
配置:map: 'china'
:指定地图类型。zoom: 1.3
:地图缩放比例。top, left, bottom
:调整地图在容器中的位置。
series
配置:type: 'lines'
: 配置飞线图。coordinateSystem: 'geo'
:指定坐标系为地理坐标系。effect
:配置飞线特效。show: true
:显示特效。symbolSize
:特效符号大小。trailLength
:特效尾迹长度。symbol:'arrow'
:箭头
lineStyle
:配置线条样式。width
:线条宽度。opacity
:线条透明度。curveness
:线条弯曲度。
data
:飞线数据,将linesData
转换成 ECharts 要求的格式。
type: 'effectScatter'
: 配置涟漪特效散点图,用于标记中心城市。coordinateSystem: 'geo'
:指定坐标系为地理坐标系。data
:中心城市数据,将centerCity
转换成 ECharts 要求的格式。 注意,这里需要给坐标添加一个数值,否则effectScatter
不会显示。
5. CSS 美化:让图表更精致
添加一些 CSS 样式,让图表更美观:
<style scoped>
.chart-container {
height: 700px; /* 根据你的屏幕尺寸调整高度 */
}
</style>
6. 优化建议:提升用户体验
- 数据动态更新: 将
centerCity
和linesData
定义成响应式数据, 使用watch
监听数据变化, 并在数据变化时更新 ECharts 图表。 - 添加 Tooltip: 使用
tooltip
配置项,在鼠标悬停时显示更详细的数据信息。 - 交互事件: 监听 ECharts 的点击事件,实现城市之间的跳转或展示更多信息。
- 颜色自定义: 根据你的项目主题,自定义飞线和散点的颜色。
- 更复杂的效果: 使用 ECharts 提供的其他特性,例如热力图、散点图等,结合飞线图实现更复杂的可视化效果。
7. 总结与展望
本文详细介绍了如何在 Vue3 项目中使用 ECharts 实现一个酷炫的中国地图飞线图。 通过学习本文,你可以掌握 ECharts 的基本配置和使用方法,并将其应用到你的项目中。
希望本文能帮助到你,如果觉得有用,请点赞、收藏、评论! 欢迎各位大佬在评论区分享你的经验和技巧,一起学习进步!
完整代码:
<template>
<div class="container">
<div class="chart-container" ref="chartContainer"></div>
</div>
</template>
<script setup>
import useEcharts, { echarts } from '@/hooks/useEcharts'
import mapJson from '@/assets/map/china.json'
echarts.registerMap('china', mapJson)
const centerCity = [{
coord:[116.405285, 39.904989]
},{
coord:[117.190182, 39.125596]
},{
coord:[114.502461, 38.045474]
},{
coord:[113.429919, 23.334643]
}]
const linesData = [[{
coord:[116.405285, 39.904989]
},{
coord:[117.190182, 39.125596]
}],[{
coord:[117.190182, 39.125596]
},{
coord:[114.502461, 38.045474]
}],[{
coord:[116.405285, 39.904989]
},{
coord:[113.429919, 23.334643]
}]]
const { container: chartContainer } = useEcharts({
geo: {
map: 'china',
zoom: 1.3,
top: '30%',
left: '10%',
bottom: '10%',
},
series: [
{
type: 'lines',
coordinateSystem: 'geo',
effect: {
show: true,
symbolSize:5,
trailLength:0.1,
symbol:'arrow'
},
lineStyle:{
width:1,
opacity:1,
curveness:0.3
},
data: linesData.map(item => {
return {
coords:[item[0].coord,item[1].coord]
}
}),
},{
type:'effectScatter',
coordinateSystem:'geo',
data:centerCity.map(item => {
item.coord.push(1)
return {
value:item.coord
}
})
}
],
})
</script>
<style scoped>
.chart-container {
height: 700px;
}
</style>