import React, { memo, useCallback, useMemo } from 'react'; import { Area, Bar, CartesianGrid, ComposedChart, Label, Line, ReferenceLine, ResponsiveContainer, Tooltip, XAxis, YAxis } from 'recharts'; import type { Margin } from 'recharts/types/util/types'; import { useTheme } from '@mui/material/styles'; import { useEmpty, useTick, ChartTooltip, formatterData, setDomainCalc, formatterId, fixChartsClasses } from '../../utils'; import type { ChartTooltipProps } from '../../utils'; import type { Theme } from '../@styles/theme-provider'; export interface ChartComposedProps { data?: Record[]; tooltip?: boolean; tooltipPostfix?: string; height?: number; dots?: boolean; domainMax?: number; domainCalc?: boolean; tickCountY?: number; YAxisUnit?: string; dataKeyX?: ChartTooltipProps['format']; dataXFormat?: ChartTooltipProps['dataXFormat']; dataYFormat?: ChartTooltipProps['dataYFormat']; tooltipFormatter?: ChartTooltipProps['tooltipFormatter']; chartConfig?: ChartTooltipProps['config'] & { type: string; yAxisSecond?: boolean; }[]; isSecondYAxis?: boolean; secondYAxisHide: boolean; secondYAxisDomainMax: number; secondYAxisDomainCalc: boolean; secondYAxisDomainCalcMultiplier?: number; referenceValue?: number; referenceTitle?: string; referenceWidth?: number; chartMargin?: Margin; tooltipProps?: Partial; } const ChartComposed = (props: ChartComposedProps) => { const theme = useTheme(); const empty = useEmpty(); const { data = [], chartConfig = [empty], domainMax = 100, dots, height, tooltip, tooltipPostfix, domainCalc = false, tickCountY, dataKeyX = 'date', dataXFormat = 'month', dataYFormat = '', tooltipFormatter, chartMargin = { left: -24, right: 6 }, isSecondYAxis = false, secondYAxisHide = false, secondYAxisDomainMax, secondYAxisDomainCalc, secondYAxisDomainCalcMultiplier = 1, referenceValue, referenceTitle, referenceWidth, YAxisUnit, tooltipProps } = props; const classes = fixChartsClasses(); const tick = useTick(); const newConfig = useMemo(() => [...chartConfig].reverse(), [chartConfig]); const formatterX = useCallback( (value: string) => formatterData(value, dataKeyX, dataXFormat), [dataKeyX, dataXFormat] ); const formatterY = useCallback( (value: string) => formatterData(value, '', dataYFormat), [dataYFormat] ); const setDomain = useCallback( (dataMax: number | undefined) => setDomainCalc(dataMax, domainCalc, domainMax), [domainMax, domainCalc] ); const setDomainSecondYAxis = useCallback( (dataMax: number | undefined) => setDomainCalc( dataMax, secondYAxisDomainCalc, secondYAxisDomainMax, secondYAxisDomainCalcMultiplier ), [secondYAxisDomainMax, secondYAxisDomainCalc, secondYAxisDomainCalcMultiplier] ); const ReferenceLabel = useCallback( ({ viewBox }) => { const xRect = viewBox.x; const yRect = viewBox.y - 9; const xText = xRect + 4; const yText = yRect + 13; return ( {referenceTitle} ); }, [referenceTitle, referenceWidth, theme] ); return ( {newConfig?.map((entry, index) => ( ))} {isSecondYAxis && ( )} {tooltip && ( } {...tooltipProps} /> )} {newConfig?.map((entry, index) => { if (entry.show) { if (entry.type === 'area') { return ( ); } if (entry.type === 'line') { return ( ); } if (entry.type === 'bar') { return ( ); } return null; } return null; })} {referenceValue && ( )} ); }; ChartComposed.defaultProps = { data: [], chartConfig: [], tooltip: true, height: 325, dots: false, domainCalc: false, domainMax: 100, tickCountY: 10, isSecondYAxis: false, secondYAxisHide: false, secondYAxisDomainMax: 100, secondYAxisDomainCalc: false, secondYAxisDomainCalcMultiplier: 1, chartMargin: { left: -24, right: 6 }, dataKeyX: 'date', dataXFormat: 'month', dataYFormat: '', referenceValue: 5 }; const m = memo(ChartComposed); export { m as ChartComposed };