效果图
代码展示
import React, { Component, Fragment } from 'react';
import ReactEcharts from "echarts-for-react";
import echarts from 'echarts';
import 'echarts-gl';
import _ from 'lodash';
import world from './world.json';
echarts.registerMap('world',world);
class Earthgraph extends Component {
constructor(props) {
super(props);
this.getApi = this.getApi.bind(this);
this.getGraph = this.getGraph.bind(this);
this.GetRandomNum = this.GetRandomNum.bind(this);
this.state= {
earthgraph:{},
geoCoordMap:{
'起点': [-90.696295, -35.679979],
'111': [-90.696295, 30.679979],
'222': [-110.696295, 30.679979],
'333': [-120.696295, 30.679979],
'444': [-130.696295, 0.679979],
'555': [-100.696295, 0.679979],
'666': [-90.696295, 0.679979],
'777': [-80.696295, 0.679979],
'888': [-70.696295, 0.679979],
'999': [-60.696295, 0.679979]
},
addrData: [
['111',[[{
name: '111'
}, {
name: "起点",
value: 90
}]]
],
["222",[[{
name: '222'
}, {
name: "起点",
value: 90
}]]
],
['333',[[{
name: '333'
}, {
name: "起点",
value: 90
}]]
],
['444',[[{
name: '444'
}, {
name: "起点",
value: 90
}]]
],
['555',[[{
name: '555'
}, {
name: "起点",
value: 90
}]]
],
['666',[[{
name: '666'
}, {
name: "起点",
value: 90
}]]
],
['777',[[{
name: '777'
}, {
name: "起点",
value: 90
}]]
],
['888',[[{
name: '888'
}, {
name: "起点",
value: 90
}]]
],
['999',[[{
name: '999'
}, {
name: "起点",
value: 90
}]]
]
],
}
}
componentDidMount() {
this.getGraph();
}
componentWillUnmount(){
this.setState=(state,callback)=>{
return
}
}
//随机生成经纬度
GetRandomNum(Min,Max) {
let Range = Max - Min;
let Rand = Math.random();
return(Min + Math.round(Rand * Range));
}
convertData(data) {
let geoCoordMap = this.state.geoCoordMap;
let res = [];
for (let i = 0; i < data.length; i++) {
let dataItem = data[i];
let [fromCoord, toCoord] = [geoCoordMap[dataItem[1].name], geoCoordMap[dataItem[0].name]];
if (fromCoord && toCoord) res.push([fromCoord, toCoord]);
}
return res;
}
getGraph() {
let _this =this;
let geoCoordMap = this.state.geoCoordMap;
let long=[],lati=[],step=20,steptwo=10,dataRandom=[];
for(let s=-180;s<=180;s+=step){
long.push(s);
}
for(let s=-90;s<=90;s+=steptwo){
lati.push(s);
}
for(let a=0,j=long.length;a<j;a++){
for(let b=0,k=lati.length;b<k;b++){
dataRandom.push({
value:[
long[a],
lati[b],
0
]
})
}
}
let temp = [];
_.forEach(dataRandom,(val) => {
temp.push(val.value);
})
let line=[];
let dataRandomLine = _.chunk(temp,Math.floor(180/steptwo)+1);
for(let c=0;c<dataRandomLine.length;c++){
if(c+1<dataRandomLine.length){
let some=dataRandomLine[c],sometwo=dataRandomLine[c+1];
for(let d=0;d<some.length;d++){
if(d+1<some.length){
line.push([
some[d],
sometwo[d+1]
])
}
if(d-1>0){
line.push([
some[d],
sometwo[d-1]
])
}
}
}
}
let [series2d, series3d] = [ [],[] ];
this.state.addrData.forEach(function(item) {
series2d.push({// 2d平面地图 + 散点
type: 'effectScatter',
coordinateSystem: 'geo',
zlevel: 3,
rippleEffect: {
color:'#FB1C87',
period: 4, //动画时间,值越小速度越快
brushType: 'fill', //波纹绘制方式 stroke, fill
scale: 4 //波纹圆环最大限制,值越大波纹越大
},
label: {
fontSize: 24,
show: false,
position: 'right',
formatter: '{b}'
},
itemStyle: {//线条起始点的圆圈
normal: {
color: '#ffffff',
borderColor:'#EA68A2',
borderWidth:8,
shadowColor:'#FB1C87',
shadowBlur:13
}
},
data: item[1].map(function(dataItem) {
return {
name: dataItem[1].name,
value: geoCoordMap[dataItem[1].name],
symbolSize: dataItem[1].value / 4
};
})
}, {
type: 'effectScatter',
coordinateSystem: 'geo',
zlevel: 3,
rippleEffect: {
color:'#00EAFF',
period: 4, //动画时间,值越小速度越快
brushType: 'fill', //波纹绘制方式 stroke, fill
scale: 4 //波纹圆环最大限制,值越大波纹越大
},
label: {
show: true,
position: 'left',
fontSize: 18,
formatter: '{b}'
},
itemStyle: {
normal: {
color: '#ffffff',
borderColor:'#00EAFF',
borderWidth:8,
shadowColor:'#032390',
shadowBlur:13
}
},
data: [{
name: item[0],
value: geoCoordMap[item[0]],
symbolSize: parseInt(Math.random() * 20 + 10),
label: {
position: 'right'
}
}]
},{
type: 'lines',
lineStyle: {
color: '#004C8E',
width: 2,
opacity: 0.6
},
tooltip: {
show: false
},
data: line
});
series3d.push({// 3d连线
type: 'lines3D',
effect: {
show: true,
period: 4,
symbolSize: [30, 30],
trailLength: 0.2,
trailWidth: 7,
},
lineStyle: {
color: '#00EAFF', //线滑动的颜色
width: 3,
opacity: 0.6
},
tooltip: {
show: false
},
data: _this.convertData(item[1])
}, {
type: 'scatter3D',
name: 'location',
coordinateSystem: 'globe',
blendMode: 'lighter',
symbol: 'circle',
symbolSize: 3,
silent: true,
itemStyle: {
color: '#04BEE7',
opacity: 1
},
data: dataRandom
})
});
let chart = echarts.init(document.createElement('canvas'), null, {
width: 4096,
height: 2048
});
// 添加2d地图 + 散点图
chart.setOption({
backgroundColor: 'rgba(2,6,45,0.7)',
geo: [{
type: 'map',
map: 'world',
left: 0,
top: 0,
right: 0,
bottom: 0,
silent: true,
boundingCoords: [
[-180, 90],
[180, -90]
],
scaleLimit: {
min:1,
max:1
},
roam: false,
itemStyle: {
borderColor: '#00D3FF',
areaColor: '#0059C7',
emphasis: {
areaColor: '#01C0F1'
}
},
label: {
fontSize: 24
}
}],
series: series2d
});
const earthgraph = {
backgroundColor: 'transparent',
tooltip: {
show: false
},
globe: {
baseTexture: chart,
top: 'middle',
left: 'center',
displacementScale: 0,
shading: 'color',
viewControl: {
distance: 180,
autoRotate: true,
},
postEffect: {
enable: true,
bloom: {
enable: true
},
},
light: {
main: {
color: '#fff', // 光照颜色
intensity: 2, // 光照强度
shadow: false // 是否显示纹理的阴影
},
},
},
roam: true,
series: series3d
}
this.setState({
earthgraph: earthgraph
})
}
render() {
return(
<Fragment>
<ReactEcharts
option={this.state.earthgraph}
notMerge={true}
lazyUpdate={true}
style={{height:'100%',width:'100%',marginTop:'-2%'}}
theme={"theme_name"}
/>
</Fragment>
)
}
}
export default Earthgraph;
说明
world.json内容太多,无法导入,可以随意在网上找一个世界地图的json文件