AntV折线图自动滚动展示

173 阅读1分钟

最近在做公司的一个大屏展示页时,要求折线图能够自动滚动,网上大多例子都是基于Echarts实现的,没有适合AntV React的,于是自己动手

import React, { useContext, useEffect } from 'react';
import { Datum, Line } from '@antv/g2plot';
import ProCard from '@ant-design/pro-card';
let ticketCount = 5;
let plot: Line;
const cardStyle = {
    backgroundColor: '#16134B',
    height: '34vh',
};
//需要展示的数据,实际这个地方的数据有很多很多
const data=[
    {
        "site_name": "Whiz Demo",
        "successful": 100
    }
]
const Demo: React.FC = () => {
const containerRef = React.createRef<HTMLElement>();
//最小的数据
let min = 100
//鼠标是否移动到图表区域
let mouseEntered = false;
data.map(res => {
    if (res.successful < min) {
        min = res.successful
    }
})
 useEffect(() => {
        plot = new Line(containerRef.current!, {
            data: data.slice(0, data.length > ticketCount ? ticketCount : data.length),
            xField: 'site_name',
            yField: 'successful',
            padding: 'auto',
            autoFit: false,
            xAxis: {
                label: {
                    style: {
                        fill: '#fff',
                    }
                },
            },
            yAxis: {
                min: min - 2,
                max: 100,
                grid: null,
                label: {
                    formatter: (v: any) => `${parseFloat(v).toFixed(2)}%`,
                    style: {
                        fill: '#fff',
                    }
                },
            },
            tooltip: {
                formatter: (datum: Datum) => {
                    return { name: datum.site_name, value: datum.successful + '%' };
                },
            },
            color: '#FF696D',
            smooth: true,
            point: {
                size: 3
            },
        });
        //添加鼠标进入图表区和离开图表区事件
        plot.on('plot:mouseenter', () => {
            mouseEntered = true;
        });
        plot.on('plot:mouseleave', () => {
            mouseEntered = false;
        });
        plot.render();
    }, [])
    useEffect(() => {
        if (data.length <= ticketCount) {
            plot.changeData(data);
            return;
        }
        let currentIndex = 0;
        //每次保证取5条数据,无限循环[1,2,3,4,5],[2,3,4,5,6],[3,4,5,6,1]...
        const getNextFiveData = () => {
            const fiveData = [];
            for (let i = 0; i < ticketCount; i++) {
                const index = (currentIndex + i) % data.length;
                fiveData.push(data[index]);
            }
            currentIndex = (currentIndex + 1) % data.length;
            return fiveData;
        }
        const timer = setInterval(() => {
            if (!mouseEntered) {
                const newData = getNextFiveData()
                plot.changeData(newData);
            }
        }, 1500);
        return () => {
            clearInterval(timer);
        };
    }, [data])
    return <ProCard
        title='xxxxx'}
        style={cardStyle}
    >
        <div ref={containerRef as React.RefObject<HTMLDivElement>} style={{ width: '100%', height: '100%' }}></div>
    </ProCard>;
}
export default Demo;

最终效果

chart.gif