react-plot
Version:
Library of React components to render SVG 2D plots.
96 lines • 3.63 kB
JavaScript
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