需求:
在一张地图上使用不同图标显示机票和火车票的轨迹图,并对线路和城市进行标注。
效果如图所示:
具体代码的实现:
<template>
<div class="development-history">
<div class="echarts-chart" id="chart" ref="chart"></div>
</div>
</template>
<script>
import { chinaData } from "@/assets/js/china"; // 引入中国地图数据
import { imgData } from "@/common/canvas-img-data"; // 引入图片信息:矢量图
export default {
name: "global-coverage",
data() {
return {
customClass1: "title",
customClass2: "desc",
myChart: ""
};
},
mounted() {
this.echartsInit();
window.onresize = () => { // 定义窗口大小变更通知事件
if (this.myChart) {
this.myChart.resize();
}
};
},
methods: {
// 地图初始化
echartsInit() {
this.myChart = this.$echarts.init(this.$refs.chart);
this.$echarts.registerMap("china", chinaData);
// 小飞机矢量图
let planePath = imgData.planePath;
let trainPath = imgData.trainPath;
let circlePath = imgData.circlePath;
// 轨迹数据
let dotData = [
[{ name: "拉萨", value: 610 }, { name: "成都", value: 0 }],
[{ name: "拉萨", value: 60 }, { name: "西安", value: 0 }],
[{ name: "西安", value: 500 }, { name: "厦门", value: 0 }],
[{ name: "西宁", value: 600 }, { name: "上海", value: 0 }],
[{ name: "西安", value: 300 }, { name: "拉萨", value: 0 }],
[{ name: "香港", value: 800 }, { name: "拉萨", value: 0 }],
[{ name: "西宁", value: 234 }, { name: "昆明", value: 0 }],
[{ name: "昆明", value: 45 }, { name: "呼和浩特", value: 0 }],
[{ name: "呼和浩特", value: 9 }, { name: "上海", value: 0 }],
];
let dotDataOne = [
[{ name: "哈尔滨", value: 360 }, { name: "成都", value: 0 }],
[{ name: "成都", value: 4430 }, { name: "北京市", value: 0 }],
[{ name: "北京市", value: 10 }, { name: "上海", value: 0 }],
[{ name: "上海", value: 1200 }, { name: "北京市", value: 0 }],
[{ name: "香港", value: 11 }, { name: "北京市", value: 0 }],
[{ name: "乌鲁木齐", value: 23 }, { name: "成都", value: 0 }],
[{ name: "长沙", value: 600 }, { name: "重庆", value: 0 }],
[{ name: "郑州", value: 600 }, { name: "厦门", value: 0 }],
];
// 城市坐标数据
let coordinates = {
北京: [116.4551, 40.2539],
天津: [117.4219, 39.4189],
上海: [121.4648, 31.2891],
香港: [114.2578, 22.3242],
澳门: [113.5547, 22.1484],
哈尔滨: [126.54, 45.80],
成都: [104.07, 30.57],
北京市: [116.4551, 40.2539],
兰州:[103.84052 , 36.06724],
拉萨:[91.17846 , 29.65949],
西宁: [101.78445 , 36.62339],
昆明: [102.83944 , 24.88627],
香港:[102.83944 , 24.88627],
呼和浩特:[111.75551 , 40.84842],
长沙:[113.08755 , 28.25182],
重庆:[106.55844 , 29.56900],
郑州:[113.63142 , 34.75344],
厦门:[118.09643 , 24.48541],
};
//城市坐标数据
this.coordinateCity = {};
this.scatterArr = [];// 城市对儿
for(let _key in coordinates){
let _item = coordinates[_key];
let obj = {
name: _key,
value: _item
}
this.scatterArr.push(obj)
}
let series = [];
let color = ["#9ae5fc", "#dcbf71", "#F5A623", "#BD10E0"]; // 自定义图中要用到的颜色
// 获取地图中起点和终点的坐标,以数组形式保存下来
let convertData = function (data) {
var res = [];
for(var i = 0; i < data.length; i++){
var dataItem = data[i];
var fromCoord = coordinates[dataItem[0].name];
var toCoord = coordinates[dataItem[1].name];
if (fromCoord && toCoord) {
res.push({
name: dataItem[0].name + "-" + dataItem[1].name,// 起点坐标 终点坐标
coords: [fromCoord, toCoord],// 起点坐标 终点坐标
value: dataItem[0].value,// 起点坐标 终点坐标
});
}
}
return res;
};
// 图中一共用到三种效果,分别为航线特效图、飞机航线图以及城市图标涟漪图。
// 要用到setOption中的series属性,并且对每个城市都要进行三次设置。
series.push(
// 散点效果 城市图标涟漪图
{
type: "scatter",
coordinateSystem: "geo", // 表示使用的坐标系为地理坐标系
zlevel: 3,//用于分层,z-index的效果
label: {
// 默认的文本标签显示样式
normal: {
show: true,
position: "right", // 标签显示的位置
formatter: "{b}", // 标签内容格式器
}
},
itemStyle: {
normal: {
color: '#b8edf4',
}
},
symbol: circlePath,data: this.scatterArr
},
);
// 飞机票、火车票轨迹
let travelSeries = [
// 飞机航线图
{
type: "lines",
zlevel: 2,//用于分层,z-index的效果
effect: {
show: true,
period: 20,
symbol: planePath, // 特效形状,可以用其他svg pathdata路径代替
symbolSize: 14
},
lineStyle: {
// 正常情况下的线条样式
normal: {
color: '#b8edf4',
width: 1,
opacity: 0.2,
curveness: 0.5
}
},
data: convertData(dotData)
},
// 航线特效图
{
type: "lines",
zlevel: 3, // 用于分层,z-index的效果
effect: {
show: false, // 动效是否显示
period: 20, // 特效动画时间
trailLength: 0, // 特效尾迹的长度
color: "#b8edf4", // 特效颜色
symbolSize: 0 // 特效大小
},
lineStyle: {
// 正常情况下的线条样式
normal: {
color: '#b8edf4',
width: 0.5, // 因为是叠加效果,要是有宽度,线条会变粗,白色航线特效不明显
opacity: 0.8,
curveness: 0.5 // 线条曲度
}
},
data: convertData(dotData)
},
// 火车轨迹图
{
type: "lines",
zlevel: 2,//用于分层,z-index的效果
effect: {
show: true,
period: 20,
symbol: trainPath, // 特效形状,可以用其他svg pathdata路径代替
symbolSize: 14
},
lineStyle: {
// 正常情况下的线条样式
normal: {
color: '#b8edf4',
width: 1,
trailLength: 0,
opacity: 0.6,
curveness: 0.2
}
},
data: convertData(dotDataOne)
},
// 轨迹线特效图
{
type: "lines",
zlevel: 2, // 用于分层,z-index的效果
effect: {
show: true, // 动效是否显示
period: 20, // 特效动画时间
trailLength: 0, // 特效尾迹的长度
color: '#b8edf4',// 特效颜色
symbolSize: 1 // 特效大小
},
lineStyle: {
// 正常情况下的线条样式
normal: {
color: '#b8edf4',//color[0],
width: 0, // 因为是叠加效果,要是有宽度,线条会变粗,白色航线特效不明显
curveness: 0.2 // 线条曲度
}
},
data: convertData(dotDataOne)
},
]
series = series.concat(travelSeries);
// 地图外围阴影
let mapSeries = {
type: "map",
map: "china",
zlevel: 1,
zoom:1.15,
geoIndex: 2,
aspectScale: 0.75, //长宽比
layoutCenter: ["50%", "51%"], //地图位置
layoutSize: "100%",
roam: false,
itemStyle: {
normal: {
areaColor: "#6857cf",
borderColor: "#6857cf",
borderWidth: 0
}
},
// 高亮样式
emphasis: {
label: {
show: false, // 高亮的时候不显示标签
},
itemStyle: {
areaColor: "#6857cf",
borderColor: "#6857cf",//边框颜色
}
},
}
series.push(mapSeries);
let option = {
textStyle: {
fontSize: 10,
color: "#FFFFFF"
},
tooltip: {
show: true,
trigger: "item",
backgroundColor: "#ffffff",
borderColor: "#ffffff",
showDelay: 0,
hideDelay: 0,
transitionDuration: 0,
textStyle:{
color: '#000',
},
formatter: function (params) {
if (params.seriesType === "lines") {
let showStr = params.name + ":" + params.value + "千人次";
return showStr;
}
}
},
geo: {
map: "china",
aspectScale: 0.75, //长宽比
roam: false, // 禁止缩放平移
layoutCenter: ["50%", "50%"], //地图位置
layoutSize: "100%",
zoom:1.15,
zlevel: 2,
label: {
normal: {
show: false,
},
},
itemStyle: { // 每个区域的样式
normal: {
areaColor: "#17048b",//区域颜色
borderColor: "#1773c3",//边框颜色
shadowColor: "transparent",//阴影颜色
shadowBlur: 0,
}
},
// 高亮样式
emphasis: {
label: {
show: false, // 高亮的时候不显示标签
},
itemStyle: {
areaColor: "#17048b",
borderColor: "#1773c3",//边框颜色
}
},
regions: [
{
name: "南海诸岛",
label: {
show: true,
color: "#009cc9",
},
itemStyle: {
areaColor: "rgb(0,52,17)",
borderColor: "rgb(235,241,236)",
normal: {
borderColor: "#0a53e9",
}
}
},
],
},
series: series,
backgroundColor: "#010347",
};
this.myChart.setOption(option);
}
},
};
</script>
<style scoped lang="scss">
.development-history {
width: 100%;
height: 100vh;
background-size: 100% 100%;
overflow: hidden;
position: relative;
}
.echarts-chart {
width: 100%;
height: 100%;
}
@media only screen and (max-width: 1366px) {
.development-history {
height: 800px;
}
}
@media only screen and (max-width: 1200px) {
.development-history {
height: 700px;
}
}
@media only screen and (max-width: 992px) {
.development-history {
height: 600px;
}
}
@media only screen and (max-width: 768px) {
.development-history {
height: 400px;
}
}
</style>
项目中使用两个地图的图层实现视觉上的立体感。
注:多轨迹图的展示关键在于echart图层的叠加。