import type { ScaleLinear, ScaleTime } from 'd3-scale'; import { useAtomValue } from 'jotai'; import { type MutableRefObject, useEffect, useState } from 'react'; import useAxisY from '../../../common/Axes/useAxisY'; import { getTimeValue } from '../../../common/timeSeries'; import type { Line, TimeValue } from '../../../common/timeSeries/models'; import { computeGElementMarginLeft, computPixelsToShiftMouse } from '../../../common/utils'; import { mousePositionAtom } from '../interactionWithGraphAtoms'; interface AnchorPointResult { positionX?: number; positionY?: number; tickAxisBottom: Date | null; tickAxisLeft: string | null; tickAxisRight: string | null; guidingLinesRef: MutableRefObject; } interface Props { baseAxis?: number; leftScale?: ScaleLinear; lines?: Array; rightScale?: ScaleLinear; timeSeries: Array; xScale: ScaleTime; maxLeftAxisCharacters: number; hasUnit?: boolean; } const useTickGraph = ({ timeSeries, xScale, leftScale, rightScale, lines = [], baseAxis = 1000, maxLeftAxisCharacters, hasUnit }: Props): AnchorPointResult => { const [tickAxisBottom, setTickAxisBottom] = useState(null); const [tickAxisLeft, setTickAxisLeft] = useState(null); const [tickAxisRight, setTickAxisRight] = useState(null); // @ts-expect-error - suppressing pre-existing type mismatch const { axisRight, axisLeft } = useAxisY({ data: { baseAxis, lines } }); const mousePosition = useAtomValue(mousePositionAtom); const positionX = mousePosition ? mousePosition[0] - computeGElementMarginLeft(maxLeftAxisCharacters) : undefined; const positionY = mousePosition ? mousePosition[1] - (hasUnit ? 29 : 4) : undefined; useEffect(() => { if (!mousePosition) { setTickAxisBottom(null); setTickAxisLeft(null); setTickAxisRight(null); return; } const pixelToShift = computPixelsToShiftMouse(xScale); const mousePositionTimeTick = mousePosition ? getTimeValue({ marginLeft: computeGElementMarginLeft(maxLeftAxisCharacters), timeSeries, x: mousePosition[0] - pixelToShift, xScale })?.timeTick : 0; const timeTickValue = mousePosition ? new Date(mousePositionTimeTick || 0) : null; setTickAxisBottom(timeTickValue); const valueTickAxisLeft = leftScale?.invert(positionY ?? 0); const formattedTickAxisLeft = axisLeft?.tickFormat?.(valueTickAxisLeft); setTickAxisLeft(formattedTickAxisLeft); if (!axisRight.display) { setTickAxisRight(null); return; } const valueTickAxisRight = rightScale?.invert(positionY ?? 0); const formattedTickAxisRight = axisRight?.tickFormat?.(valueTickAxisRight); setTickAxisRight(formattedTickAxisRight); }, [mousePosition]); // @ts-expect-error - suppressing pre-existing type mismatch return { positionX, positionY, tickAxisBottom, tickAxisLeft, tickAxisRight }; }; export default useTickGraph;