frontend/libs/canvasSpreadsheet/src/lib/components/Charts/lineChart/LineChart.tsx (75 lines of code) (raw):

import { EChartsOption } from 'echarts'; import ReactECharts from 'echarts-for-react'; import { useEffect, useState } from 'react'; import { AppTheme, ChartsData } from '@frontend/common'; import { ChartConfig } from '../types'; import { getColor, getOption } from './chartOptions'; type Props = { chartConfig: ChartConfig; chartData: ChartsData; theme: AppTheme; zoom: number; }; export function LineChart({ chartConfig, chartData, theme, zoom }: Props) { const [chartOptions, setChartOptions] = useState<EChartsOption>( getOption(theme, zoom) ); useEffect(() => { const data = chartData[chartConfig.tableName]; if (data) { const legendData: string[] = []; const xAxisData: string[] = []; const seriesData: EChartsOption['series'] = []; for (const [key, item] of Object.entries(data)) { legendData.push(key); for (let i = 0; i < item.length; i++) { const points = item[i].points; for (const [pointKey] of Object.entries(points)) { xAxisData.push(pointKey); } } } legendData.sort((a, b) => a.localeCompare(b)); xAxisData.sort((a, b) => new Date(a).getTime() - new Date(b).getTime()); for (const [key, item] of Object.entries(data)) { for (let i = 0; i < item.length; i++) { const points = item[i].points; const seriesDataArray = new Array(xAxisData.length).fill(null); for (const [pointKey, pointValue] of Object.entries(points)) { const index = xAxisData.indexOf(pointKey); if (index === -1 || index > seriesDataArray.length - 1) continue; seriesDataArray[index] = pointValue; } const legendIndex = legendData.indexOf(key); seriesData.push({ name: key, type: 'line', data: seriesDataArray, connectNulls: true, color: getColor(legendIndex), }); } } const optionsWithData = getOption( theme, zoom, legendData, xAxisData, seriesData ); setChartOptions(optionsWithData); return; } const options = getOption(theme, zoom); setChartOptions(options); }, [chartConfig, chartData, theme, zoom]); return ( <ReactECharts lazyUpdate={true} notMerge={true} option={chartOptions} opts={{ width: chartConfig.width, height: chartConfig.height, }} style={{ height: '100%' }} /> ); }