import { useRef, useState } from 'react'; import { useDebounceFn } from '@/hooks/useDebounceFn'; import { useFormatDateInterval } from '@/hooks/useFormatDateInterval'; import { useNumber } from '@/hooks/useNumerFormatter'; import { isNil } from 'ramda'; import type { AxisDomain } from 'recharts/types/util/types'; import type { IInterval } from '@openpanel/validation'; export const AXIS_FONT_PROPS = { fontSize: 8, className: 'font-mono', }; export function getYAxisWidth(value: string | undefined | null) { const charLength = AXIS_FONT_PROPS.fontSize * 0.6; if (isNil(value) || value.length === 0) { return charLength * 2; } return charLength * value.length + charLength; } export const useYAxisProps = ({ data, hide, }: { data: number[]; hide?: boolean; }) => { const [width, setWidth] = useState(24); const setWidthDebounced = useDebounceFn(setWidth, 100); const number = useNumber(); const ref = useRef([]); return { ...AXIS_FONT_PROPS, width: hide ? 0 : width, axisLine: false, tickLine: false, allowDecimals: false, tickFormatter: (value: number) => { const tick = number.short(value); const newWidth = getYAxisWidth(tick); ref.current.push(newWidth); setWidthDebounced(Math.max(...ref.current)); return tick; }, }; }; export const useXAxisProps = ( { interval = 'auto', hide, }: { interval?: IInterval | 'auto'; hide?: boolean; } = { hide: false, interval: 'auto', } ) => { const formatDate = useFormatDateInterval( interval === 'auto' ? 'day' : interval ); return { height: hide ? 0 : undefined, axisLine: false, dataKey: 'timestamp', scale: 'utc', domain: ['dataMin', 'dataMax'] as AxisDomain, tickFormatter: interval === 'auto' ? undefined : (m: string) => formatDate(new Date(m)), type: 'number' as const, tickLine: false, minTickGap: 20, ...AXIS_FONT_PROPS, } as const; };