react+echarts实现地图飞线图
参考
1.datav 大屏特效使用 https://blog.csdn.net/qq_53479087/article/details/129411685
2.map china not exists. the geojson of the map must be provided. https://blog.csdn.net/qq_45043813/article/details/136999076
3.ECharts中Map(地图)样式配置、渐变色生成 https://cloud.tencent.com/developer/article/2402983
4.第三方示例平台:https://www.makeapie.cn/echarts
5.ehcarts配置项:https://echarts.apache.org/zh/option.html#title
效果

有个问题:未设置飞线的接收点也会有飞线效果,比如新疆,后面看看怎么解决。
1.安装echarts和echarts-for-react
pnpm add echarts echarts-for-react
我的版本是:
"echarts": "^5.6.0"
"echarts-for-react": "^3.0.2"
2.地图组件
import { useEffect, useRef, useState } from 'react'
import * as echarts from 'echarts'
import ReactECharts from 'echarts-for-react'
import chinaJson from './china.json' // 直接导入 GeoJSON
export default function MapFlyLine() {
const chartRef = useRef(null)
const [echartsOption, setEchartsOption] = useState()
// 接收点颜色
const centerColor = '#FABD45'
let centerCitys: any[] = []
let aroundCitys: any[] = []
let linesArr: any[] = []
const result = [
{
name: '总部-北京',
addressX: '116.4',
addressY: '39.9',
provinceName: '北京市',
childVOS: [
{
name: '分部-上海市',
addressX: '121.47',
addressY: '31.23',
showLine: true,
},
{
name: '分部-新疆',
addressX: '87.617733',
addressY: '43.792818',
showLine: false,
},
{
name: '分部-青海',
addressX: '101.778916',
addressY: '36.623178',
showLine: true,
},
{
name: '分部-四川',
addressX: '104.065735',
addressY: '30.659462',
showLine: true,
},
{
name: '分部-湖南',
addressX: '112.982279',
addressY: '28.19409',
showLine: true,
},
{
name: '分部-西藏',
addressX: '91.132212',
addressY: '29.660361',
showLine: false,
},
{
name: '分部-广西',
addressX: '108.320004',
addressY: '22.82402',
showLine: false,
},
],
},
]
result.forEach((center, index) => {
// 总部
centerCitys.push({
name: center.name,
value: [center.addressX, center.addressY],
provinceName: center.provinceName,
})
center.childVOS.forEach(child => {
// 分部
aroundCitys.push({
name: child.name,
value: [child.addressX, child.addressY],
itemStyle: {
color: centerColor,
},
})
// 飞线
linesArr.push({
name: `${child.name}-${center.name}`,
coords: [
[center.addressX, center.addressY],
[child.addressX, child.addressY],
],
lineStyle: {
normal: {
width: 2,
curveness: 0, // 边的曲度,支持从 0 到 1 的值,值越大曲度越大
color: {
type: 'linear', // 线性渐变
x: 1,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: 'rgba(250, 189, 69, 1)', // 起始颜色
},
{
offset: 1,
color: ' rgba(250, 189, 69, 0)', // 终止颜色
},
],
},
opacity: child.showLine ? 1 : 0,
},
},
})
})
})
const regions = chinaJson.features.map(item => {
const { name } = item.properties
return {
name: name,
itemStyle: {
normal: {
shadowColor: 'rgba(133, 26, 10, 1)', // 阴影颜色
shadowBlur: 5, // 阴影模糊大小
shadowOffsetX: 2, // 阴影水平偏移
shadowOffsetY: 12, // 阴影垂直偏移
},
},
}
})
const option: any = {
// 地理坐标系组件,地图的配置是一层盖一层,从底层到顶层的配置依次为:geo => series => visualMap。geo隐藏掉只有series也是能正常显示整个地图的。
geo: {
map: 'china', // 使用 registerMap 注册的地图名称
zlevel: 13, // 所有图形的 zlevel 值
show: true,
// layoutCenter: ['50%', '50%'], // 地图中心在屏幕中的位置
roam: false, // 是否开启鼠标缩放和平移漫游,只开启单个时,设置'scale' 或者 'move'
// layoutSize: '100%', // 地图的大小
zoom: 1.2, // 当前视角的缩放比例
// 图形上的文本标签
label: {
normal: {
show: true, // 开启会显示省份名称
textStyle: {
fontSize: 12,
color: 'rgba(253, 218, 190,0.45)',
},
},
},
// 在地图中对特定的区域配置样式(不包含南海诸岛缩略框)
regions: regions,
// 地图区域的多边形 图形未选中的样式(包含南海诸岛缩略框)
itemStyle: {
normal: {
areaColor: '#9E1B12',
borderColor: '#620E04',
borderWidth: 1,
},
},
// 鼠标移入高亮效果
emphasis: {
disabled: true,
},
},
series: [
// 发射点
{
type: 'effectScatter', // 带有涟漪特效动画的散点(气泡)图
coordinateSystem: 'geo', // 该系列使用的坐标系
zlevel: 15,
symbol:
'image://data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7', // 标记的图形
symbolSize: 13, // 标记的大小
// 涟漪特效相关配置
rippleEffect: {
period: 6, // 动画的周期,秒数
num: 3, // 波纹的数量
brushType: 'fill', // 波纹的绘制方式,可选 'stroke' 和 'fill'
scale: 3, // 动画中波纹的最大缩放比例
},
data: centerCitys,
},
// 接收点
{
type: 'effectScatter',
coordinateSystem: 'geo',
zlevel: 15,
symbolSize: 4,
data: aroundCitys,
},
// 飞线
{
type: 'lines',
coordinateSystem: 'geo',
zlevel: 14,
// 线特效的配置
effect: {
show: true,
period: 2, // 控制流星的速度,数字越小越快
trailLength: 0.2, // 控制流星尾巴的长度,范围为0-1
symbol: 'pin', // 尾巴形状,也可以设置成其他符号
symbolSize: 10, // 尾巴大小
},
data: linesArr,
},
],
}
// 注册地图
useEffect(() => {
echarts.registerMap('china', chinaJson) // 'china' 是地图注册名称
setEchartsOption(option) // 确保 registerMap 在 setEchartsOption 之前执行
}, [])
// 响应式重绘(窗口大小变化)
useEffect(() => {
const handleResize = () => {
if (chartRef.current) {
chartRef.current.getEchartsInstance().resize()
}
}
window.addEventListener('resize', handleResize)
return () => {
window.removeEventListener('resize', handleResize)
}
}, [])
if (echartsOption) {
return <ReactECharts ref={chartRef} option={echartsOption} style={{ height: '70vh' }} />
}
return <></>
}
china.json文件可去DataV下载
我的其他问题
1.使用DataV组件
import { DigitalFlop } from '@jiaminghi/data-view-react'
报错:无法找到模块“@jiaminghi/data-view-react”的声明文件
解决方法:
在项目下随便找个位置 创建一个 datav.d.ts (随便起的名字),内容:
declare module "@jiaminghi/data-view-react";
2.地图第一次会显示,但一刷新就报错
Map china not exists. The GeoJSON of the map must be provided.
Uncaught TypeError: Cannot read properties of undefined (reading 'regions')
原因:需要确保 registerMap 在 setOption 之前执行。
// 注册地图 useEffect(() => { echarts.registerMap('china', chinaJson) // 'china' 是地图注册名称 setEchartsOption(option) // 确保 registerMap 在 setEchartsOption 之前执行 }, []) if (echartsOption) { return <ReactECharts option={echartsOption} style={{ height: '52vh' }} /> } return <></>
3.想要不显示南海诸岛具体图形,只显示缩略图
修改china.json文件,我是从第三方示例下载的:https://www.makeapie.cn/echarts_content/x---RvEDTa.html


浙公网安备 33010602011771号