La elección de la biblioteca de visualización de datos en React, ejemplo de ListChart (gráfico de cambio de lista, datos similares son la barra del eje x)

Tabla de contenido

Echarts

Echarts Nativos+TS

ListChart.tsx

ListChartUtil.tsx

ReactECCharts

Los ganchos de reacción encapsulan los componentes de Echarts5 (ts/js)

Comparado

D3

recargas

Echarts

Echarts está desarrollado por Baidu, que está más en línea con los hábitos de los chinos . Admite varios tipos de gráficos y tiene un buen rendimiento interactivo . La documentación es detallada y amigable. Es muy recomendable.

defecto

  • Los principiantes pueden encontrar Echarts difíciles de configurar y requieren costos de aprendizaje adicionales .

  • La personalización de Echarts puede hacer que el código se vuelva detallado , lo que aumenta la carga de trabajo y el tiempo de desarrollo.

  • En algunos casos, los gráficos electrónicos pueden ser lentos al representar grandes conjuntos de datos, lo que requiere otras optimizaciones para mejorar el rendimiento.

Echarts Nativos+TS

Los documentos y funciones oficiales de echats nativos son más completos que echarts-for-react,

Pero echarts-for-react es más amigable para reaccionar y más fácil de usar.

 

ListChart.tsx

import React, { useEffect, useRef, useState } from 'react';
import { List, Button} from 'antd';
import { LineChartOutlined, BarChartOutlined } from '@ant-design/icons';
import { ProCard } from '@ant-design/pro-components';
import * as echarts from "echarts";

import './ListChart.css'
import { LIST_NAME, CHART_OPTION,resize,findSubstrIdx } from '../utils/ListChartUtil';
import { ListChartStatus } from "./ListChartStatus";

const ListChart: React.FC<ListChartStatus> = ({ urlPre, proc_datas, board_name }) => {

    const chartRef = useRef<HTMLDivElement>(null); 
    const [selectedIdx, setselectedIdx] = useState<number>(0);
    const [isLine, setIsLine] = React.useState<boolean>(true);
    const proc_list = new Array(proc_datas.length).fill(null).map((val, i) => {
        return proc_datas[i].proc_name;
    });
    let chart: any = null;
    
    useEffect(() => {
        if (chartRef.current) {
            chart = echarts.init(chartRef.current);
            const {option,urlSufs}=getOption(proc_datas[selectedIdx])
            chart.setOption(option);
            resize(chart);
            chart.on('click', isLine ? 'xAxis' : 'series', function (params: any) {
                const clickDate= isLine ? params.value:params.seriesName;
                window.open(urlPre + '/' + urlSufs[findSubstrIdx(urlSufs, clickDate)] + '/index.html', '_blank');
            });
        }  
    }, [chartRef, selectedIdx, isLine]);

    const initDate_UrlSufs=(proc_data:any)=>{
        let urlSufs: string[] = [];
        let dates: string[] = [];
        proc_data.date_list.forEach((date: string, idx: number) => {
            urlSufs.push(date + '/' + proc_data.report_id_list[idx]);
            dates.push(date.substring(5));
        });
        return {dates,urlSufs};
    }
    const  getBarDates=(series:any)=>{
        const barDatas: any = [];
        LIST_NAME.forEach((_, idx) => {
            if (series[idx] && series[idx].length) {
                barDatas.push([LIST_NAME[idx], ...series[idx]])
            }
        })
        return barDatas;
    }
    const getOption=(proc_data:any)=>{
        const {dates,urlSufs}=initDate_UrlSufs(proc_data)
        const series = [proc_data.avg_list, proc_data.sigma3_up_list, proc_data.sigma3_up_target_list, proc_data.sigma3_down_list, proc_data.max_list, proc_data.min_list]
        let option = {  
            tooltip: CHART_OPTION.tooltip,
            legend: CHART_OPTION.legend,
            toolbox: CHART_OPTION.toolbox,
            yAxis: CHART_OPTION.yAxis,
            title: {
                text: proc_data ? board_name + ":" + proc_data.proc_name : board_name,
                subtext: "点击日期可跳转到详情报告",
            },
            xAxis: {
                type: 'category', // 类型为分类轴
                triggerEvent: true, // 是否触发鼠标事件
                data: isLine ? proc_data.date_list.map((date: string, idx: number) => {
                    return dates[idx]
                }) : null,
            },
            series: isLine ? LIST_NAME.map((_, idx) => {
                if (series[idx] && series[idx].length) {
                    return {
                        name: LIST_NAME[idx],
                        type: 'line',
                        data: series[idx],
                        emphasis: {
                            focus: 'series'
                        },
                    }
                }
            }) : dates.map((_, idx) => {
                return {
                    name: dates[idx],
                    type: 'bar',
                    event: 'click',
                    emphasis: {
                        focus: 'series'
                    },
                }
            }),

            dataset: isLine ? null : {
                source: [
                    ['pref', ...dates],
                    ...getBarDates(series)
                ]
            },
        };
        return {option,urlSufs};
    }
    return (<ProCard layout="center"  className="procard" ghost>
        <ProCard colSpan={6} ghost >
            <List
                size="small"
                bordered
                className='procard-list'
                dataSource={proc_list}
                renderItem={(item, index) => <List.Item key={Math.random()} className={selectedIdx === index ? 'selected' :undefined }
                    onClick={() => setselectedIdx(index)}>
                    {item}</List.Item>}
            />
        </ProCard>
        <ProCard colSpan={18} ghost >
            <div className="procard-button" >
                <Button className="ant-btn" icon={<LineChartOutlined />} onClick={() => setIsLine(true)} ></Button>
                <Button className="ant-btn" icon={<BarChartOutlined />} onClick={() => setIsLine(false)}></Button>
            </div>
            <div key={`divChart${Math.random()}`}
                ref={chartRef}
                className='chart'
                style={
   
   {
                    flex: 2,
                    flexDirection:"column",
                    height: "40vh",
                    paddingLeft: "1vw",
                }}
            ></div>
        </ProCard>
    </ProCard>
    )
}
export default ListChart;

