82 lines
1.9 KiB
TypeScript
82 lines
1.9 KiB
TypeScript
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<number[]>([]);
|
|
|
|
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;
|
|
};
|