这是基于ECharts封装的react组件库,可以让你轻松的操作Echarts图表链接: link.
其实官网的实例就已经有动态刷新的效果了请看这里
import React, { useState, useEffect } from 'react';
import ReactECharts from 'echarts-for-react';
import {cloneDeep} from 'lodash';// 这里因为lodash版本不一样的问题所以引入方式和官网不一样
const Page: React.FC = () => {
const DEFAULT_OPTION = {
// Echarts图表所需要的数据,请移步看官网实例
// 这里的数据是初始化的时候的默认的数据
};
let count;
const [option, setOption] = useState(DEFAULT_OPTION);
function fetchNewData() {
const axisData = (new Date()).toLocaleTimeString().replace(/^\D*/,'');
const newOption = cloneDeep(option); // 一定要进行深拷贝
newOption.title.text = 'Hello Echarts-for-react.' + new Date().getSeconds();
const data0 = newOption.series[0].data;
const data1 = newOption.series[1].data;
data0.shift(); // 删除第一个元素
data0.push(Math.round(Math.random() * 1000));// 在数组末尾添加元素
data1.shift();// 删除第一个元素
data1.push((Math.random() * 10 + 5).toFixed(1) - 0);// 在数组末尾添加元素
newOption.xAxis[0].data.shift();// 删除第一个元素
newOption.xAxis[0].data.push(axisData);// 在数组末尾添加元素
newOption.xAxis[1].data.shift();// 删除第一个元素
newOption.xAxis[1].data.push(count++);// 在数组末尾添加元素
setOption(newOption);
}
useEffect(() => {
const timer = setInterval(() => {
fetchNewData();
}, 1000);
return () => clearInterval(timer);
});
return <ReactECharts
option={option}
style={{ height: 400 }}
/>;
};
export default Page;
上面就是官网的示例,用到了react的Hook
,原理就是设置一个定时器每隔一秒钟去把option的数据进行刷新然后重新渲染数据。
在在大屏数据可视化的应用当中我们通常是通过websocket的服务器来推送数据实现实时刷新数据,当服务器推送消息过来以后我们才去进行更新,下面是我使用的方法。
用到了redux对服务器发过来的数据进行管理,本来有使用redux-saga,用了之后反而变麻烦了,然后就不用了
import React, {useEffect, useState} from 'react';
import ReactEcharts from 'echarts-for-react';
import {cloneDeep} from 'lodash';
const BarChart = (props) =>{
const {state}= props;
const options = {
// 为了方便看代码数据我就不展示了
}
const [option, setOption] = useState(options);
function updateOption(s){
const axisData = (s.data.x);
const newOption = cloneDeep(option);
const data0 = newOption.series[0].data;
const data1 = newOption.series[1].data;
data0.shift();
data0.push(s.data.y);// 这边就是对服务器传过来的数据进行处理
data1.shift();
data1.push(s.data.y1);
newOption.xAxis[0].data.shift();
newOption.xAxis[0].data.push(axisData);
setOption(newOption);
}
useEffect(() => {
updateOption(state);
},[state]);
return(
<ReactEcharts
option={option}
notMerge={true}
lazyUpdate={true}
style={{width: '100%',height:'100%'}}
/>
)
}
const mapStateToProps = (state,props) => ({
...props,
state
});
const mapDispatch = {
getData:actions.getValue// 这个地方暂时不用了
}
export default connect(
mapStateToProps,//把仓库的状态映射为组件的属性对象
mapDispatch
)(BarChart)
通过redux对数据进行管理,只要服务器发送数据过来触发websocket的onmessage事件就能让图表进行刷新
import React, {useRef} from 'react';
import ReactEcharts from 'echarts-for-react';
import {cloneDeep} from 'lodash';
const options = {
// 为了方便看代码数据我就不展示了
};
function updateOption(o,s){
const axisData = (s.data.x);
const newOption = cloneDeep(o); //深拷贝一份原来的数据
const data0 = newOption.series[0].data;
const data1 = newOption.series[1].data;
data0.shift();
data0.push(s.data.y);// 这边就是对服务器传过来的数据进行处理
data1.shift();
data1.push(s.data.y1);
newOption.xAxis[0].data.shift();
newOption.xAxis[0].data.push(axisData);
return newOption;
}
const BarChart =React.memo( (props) =>{
const {state}= props;
const option = useRef(options);
option.current = updateOption(option.current, state);
return(
<ReactEcharts
option={option.current}
notMerge={true}
lazyUpdate={true}
style={{width: '100%',height:'100%'}}
/>
)
})
const mapStateToProps = (state,props) => ({
...props,
state
});
const mapDispatch = {
getData:actions.getValue// 这个地方暂时不用了
}
export default connect(
mapStateToProps,//把仓库的状态映射为组件的属性对象
mapDispatch
)(BarChart)
是不是看起来代码变的少一点了,这样不就优化了吗
其实优化的地方主要有以下几点
1、使用了React.memo()
只有当props
的值改变的时候才会触发更新
2、将updateOption
函数放到组件外面声明,这样做的目的是因为之前把这个函数放在组件里面,组件更新的时候这个函数会被重新声明。