react与echarts的配合动态展示数据(以地图绘点为例)

1、用来干什么:该例子主要用来描述在react项目中,如何用echarts的绘制功能制作一个动态获取接口数据的地图
2、会收获什么:将会介绍百度API的使用与注意事项,echarts配合百度地图API绘制点图,点浮动时展示详细数据
3、示例
效果如图所示(关于具体的样式可以自行设计)
在这里插入图片描述
1)接入百度API
需要申请百度API开发者模式
https://lbsyun.baidu.com/index.php?title=jspopularGL
按步骤操作即可
在这里插入图片描述
请添加图片描述
在react的index.html中引入API
换成自己的ak,此时注意请求为https(http协议也行),查看一下setupProxy.js文件target网址的传输协议是否与百度api的相同,避免跨域。(以target里的为准,改动百度api的)
在这里插入图片描述
2)引入echarts绘制点
基于官网例子进行绘制
https://echarts.apache.org/examples/zh/editor.html?c=effectScatter-bmap

点的数据与位置从后台获取,在页面加载前完成绘制

let bReady = false;
let context = "";
let sLastDateInputofDoAjaxGetTooltip = "";
class Position extends React.Component {
	state = {
     	data: [],
     	geoCoordMap: {},
	}
	componentDidMount() {
     	this.getPositionData()  
	}
	render() {
        return (
            <div className="map">
                <div id="main" style={{ width: '1800px', height: '1200px' }} />
            </div>
        )
 	}
 }
 export default Position;
//地图数据接口
    getPositionData() {
        mirrorService.getPosition().then(res => {
            if (res.code === 200) {
                console.log("返回的数据为", res);
                //拼接相应的数组
                let newArr = res.distributions
                let data = []
                newArr.map(item => {
                    data.push({name:item.district, value: item.nums, province: item.province, city: item.city})
                })

                let geoCoordMap = {}
                newArr.map(item => {
                    geoCoordMap[item.district]=[item.lng, item.lat]
                })
				//数据与地理位置的准备
                this.setState({
                    data,  //数组,[省:,市: ,区: ,该区总数量: ]
                    geoCoordMap,  //对象, {区: 区的经纬度数组}
                })
                
                //绘制地图
                this.drawMap()

        	}
        }).catch(error => {
            error && message.error(error);
        })
    }

绘制地图函数

