UNPKG

@nafr/echo-ui

Version:

A UI library born for WAA

54 lines (53 loc) 2.37 kB
import { jsx as _jsx } from "react/jsx-runtime"; import { forwardRef, useEffect, useImperativeHandle, useRef, useState } from 'react'; import { scaleLinear, select, axisRight, axisBottom } from 'd3'; import { cn } from '../../../lib/utils'; import { useStyle } from './styles'; import { MAX, MIN, TICKS, TICK_SIZE } from './constants'; export const Axis = forwardRef((props, ref) => { const { min = MIN, max = MAX, ticks = TICKS, tickSize = TICK_SIZE, vertical = false, relatedRef, ...restProps } = props; useImperativeHandle(ref, () => svgRef.current); const [width, setWidth] = useState(0); const [height, setHeight] = useState(0); const svgRef = useRef(null); useEffect(() => { initAxis(); }, [min, max, tickSize, vertical, ticks, width, height, relatedRef]); const initAxis = () => { if (svgRef.current === null) return; const element = svgRef.current; if (relatedRef?.current) { setWidth(relatedRef.current.clientWidth); setHeight(relatedRef.current.clientHeight); } else { const { height, width } = element.getBoundingClientRect(); setWidth(width); setHeight(height); } // Clear previous axis select(element).selectAll('*').remove(); // Set up scales and axes const yScale = scaleLinear().domain([min, max]).range([height, 0]); const yAxis = axisRight(yScale).ticks(ticks).tickSize(tickSize); const xScale = scaleLinear().domain([min, max]).range([0, width]); const xAxis = axisBottom(xScale).ticks(ticks).tickSize(tickSize); const svg = select(svgRef.current); let axisGroup; if (vertical) axisGroup = svg.append('g').classed('y-axis', true).call(yAxis); else axisGroup = svg.append('g').classed('x-axis', true).call(xAxis); // Positioning axis if (!vertical) axisGroup.attr('transform', `translate(0,${height})`); // Remove axis line svg.select('.domain').style('display', 'none'); }; return (_jsx("svg", { ...restProps, ref: svgRef, className: cn(useStyle({ vertical }), restProps.className), style: { ...restProps.style, width: vertical ? 20 : width, height: vertical ? height : 20, } })); });