前言
如果没有geoJSON数据,可以去 datav官网 导出
定义数据结构
const pointsDataArr = [
{
name: '鄂州', // 展示的名称
routeName: [
{
region: '黄冈',
lable: '黄冈线',
value: 10
}
], // 路线
value: [114.89, 30.34], // title显示的经纬度
id: 'ez', // geo对应id
fileName: '420700_ez', // geoJSON 文件名
position:{
left: '10%',
top: 0
},
markerArr: [{ sectionName: '鄂州电厂', value: [114.60, 30.16] }] // marker
},
{
name: '黄冈',
routeName: [
{
region: '黄石',
lable: '黄石线',
value: 10
},
{
region: '鄂州',
lable: '鄂州线',
value: 10
}
],
position:{
left: '10%',
top: 0
},
value: [115.4, 30.8],
id: 'hg',
fileName: '421100_hg',
markerArr: []
},
{
name: '黄石',
routeName: [
{
region: '鄂州',
lable: '鄂州线',
value: 10
}
],
position:{
left: '10%',
top: 0
},
value: [115.03, 30],
id: 'hs',
fileName: '420200_hs',
markerArr: [{ sectionName: '西塞山电厂', value: [115.10, 29.76] }]
}
]
一、初始化在echarts中导入地图数据
this.myCharts = echarts.init(this.$refs.map); // 初始化
/*
引入geoJSON
@params(id,geoJSON地图数据)
*/
pointsDataArr.forEach(item => {
this.myCharts.registerMap(
item.id, { geoJSON:require(`@/assets/geoJson/${item.fileName}.json`
)
})
echarts.registerMap('hg', { geoJSON: require(`@/assets/geoJson/${item.fileName}.json`) });
echarts.registerMap('wh', { geoJSON: require(`@/assets/geoJson/${item.fileName}.json`) });
// 处理geo数据
const geo = []
pointsDataArr.forEach((item,index) => {
geo.push({
id:item.id, // 这里的id与echarts.registerMap方法中的id对应
name: item.id,
zlevel: index, // 防止都在一层 卡顿
map: item.id,
roam: false, // 禁止拖拽和放大
geoIndex: index, // 地图索引
zoom: 0.7, // 级别
...item.position, // 避免几个地图都在一起
label: {
normal: { // 静态的时候展示样式
show: false // 是否显示地图省份得名称
},
emphasis: {
show: false // 隐藏悬浮显示地区文字
}
},
itemStyle: {
normal: {
color: '#386935', // 地图背景色
borderColor: '#5D8646', // 省市边界线00fcff 516a89
areaColor: '#386935', // 地图背景色
borderWidth: 1,
shadowBlur: 1,
shadowColor: '#386935',
shadowOffsetX: 5,
shadowOffsetY: 10
},
emphasis: {
color: '#386935' // 悬浮背景
}
}
})
})
2、由于地图都是分开的,会导致经纬度不准确,这里做一个经纬度与px的转换
// 注意 要首先 myCharts.setOption(option) 才能获取 convertFromPixel api
// 经纬度转像素 像素在转经纬度
lonLatCutpixel(lonLat, pixelInfo) {
// 坐标转换为像素坐标 geoIndex 对应这geo
const pixel = this.myCharts.convertToPixel(
pixelInfo,
lonLat
);
// 统一根据第一个geo来换算 geoIndex 对应这上面定义的
const point = this.myCharts.convertFromPixel({ geoIndex: 0 }, pixel);
return point;
},
3、画线段性动画
const linesData = {
type: 'lines',
zlevel: 99,
effect: {
show: true,
period: 3, // 箭头指向速度,值越小速度越快
trailLength: 0, // 特效尾迹长度[0,1]值越大,尾迹越长重
symbol: 'triangle', // 箭头图标
symbolSize: 14, // 图标大小
color: '#fff'
},
selectedMode: 'single', // 开启单机点中
select: { // 选中后的样式
lineStyle: {
color: 'red',
width: 3
}
},
label: { // 线中间的数据 title
show: true,
formatter: (params) => `${params.data.lable}\n{a|${params.data.value}}`,
rich: {
a: {
align: 'left',
color: 'rgb(207, 78, 178)',
padding: [4, 10, 0, 10],
lineHeight: 30,
height: 18,
backgroundColor: 'rgb(32, 66, 17)',
fontSize: 16,
borderRadius: 4
}
},
opacity: 1,
verticalAlign: 'middle', // 是否在线的中间
position: 'middle', // 在线的中间 可以旋转
textStyle: {
color: '#fff',
fontSize: 20
}
},
lineStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: '#61CB34'
},
{
offset: 0.9,
color: '#61CB3410'
},
{
offset: 1,
color: '#61CB34'
}
]),
width: 2, // 线条宽度
curveness: 0.2 // 尾迹线条曲直度
},
emphasis: {
color: 'yellow' // 悬浮背景
}
},
data: this.convertData() // 此方法在下面定义 处理多个地图连接 坐标问题
};
// 处理经纬度偏移 lonLatCutpixel 方法在 2 中定义过了
convertData() {
const res = [];
this.pointsDataArr.forEach((item, index) => {
// 坐标转换为像素坐标 geoIndex 对应这geo 开始
const startingPoint = this.lonLatCutpixel(item.value, { geoIndex: index });
item.routeName.forEach((val) => {
let originaLonlat = null;
let originaIndex = 0;
let info = {};
// 得到结束线的经纬度
this.pointsDataArr.forEach((key, i) => {
if (key.name === val.region) {
originaLonlat = key.value;
originaIndex = i;
info = val;
}
});
// 坐标转换为像素坐标 geoIndex 对应这geo (结束)
const endingPoint = this.lonLatCutpixel(originaLonlat, { geoIndex: originaIndex
});
res.push({
coords: [startingPoint, endingPoint],
...info
});
});
});
return res;
},
4、画闪动圆点
const arr = [];
this.pointsDataArr.forEach((val, index) => {
// 换算经纬度
const lonLat = this.lonLatCutpixel(val.value, { geoIndex: index });
arr.push({
name: val.name,
value: lonLat
});
});
const pointsData = {
type: 'effectScatter',
coordinateSystem: 'geo',
zlevel: 10,
showEffectOn: 'render',
rippleEffect: { // 设置圆点动画
color: '#61CB34',
number: 1,
period: 1,
scale: 2,
brushType: 'fill'
},
hoverAnimation: true, // 启动动画
label: { // 圆点上面的标题
normal: {
formatter: '{b}',
position: 'top',
offset: [0, 0],
color: '#fff',
show: true,
fontSize: 26
}
},
symbol: 'circle',
symbolSize: 30,
itemStyle: {
normal: {
color: '#61CB34',
shadowBlur: 10,
shadowColor: '#61CB34'
}
},
data: arr
};
5、引入每个模块 setOption
setOption() {
if (this.myCharts) {
this.myCharts.clear();
this.myCharts = null;
}
this.myCharts = echarts.init(this.$refs.map);
// @params (与geo里面的id对应,{geoJSON数据})
this.pointsDataArr.forEach((item) => {
// eslint-disable-next-line import/no-dynamic-require
echarts.registerMap(item.id, { geoJSON: require(`@/assets/geoJson/${item.fileName}.json`) });
});
const option = {
backgroundColor: 'rgba(0,0,0,0)',
tooltip: {
show: false
// trigger: 'item',
// backgroundColor: 'rgba(120, 147, 222, 0.5)',
// borderColor: '#fff',
// formatter: (params) => {
// if (params.name) {
// return params.name;
// }
// return params.value;
// },
// enterable: true,
// padding: [0, 10],
// textStyle: { color: '#fff' }
},
xAxis: {
show: false
},
yAxis: {
show: false
},
// visualMap: {
// type: 'continuous',
// realtime: false,
// calculable: true
// },
geo: geo,
series: []
};
// 先注册一遍 这样才能使用 echarts转换经纬度的api
this.myCharts.setOption(option);
option.series = [
linesData,
pointsData
];
this.myCharts.setOption(option);
// 添加点击事件
this.myCharts.on('click', (e) => {
console.log(e);
});
// 默认选中第一条线
this.myCharts.dispatchAction({
type: 'select',
dataIndex: 0
});
this.myCharts.on('selectchanged', (params) => {
// 不让取消选中
if (params.fromAction === 'unselect') {
this.myCharts.dispatchAction({
type: 'select',
dataIndex: params.fromActionPayload.dataIndexInside
});
}
});
}
效果图如下