import React, { useCallback, useMemo, ReactNode } from 'react'; import Typography from '@mui/material/Typography'; import Grid from '@mui/material/Grid'; import Box from '@mui/material/Box'; import { AreaProps } from 'recharts'; import type { TooltipProps as BaseTooltipProps } from 'recharts'; import { formatterData, formattedLabel } from '../formatters/formatters'; import createClasses from './styles'; import type { ValueType, NameType } from './index'; export type RechartsTooltipProps = BaseTooltipProps; export type TooltipFormatterType = (item: PayloadItem, index: number) => PayloadItem; type ArrayElement = A extends readonly (infer T)[] ? T : never; export type PayloadItem = ArrayElement; export interface ChartTooltipProps extends RechartsTooltipProps { active?: boolean; label?: string; format?: string; dataXFormat?: string; dataYFormat?: string; tooltipFormatter?: TooltipFormatterType; valuePostfix?: string; disableReverse?: boolean; config: { id: string; show: boolean; name?: string; color?: string; disableStroke?: boolean; areaProps?: Omit; stopOpacity?: [number, number]; }[]; withTitleValue?: boolean; withTitle?: string; } const ChartTooltip = (props: ChartTooltipProps) => { const { payload, active, label, format, dataXFormat, dataYFormat, tooltipFormatter, labelFormatter, config, valuePostfix, disableReverse = false, withTitleValue, withTitle } = props; const showTooltip = useMemo(() => active && payload && Array.isArray(payload), [active, payload]); const classes = createClasses(); const labelFormat = useMemo(() => { return labelFormatter && payload ? labelFormatter(label, payload) : formattedLabel(label || '', format, dataXFormat); }, [format, dataXFormat, label, labelFormatter, payload]); const valueFormat = useCallback(value => formatterData(value, '', dataYFormat), [dataYFormat]); const findNamebyId = useCallback( (key: string) => config?.find(({ id }) => id === key)?.name, [config] ); const payloadItems = useMemo( () => (disableReverse ? payload : payload?.slice().reverse())?.map((value, index) => tooltipFormatter ? tooltipFormatter(value, index) : value ), [disableReverse, payload, tooltipFormatter] ); const titleValue = payload?.reduce((acc, cur) => { return acc + (cur.value as number); }, 0); if (showTooltip) { return ( {withTitle ? ( <> {withTitleValue ? `${withTitle} (${titleValue})` : withTitle} {labelFormat} ) : ( {withTitleValue ? `${labelFormat} (${titleValue})` : labelFormat} )} {payloadItems?.map((item, index) => ( {item.name && findNamebyId(item.name)}: {valueFormat(item.value)} {valuePostfix} ))} ); } return null; }; ChartTooltip.defaultProps = { payload: [], active: false, label: '', format: 'date', dataXFormat: '', dataYFormat: '', config: [], valuePostfix: '' }; export default ChartTooltip;