react项目中使用使用echarts-for-react组件动态刷新数据图表的问题

景鹏飞
2023-12-01

echarts-for-react

这是基于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的方式刷新数据

在在大屏数据可视化的应用当中我们通常是通过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事件就能让图表进行刷新

优化react组件性能的方法

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函数放到组件外面声明,这样做的目的是因为之前把这个函数放在组件里面,组件更新的时候这个函数会被重新声明。

 类似资料: