import { useTheme } from '@mui/material'; import type { Axis } from '@visx/visx'; import { isNil } from 'ramda'; import { useMemo } from 'react'; import { formatMetricValueWithUnit, getUnits } from '../timeSeries'; import { commonTickLabelProps } from '../utils'; import type { Data, LabelProps } from './models'; interface AxisYData { displayUnit: boolean; numTicks?: number; tickFormat: (value: unknown) => string; tickLabelProps: Axis.TickLabelProps; unit: string; } interface AxisRightData extends AxisYData { display: boolean; } interface AxisY { axisLeft: AxisYData; axisRight: AxisRightData; } interface Props { data: Omit; graphHeight?: number; graphWidth?: number; isHorizontal: boolean; } const useAxisY = ({ data, graphHeight, graphWidth, isHorizontal }: Props): AxisY => { const theme = useTheme(); const { lines } = data; const [firstUnit, secondUnit] = getUnits(lines); const numTicks = isHorizontal ? graphHeight && Math.ceil(graphHeight / 30) : graphWidth && Math.ceil(graphWidth / 60); const displayAxisRight = data?.axisYRight?.display || Boolean(secondUnit); const displayUnitAxisRight = data?.axisYRight?.displayUnit || Boolean(secondUnit); const displayUnitAxisLeft = data?.axisYLeft?.displayUnit || true; const leftUnit = useMemo( () => data.axisYLeft?.unit ?? firstUnit, [data.axisYLeft?.unit, firstUnit] ); const rightUnit = useMemo( () => data.axisYRight?.unit ?? secondUnit, [data.axisYRight?.unit, secondUnit] ); const formatTick = ({ unit }: { unit: string }) => (value: unknown): string => { if (isNil(value)) { return ''; } return formatMetricValueWithUnit({ base: data.baseAxis, unit, value: value as number }) as string; }; const labelProps = ({ textAnchor, ...rest }: LabelProps): Record => ({ ...commonTickLabelProps, textAnchor, ...rest }); const tickLabelPropsAxisLeft = (): Record => labelProps({ dx: theme.spacing(-1), dy: theme.spacing(0.5), textAnchor: 'end' }); const tickLabelPropsAxisRight = (): Record => labelProps({ dx: theme.spacing(0.5), dy: theme.spacing(0.5), textAnchor: 'start' }); return { axisLeft: { displayUnit: displayUnitAxisLeft, numTicks, tickFormat: formatTick({ unit: leftUnit }), tickLabelProps: tickLabelPropsAxisLeft, unit: leftUnit }, axisRight: { display: displayAxisRight, displayUnit: displayUnitAxisRight, numTicks, tickFormat: formatTick({ unit: rightUnit }), tickLabelProps: tickLabelPropsAxisRight, unit: rightUnit } }; }; export default useAxisY;