UNPKG

react-plot

Version:

Library of React components to render SVG 2D plots.

96 lines 3.63 kB
import { jsx as _jsx } from "react/jsx-runtime"; import { extent } from 'd3-array'; import { area } from 'd3-shape'; import { memo, useEffect, useMemo } from 'react'; import { useLegend } from '../../contexts/legendContext.js'; import { usePlotContext, usePlotDispatchContext, } from '../../contexts/plotContext.js'; import { useIsSeriesVisible, useShift } from '../../hooks.js'; import { useId, validateAxis } from '../../utils.js'; function RangeSeriesInner(props) { const id = useId(props.id, 'series'); const [, legendDispatch] = useLegend(); const { colorScaler } = usePlotContext(); const { lineStyle = { fill: colorScaler(id), fillOpacity: 0.5 }, hidden, xAxis = 'x', yAxis = 'y', data, label, xShift: propsXShift = '0', yShift: propsYShift = '0', } = props; const { xShift, yShift } = useShift({ xAxis, yAxis, xShift: propsXShift, yShift: propsYShift, }); // Update plot context with data description const dispatch = usePlotDispatchContext(); useEffect(() => { const [xMin, xMax] = extent(data, (d) => d.x); const [y1Min, y1Max] = extent(data, (d) => d.y1); const [y2Min, y2Max] = extent(data, (d) => d.y2); const x = { min: xMin, max: xMax, shift: propsXShift, axisId: xAxis }; const y = { min: Math.min(y1Min, y2Min), max: Math.max(y1Max, y2Max), shift: propsYShift, axisId: yAxis, }; dispatch({ type: 'addSeries', payload: { id, x, y, label } }); // Delete information on unmount return () => dispatch({ type: 'removeSeries', payload: { id } }); }, [dispatch, id, data, xAxis, yAxis, label, propsXShift, propsYShift]); const isVisible = useIsSeriesVisible(id); useEffect(() => { if (!hidden) { legendDispatch({ type: 'ADD_LEGEND_LABEL', payload: { id, label, colorLine: lineStyle.stroke, range: { rangeColor: lineStyle.fill || 'none', }, }, }); return () => legendDispatch({ type: 'REMOVE_LEGEND_LABEL', payload: { id }, }); } return undefined; }, [label, legendDispatch, lineStyle.fill, lineStyle.stroke, id, hidden]); if (hidden) return null; const lineProps = { id, data, xAxis, yAxis, lineStyle, transform: `translate(${xShift},${yShift})`, }; return isVisible ? _jsx(RangeSeriesRender, { ...lineProps }) : null; } export const RangeSeries = memo(RangeSeriesInner); function RangeSeriesRender({ data, xAxis, yAxis, lineStyle, transform, }) { // Get scales from context const { axisContext } = usePlotContext(); const [xScale, yScale] = validateAxis(axisContext, xAxis, yAxis); // calculates the path to display const path = useMemo(() => { if (xScale === undefined || yScale === undefined) { return null; } // Calculate area from D3 const areaGenerator = area() .x((d) => xScale(d.x)) .y0((d) => yScale(d.y1)) .y1((d) => yScale(d.y2)); return areaGenerator(data); }, [data, xScale, yScale]); if (!path) return null; // default style const style = { strokeWidth: 2, ...lineStyle, }; return _jsx("path", { transform: transform, style: style, d: path, fill: "none" }); } //# sourceMappingURL=RangeSeries.js.map