ScatterChart.tsx 2.2 KB
Newer Older
1
import React, {FunctionComponent, useEffect, useMemo} from 'react';
P
Peter Pan 已提交
2
import {WithStyled, backgroundColor, position, primaryColor, size} from '~/utils/style';
3

4
import GridLoader from 'react-spinners/GridLoader';
5
import styled from 'styled-components';
6 7
import useECharts from '~/hooks/useECharts';

8 9
const Wrapper = styled.div`
    position: relative;
P
Peter Pan 已提交
10
    background-color: ${backgroundColor};
11 12 13 14 15 16

    > .echarts {
        height: 100%;
    }

    > .loading {
17 18
        ${position('absolute', 0, null, null, 0)}
        ${size('100%')}
19 20 21 22 23 24
        display: flex;
        justify-content: center;
        align-items: center;
    }
`;

25 26
const SYMBOL_SIZE = 12;

27 28 29 30 31 32 33
const options2D = {
    xAxis: {},
    yAxis: {},
    toolbox: {
        show: true,
        showTitle: false,
        itemSize: 0,
34

35 36 37 38 39 40
        feature: {
            dataZoom: {},
            restore: {},
            saveAsImage: {}
        }
    }
41 42
};

43 44 45 46 47
const options3D = {
    grid3D: {},
    xAxis3D: {},
    yAxis3D: {},
    zAxis3D: {}
48 49
};

50 51 52
const series2D = {
    symbolSize: SYMBOL_SIZE,
    type: 'scatter'
53 54
};

55 56 57
const series3D = {
    symbolSize: SYMBOL_SIZE,
    type: 'scatter3D'
58 59
};

60 61 62 63 64
type ScatterChartProps = {
    loading?: boolean;
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    data?: Record<string, any>[];
    gl?: boolean;
65 66
};

67
const ScatterChart: FunctionComponent<ScatterChartProps & WithStyled> = ({data, loading, gl, className}) => {
P
Peter Pan 已提交
68
    const {ref, echart, wrapper} = useECharts<HTMLDivElement>({
69
        loading,
P
Peter Pan 已提交
70 71
        gl,
        autoFit: true
72
    });
73

74
    const chartOptions = useMemo(
75 76 77 78 79 80 81 82 83
        () => ({
            ...(gl ? options3D : options2D),
            series:
                data?.map(series => ({
                    ...(gl ? series3D : series2D),
                    ...series
                })) ?? []
        }),
        [gl, data]
84
    );
85 86

    useEffect(() => {
87
        echart?.setOption(chartOptions);
88
    }, [chartOptions, echart]);
89

90
    return (
P
Peter Pan 已提交
91
        <Wrapper ref={wrapper} className={className}>
92 93 94 95 96 97 98 99
            {!echart && (
                <div className="loading">
                    <GridLoader color={primaryColor} size="10px" />
                </div>
            )}
            <div className="echarts" ref={ref}></div>
        </Wrapper>
    );
100 101 102
};

export default ScatterChart;