要在地球视角下画出海运路线图
方案
- 添加 globl 地球
- 创建geo地理坐标系
- 创建canvas对象用于承载地图世界地图this.worldChart
let cav = document.createElement("canvas");
this.$echarts.registerMap("world", geoJson);
this.worldChart = this.$echarts.init(cav, null, {
width: 4096,
height: 2048,
});
this.worldChart.setOption(this.worldChartOption);
- 设置globl 的baseTexture为this.worldChart
- 添加lines3D飞线效果
上组件源码
<template>
<div>
<div id="box" @click="showAll"></div>
</div>
</template>
<script>
import geoJson from "./mapJson.js";
import { nameMap, startPoint, changKu, chuan, gongChang } from "./data.js";
import { points, line } from "./lines.js";
export default {
data() {
return {
worldChart: null,
worldChartOption: {
backgroundColor: "rgba(3,28,72,1)",
geo: {
type: "map",
map: "world",
nameMap: nameMap,
left: 0,
top: 0,
right: 0,
bottom: 0,
boundingCoords: [
[-180, 90],
[180, -90],
],
zoom: 0,
roam: true,
itemStyle: {
areaColor: "#174f87",
color: "#fff",
borderColor: "#2578cb",
opacity: 0.9,
},
emphasis: {
itemStyle: {
areaColor: "#31deff",
color: "#174f87",
borderColor: "#318ED2",
borderWidth: 2,
shadowColor: "#15629A",
shadowBlur: 1,
shadowOffsetX: 3,
shadowOffsetY: 5,
},
},
label: {
fontSize: 28,
},
},
series: [],
},
globleChart: null,
globleChartOption: {
globe: {
show: true,
globeRadius: 120,
globeOuterRadius: 150,
environment: require("./assets/starfield.jpg"),
shading: "lambert",
zlevel: 10,
light: {
ambient: {
intensity: 1,
},
main: {
intensity: 1.6,
shadow: false,
},
},
atmosphere: {
show: true,
offset: 6,
color: "rgba(61,149,248,0.6)",
glowPower: 5,
innerGlowPower: 8,
},
viewControl: {
distance: 240,
autoRotate: true,
autoRotateSpeed: 5,
autoRotateAfterStill: 5,
},
},
series: [],
},
};
},
mounted() {
this.initData();
},
methods: {
initData() {
let cav = document.createElement("canvas");
this.$echarts.registerMap("world", geoJson);
this.worldChart = this.$echarts.init(cav, null, {
width: 4096,
height: 2048,
});
this.worldChart.setOption(this.worldChartOption);
this.globleChart = this.$echarts.init(document.getElementById("box"));
this.globleChartOption.globe.baseTexture = this.worldChart;
this.globleChart.setOption(this.globleChartOption, true);
this.addLines(line);
this.addPoint(points);
this.worldChart.on("click", (params) => {
console.log(params);
});
this.globleChart.on("click", (params) => {
console.log(params);
});
},
addLines(list) {
let flyLineList = [];
list.forEach((li) => {
for (let index = 0; index < li.coords.length - 1; index++) {
flyLineList.push({
coords: [li.coords[index], li.coords[index + 1]],
value: "",
});
}
});
const luxian = {
type: "lines",
id: "line",
coordinateSystem: "geo",
blendMode: "lighter",
polyline: true,
zlevel: 10,
effect: {
show: true,
period: 4,
trailLength: 0.2,
},
lineStyle: {
color: "#CCA343",
width: 4,
curveness: 0.5,
opacity: 0.4,
},
data: list,
};
let startPoint = [];
let endPoint = [];
let chuanPoint = [];
list.forEach((el) => {
el.coords.forEach((em, i) => {
if (i === 0) {
const haveSamePoint = startPoint.find(
(item) => item && item.name == el.name.split("-")[0]
);
if (!haveSamePoint) {
startPoint.push({
name: el.name.split("-")[0],
value: em,
symbolSize: 30,
symbol: changKu,
});
}
} else if (i === el.coords.length - 1) {
const haveSamePointEnd = endPoint.find(
(item) => item && item.name == el.name.split("-")[1]
);
if (!haveSamePointEnd) {
endPoint.push({
name: el.name.split("-")[1],
value: em,
symbolSize: 30,
symbol: gongChang,
});
}
} else {
chuanPoint.push({
name: "",
value: em,
symbolSize: 60,
symbol: chuan,
});
}
});
});
const linePoint = {
type: "scatter",
id: "onlinePoint",
coordinateSystem: "geo",
zlevel: 16,
rippleEffect: {
brushType: "stroke",
},
label: {
fontSize: 16,
show: true,
position: "right",
formatter: "{b}",
},
itemStyle: {
normal: {
color: "#f5f802",
},
},
data: [...startPoint, ...endPoint, ...chuanPoint],
};
console.log([...startPoint, ...endPoint, ...chuanPoint], 787);
this.updataSerise("line", luxian);
this.updataSerise("onlinePoint", linePoint);
setTimeout(() => {
this.updataChart();
}, 10);
},
addPoint(list) {
const areaPion = {
type: "effectScatter",
id: "areaPoint",
coordinateSystem: "geo",
zlevel: 11,
symbol: startPoint,
rippleEffect: {
brushType: "stroke",
},
label: {
fontSize: 18,
show: true,
position: "right",
formatter: "{b}",
},
itemStyle: {
normal: {
color: "#f5f802",
},
},
data: list,
};
this.updataSerise("areaPoint", areaPion);
setTimeout(() => {
this.updataChart();
this.changeView();
}, 10);
},
updataGlobleSerise(id, item) {
let ind = this.globleChartOption.series.findIndex((el) => el.id === id);
if (ind > -1) {
this.globleChartOption.series[ind] = item;
} else {
this.globleChartOption.series.push(item);
}
},
updataSerise(id, item) {
let ind = this.worldChartOption.series.findIndex((el) => el.id === id);
if (ind > -1) {
this.worldChartOption.series[ind] = item;
} else {
this.worldChartOption.series.push(item);
}
},
updataChart() {
this.worldChart.setOption(this.worldChartOption);
this.globleChart.setOption(this.globleChartOption, true);
},
showAll() {
this.$emit("no-act");
},
changeViewByCountry(country) {
const targ = points.find((el) => el.name == country);
if (targ) {
this.changeView(targ.value);
}
},
changeView(point) {
let coord = point || [116.46, 39.92];
this.globleChartOption.globe.viewControl.targetCoord = coord;
this.globleChart.setOption(this.globleChartOption);
},
resize() {
this.worldChart.resize();
this.globleChart.resize();
},
},
watch: {},
created() {},
};
</script>
<style scoped>
#box {
width: 100vw;
height: 100vh;
}
.tootipbox {
position: fixed;
left: 50%;
top: 500%;
z-index: 9999;
background-image: url("../../../../assets/img/screen6/label_bg.png");
background-repeat: no-repeat;
background-size: 100% 100%;
width: 200px;
height: 125px;
background-position: center center;
padding: 10px 20px;
font-size: 10px;
}
</style>