import { defaultsDeep } from 'es-toolkit/compat'; import React from 'react'; import type { AxesConfigFn, ChartMargin, TimeChartData } from './types'; import { Resolution } from './types'; import useIsMobile from 'lib/hooks/useIsMobile'; import { ChartArea } from './parts/ChartArea'; import { ChartAxis } from './parts/ChartAxis'; import { ChartGridLine } from './parts/ChartGridLine'; import { ChartLine } from './parts/ChartLine'; import { ChartOverlay } from './parts/ChartOverlay'; import { ChartSelectionX } from './parts/ChartSelectionX'; import { ChartTooltip } from './parts/ChartTooltip'; import { getDateLabel } from './utils/getDateLabel'; import { useTimeChartController } from './utils/useTimeChartController'; export interface ChartProps { charts: TimeChartData; zoomRange?: [ Date, Date ]; onZoom: (range: [ Date, Date ]) => void; margin?: ChartMargin; noAnimation?: boolean; resolution?: Resolution; axesConfig?: AxesConfigFn; isEnlarged?: boolean; } const DEFAULT_CHART_MARGIN = { bottom: 20, left: 10, right: 20, top: 10 }; export const Chart = React.memo(({ isEnlarged, charts, onZoom, margin: marginProps, noAnimation, resolution, zoomRange, axesConfig: axesConfigProps, }: ChartProps) => { const isMobile = useIsMobile(); const overlayRef = React.useRef(null); const range = React.useMemo( () => zoomRange || [ charts[0].items[0].date, charts[0].items[charts[0].items.length - 1].date, ], [ zoomRange, charts ], ); const displayedCharts = React.useMemo(() => { return charts.map((chart) => ({ ...chart, items: chart.items .filter((item) => item.date >= range[0] && item.date <= range[1]) .map((item) => (item.dateLabel ? item : { ...item, dateLabel: getDateLabel(item.date, item.date_to, resolution), })), })); }, [ charts, range, resolution ]); const margin: ChartMargin = React.useMemo(() => ({ ...DEFAULT_CHART_MARGIN, ...marginProps }), [ marginProps ]); const axesConfig = React.useMemo(() => { return defaultsDeep(axesConfigProps?.({ isEnlarged, isMobile }), { x: { ticks: isEnlarged && !isMobile ? 8 : 4, }, y: { ticks: isEnlarged ? 6 : 3, nice: true, }, }); }, [ axesConfigProps, isEnlarged, isMobile ]); const { ref, rect, innerWidth, innerHeight, chartMargin, axes, } = useTimeChartController({ data: displayedCharts, margin, axesConfig, }); return ( { displayedCharts.map((chart) => { const id = `${ chart.id }-${ isEnlarged ? 'fullscreen' : 'small' }`; return ( { chart.charts.map((chartConfig) => { if (chartConfig.type === 'area') { return ( ); } return ( ); }) } ); }) } ); });