refactor(dashboard): the chart component is now cleaned up and easier to extend
This commit is contained in:
81
apps/dashboard/src/components/report-chart/common/axis.tsx
Normal file
81
apps/dashboard/src/components/report-chart/common/axis.tsx
Normal file
@@ -0,0 +1,81 @@
|
||||
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;
|
||||
};
|
||||
Reference in New Issue
Block a user