drawMap() {
        var chartDom = document.getElementById('main');
        var myChart = echarts.init(chartDom);

        //let that = this
        var option;
        option = {
            title: {
                text: '全国主要城市',
                subtext: '设备分布',
                left: 'center'
            },
            tooltip: {
                trigger: 'item',
                //triggerOn: "click",
                formatter: function (params, ticket, callback) {
                     //优化显示,防止闪烁
                    console.log(params.data);
                    if (sLastDateInputofDoAjaxGetTooltip === params.data.name) {
                        return context;
                    } else {
						//鼠标触碰圆点时,调用接口查询该区的详细数据
                        mirrorService.getDetailPosition(params.data.province, params.data.city, params.data.name).then(res => {
                            bReady = false;//设置状态为不可用
                            if(sLastDateInputofDoAjaxGetTooltip === params.data.name){
                                bReady = true;
                                return;
                            }else {
                                sLastDateInputofDoAjaxGetTooltip = params.data.name;
                            }
                        
                        if (res.code === 200) {
                            console.log("返回的详情数据", res);
                            context = `${params.data.name}的设备有</br>`

                            res.distributions.forEach(item => {
                                context += `位置:${item.address} 数量:${item.nums}</br>`;
                            });
                            
                            let itv = setInterval(function () {
                                if(bReady === true){
                                    callback(ticket, context);
                                    window.clearInterval(itv);//停止检查
                                }
                            }, 100);
                            bReady = true;//不管有没有内容,状态都要改回去
                        }
                        })

                    }
                    
                    return "数据查询中……";
                  },
            },

			
            bmap: {
                center: [125.114129, 35.550339],
                zoom: 5,
                roam: true,
                mapStyle: {
                    styleJson: [{
                        "featureType": "water",
                        "elementType": "geometry",
                        "stylers": {
                            "visibility": "on",
                            "color": "#ccd6d7ff"
                        }
                    }, {
                        "featureType": "green",
                        "elementType": "geometry",
                        "stylers": {
                            "visibility": "on",
                            "color": "#dee5e5ff"
                        }
                    }, 
                    //.....数据量太多,可以自行设计
                    //[百度地图个性化设计](https://lbsyun.baidu.com/customv2/editor/6e940a9e621efcb9cff05e4492936858)
                    ]
                }
            },

            series: [
                {
                    name: '设备',
                    type: 'scatter',
                    coordinateSystem: 'bmap',
                    data: this.convertData(this.state.data),
                    symbolSize: function (val) {
                        return 15;
                    },
                    encode: {
                        value: 2
                    },
                    label: {
                        normal: {
                            show: true,
                            formatter: this.showNumber(this.state.data)
                        },
                        formatter: '{c}',
                        position: 'right',
                        show: false
                    },
                    emphasis: {
                        label: {
                            show: true
                        }
                    },
                    
                },
                {
                    name: 'Top 5',
                    type: 'effectScatter',
                    coordinateSystem: 'bmap',
                    data: this.convertData(
                        this.state.data
                            .sort(function (a, b) {
                                return b.value - a.value;
                            })
                            .slice(0, 5)
                    ),
                    symbolSize: function (val) {
                        return 20;
                    },
                    encode: {
                        value: 2
                    },
                    showEffectOn: 'render',
                    rippleEffect: {
                        brushType: 'stroke'
                    },
                    label: {
                        normal: {
                            show: true,
                            formatter: this.showNumber(this.state.data),
                        },
                        formatter: '{b}',
                        position: 'right',
                        show: true
                    },
                    itemStyle: {
                        shadowBlur: 10,
                        shadowColor: '#333'
                    },
                    emphasis: {
                        scale: true
                    },
                    zlevel: 1
                }
            ]
                };
        option && myChart.setOption(option);
    }

	//显示圆点数字
    showNumber(data) {
        let numbers = []
        if (data.length != 0) {
            numbers = data.map(item => item.value)  
        }
        return numbers
    }
  
  	//数据的处理函数
    convertData(data) {
    	var res = [];
    	for (var i = 0; i < data.length; i++) {
    		var geoCoord = this.state.geoCoordMap[data[i].name];
    		if (geoCoord) {
      			res.push({
        			name: data[i].name,
          			value: geoCoord.concat(data[i].value),
          			city: data[i].city,
          			province: data[i].province
      			});
   		 	}
  		}
  		return res;
	};

问题汇总
1、tooltip中formatter的使用
此函数可以按照需要浮动展示数据,也可以在数据量较大或者降低耦合时,对相应数据的接口调用,此例中圆点展示区的总数,点浮动调用查询此区的详细数据。
建议使用回调函数function (params, ticket, callback) {}的格式,配合callback做到异步的效果

2、formatter内接口函数的调用
2.1 对于获取的数据直接与当前的数据进行字符拼接等操作,然后返回即可,所以请求数据不必保存到state
2.2 如果在formatter内直接实现接口函数,则不必考虑this指向问题,如果在外部实现再内部调用,可能会出现this丢失的问题,需要
在option外提前保存this,一般写为

let that = this
...
formatter: function (params, ticket, callback) {
	...
	that.函数(参数)
}

2.3 对于不同的请求方式,注意相应写法要求即可,实例中使用了fetch方式,jQuery Ajax,promise等异步请求方式都可以实现

3.在小圆圈内移动鼠标时,加载的内容会出现闪烁或再次加载
详细可参考https://blog.csdn.net/fanpeizhong/article/details/80274740?spm=1001.2014.3001.5502

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值