echarts绘制3D旋转地球

效果图

3D旋转地球

代码展示

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文件

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值