ListChart.css

.procard {
    display: flex;
    padding-top: 10px;
}
.procard-list {
    overflow-y: scroll;
    height: 45vh;
}
.selected {
    background-color: #e6f7ff !important;
  }
.procard-button{
    display: flex;
    justify-content: flex-end;
    padding-right: 7vw;
}

ListChartUtil.tsx

​
export const LIST_NAME = ['avg', '3∑-up', '3∑-up-target', '3∑-down', 'max', 'min']

export const CHART_OPTION = {
  tooltip: {
    trigger: 'axis',
    axisPointer: {
      type: "shadow"
    },
  },
  legend: {
    left: 'center',
    width: '35%',
    selected: {
      'min': false,
      '3∑-down': false,
    }
  },
  toolbox: {
    show: true,
    feature: {
      dataZoom: {
        yAxisIndex: 'none'
      },
      dataView: { readOnly: false },
      //   magicType: { type: ['line'] },
      restore: {},
      saveAsImage: {}
    },
    right: "10%"
  },
  yAxis: {
    type: 'value',
    axisLabel: {
      formatter: '{value}  '
    }
  },
}
const dom: any = [];  //所有echarts图表的数组
/**
 * 当屏幕尺寸变化时,循环数组里的每一项调用resize方法来实现自适应。
 * @param {*} eDom 
 */
export function resize(eDom: any) {
  dom.push(eDom);
  window.onresize = () => {
    dom.forEach((it: any) => {
      it.resize();
    })
  };
}

export function findSubstrIdx(arr: string[], substr: string): number {
  for (let i = 0; i < arr.length; i++) {
    if (arr[i].indexOf(substr) !== -1) {
      return i;
    }
  }
  return -1;
}

​

ReactECCharts

Los ganchos de reacción encapsulan los componentes de Echarts5 (ts/js)
 

React+TypeScript encapsula ECharts_react typescript echart_KzXuanCn's Blog-CSDN Blog

GitHub - hustcc/echarts-for-react: ⛳️ Componentes de Apache ECharts para el envoltorio de React. Un envoltorio de React simple para los echarts de Apache.

Comparado

D3

es una biblioteca de JavaScript basada en documentos basada en datos que es altamente flexible y personalizable , pero requiere más esfuerzo de codificación.

recargas

Es una biblioteca basada en la encapsulación de React, que utiliza la poderosa función de dibujo de D3, lo que facilita el uso de React para la visualización de datos .

ventaja

  • Recharts es fácil de usar porque tiene pocas opciones de personalización.

  • Se integra con los métodos de ciclo de vida de React, lo que facilita la adición a las aplicaciones de React y es compatible con los administradores de estado de Redux.

  • Ligero con menos impacto en la memoria y la CPU.

  • Admite múltiples estilos, colores personalizados y animaciones.

defecto

  • No es compatible con todos los tipos de gráficos, no hay gran variedad de Echarts.

  • Menos funciones que Echarts

En resumen, si necesitas diseñar gráficos muy personalizados y tienes suficiente experiencia en desarrollo, puede que te resulte más cómodo utilizar Echarts. Por otro lado, Recharts puede ser más adecuado para tareas de visualización de datos rápidas y fáciles y fácil de integrar en las aplicaciones React.

Supongo que te gusta

Origin blog.csdn.net/qq_28838891/article/details/131063427
Recomendado
Clasificación