import type { SVGAttributes } from 'react'; import { forwardRef } from 'react'; import type { UseLinearPrimaryTicksResult } from 'react-d3-utils'; type AxisPosition = 'top' | 'bottom' | 'left' | 'right'; interface BaseD3AxisProps { tickLength?: number; axisPosition: AxisPosition; } type PrimaryGridElementProps = Pick< SVGAttributes, 'stroke' | 'strokeOpacity' | 'strokeDasharray' >; type SecondaryGridElementProps = PrimaryGridElementProps & { secondaryGridDensity?: number; }; interface D3AxisProps extends BaseD3AxisProps, Pick, 'transform' | 'children' | 'className'>, UseLinearPrimaryTicksResult { gridSize?: number; primaryGridProps?: PrimaryGridElementProps; secondaryGridProps?: SecondaryGridElementProps; showGrid?: boolean; } interface TicketsProps extends UseLinearPrimaryTicksResult, BaseD3AxisProps {} interface BaseLineProps extends Pick, BaseD3AxisProps {} interface GridProps extends UseLinearPrimaryTicksResult { axisPosition: AxisPosition; gridSize?: number; gridProps?: T; } function isVerticalAxis(axisPosition: AxisPosition) { return ['left', 'right'].includes(axisPosition); } function BaseLine(props: BaseLineProps) { const { axisPosition, tickLength = 6, scale } = props; const [x1, x2] = scale.range(); const sign = ['left', 'top'].includes(axisPosition) ? -1 : 1; let path = `M${x2},${sign * tickLength} V0 H${x1} V${sign * tickLength}`; if (isVerticalAxis(axisPosition)) { path = `M${sign * tickLength},${x2} H0 V${x1} H${sign * tickLength}`; } return ; } function Tickets(props: TicketsProps) { const { ticks, tickLength = 6, axisPosition } = props; if (!Array.isArray(ticks) || ticks.length === 0) return null; const isVertical = isVerticalAxis(axisPosition); const positionSign = axisPosition === 'left' || axisPosition === 'top' ? -1 : 1; return ticks.map(({ label, position }) => { return ( {label} ); }); } function getLinePosition(position: any, axisPosition: any, gridSize: any) { if (['top', 'bottom'].includes(axisPosition)) { return { x1: position, x2: position, y1: axisPosition === 'top' ? gridSize : -gridSize, y2: 0, }; } return { x1: axisPosition === 'left' ? gridSize : -gridSize, x2: 0, y1: position, y2: position, }; } function PrimaryGrid(props: GridProps) { const { ticks, axisPosition, gridSize, gridProps = {} } = props; return ticks.map(({ position }) => { return ( ); }); } function SecondaryGrid(props: GridProps) { const { ticks, axisPosition, scale, gridSize, gridProps = {} } = props; const { secondaryGridDensity = 5, ...otherGridProps } = gridProps; const secondaryTickets = scale?.ticks(ticks.length * secondaryGridDensity); return secondaryTickets?.map((tick) => { const position = scale?.(tick); if (!position) return null; return ( ); }); } export const D3Axis = forwardRef( (props, ref) => { const { ticks, scale, axisPosition, gridSize, children, primaryGridProps, secondaryGridProps, tickLength, showGrid = false, ...otherProps } = props; const isVertical = isVerticalAxis(axisPosition); return ( {children} {showGrid && ( )} ); }, );