Echarts图表实现循环动画(数据不变)

3,366 阅读1分钟

后端请求的数据不变,但是为了展示效果,希望循环Echarts初始化动画效果

1. 折线图循环初始化动画

setInterval(()=>{
	// 先echart.clear(),再初始化echart.setOption()
}, 4000

2. 环图循环选中动画

setInterval(()=>{
	// 先取消高亮downplay当前,再高亮选中highlight下一个
}, 4000

封装Chart组件

  • 支持自适应图标尺寸
  • 动态设置是否展示动画
import React from 'react';
import echarts from 'echarts';
import * as _ from 'lodash';

interface Props {
    id: string;
    option: any;
    isActive?: boolean; // 是否展示动画效果
}

export default class Chart extends React.Component<Props> {
    state = {
        myEchart: null,
        timer: null,
        dataIndex: 0,
    }
 
    componentDidMount() {
        this.init();
        
        window.addEventListener("resize", () => {
            if(!this.state.myEchart) return;
            (this.state.myEchart as any).resize();
        })

        if(this.props.isActive) {
            var timer;
            if(_.get(this, 'props.option.series[0].type', '') === 'pie') { // 饼图:循环选中动画
                timer = setInterval(this.chartHover, 1500);
            } else { // 其他:循环初始动画
                timer = setInterval(() => { 
                    if(this.state.myEchart)
                    this.clearChart();
                    this.init();
                }, 4000);
            }
            this.setState({timer});
        }
    }
	
    // 初始化动画
    init = () => {
        let myEchart = echarts.init(document.getElementById(this.props.id));
        myEchart.setOption(this.props.option);
        this.setState({
            myEchart
        })
    }
	
    // 清除图标
    clearChart = () => {
        (this.state.myEchart as any).clear();
    }
	
    // 饼图 循环选中
    chartHover = () => {
        var dataIndex = this.state.dataIndex;
        var dataLen = this.props.option.series[0].data.length;
        let myEchart = echarts.init(document.getElementById(this.props.id));
        // 取消之前高亮的图形
        myEchart.dispatchAction({
          type: 'downplay',
          seriesIndex: 0,
          dataIndex: dataIndex
        })
        dataIndex = (dataIndex + 1) % dataLen
        // 高亮当前图形
        myEchart.dispatchAction({
          type: 'highlight',
          seriesIndex: 0,
          dataIndex: dataIndex
        })
        this.setState({dataIndex});
        this.setState({myEchart});
    }

    UNSAFE_componentWillReceiveProps(nextProps) {
        let myEchart = echarts.init(document.getElementById(this.props.id));
        myEchart.setOption(nextProps.option);
    }

    componentWillUnmount() {
        window.removeEventListener("resize",() => {
            if(!this.state.myEchart) return;
            (this.state.myEchart as any && this.state.myEchart).resize();
        })

        if(this.state.timer){
            clearInterval(this.state.timer as any);
        }
    }

    render() {
        const { id } = this.props;
        return (
            <div style={{width: '100%', height: '100%'}} id={id}></div>
        )
    }
}

使用姿势

<Chart id='stress' option={optionS} isActive={true} />