Add settings page for managing forecasting API key and URL via UI

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
jtricerolph 2026-07-20 14:37:36 +00:00
parent cae411eae7
commit 1c411e402e
19809 changed files with 1962608 additions and 97 deletions

668
frontend/node_modules/recharts/es6/cartesian/Area.js generated vendored Normal file
View file

@ -0,0 +1,668 @@
var _excluded = ["id"],
_excluded2 = ["activeDot", "animationBegin", "animationDuration", "animationEasing", "connectNulls", "dot", "fill", "fillOpacity", "hide", "isAnimationActive", "legendType", "stroke", "xAxisId", "yAxisId"];
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
import * as React from 'react';
import { PureComponent, useMemo, useRef } from 'react';
import { clsx } from 'clsx';
import { Layer } from '../container/Layer';
import { CartesianLabelListContextProvider, LabelListFromLabelProp } from '../component/LabelList';
import { Dots } from '../component/Dots';
import { interpolate, isNan, isNullish, isNumber, noop } from '../util/DataUtils';
import { getCateCoordinateOfLine, getNormalizedStackId, getTooltipNameProp, getValueByDataKey } from '../util/ChartUtils';
import { isClipDot } from '../util/ReactUtils';
import { ActivePoints } from '../component/ActivePoints';
import { SetTooltipEntrySettings } from '../state/SetTooltipEntrySettings';
import { GraphicalItemClipPath, useNeedsClip } from './GraphicalItemClipPath';
import { selectArea } from '../state/selectors/areaSelectors';
import { useIsPanorama } from '../context/PanoramaContext';
import { useCartesianChartLayout, useChartLayout } from '../context/chartLayoutContext';
import { useChartName } from '../state/selectors/selectors';
import { SetLegendPayload } from '../state/SetLegendPayload';
import { useAppSelector } from '../state/hooks';
import { AnimatedItems, useAnimationCallbacks } from '../animation/AnimatedItems';
import { matchAnimationItems, matchByIndex } from '../animation/matchBy';
import { useAnimationStartSnapshot } from '../animation/useAnimationStartSnapshot';
import { resolveDefaultProps } from '../util/resolveDefaultProps';
import { usePlotArea } from '../hooks';
import { RegisterGraphicalItemId } from '../context/RegisterGraphicalItemId';
import { SetCartesianGraphicalItem } from '../state/SetGraphicalItem';
import { svgPropertiesNoEvents } from '../util/svgPropertiesNoEvents';
import { getRadiusAndStrokeWidthFromDot } from '../util/getRadiusAndStrokeWidthFromDot';
import { svgPropertiesAndEvents } from '../util/svgPropertiesAndEvents';
import { Shape } from '../util/ActiveShapeUtils';
import { ZIndexLayer } from '../zIndex/ZIndexLayer';
import { DefaultZIndexes } from '../zIndex/DefaultZIndexes';
import { propsAreEqual } from '../util/propsAreEqual';
import { AreaRevealShape } from './AreaRevealShape';
/**
* @inline
*/
/**
* Our base value array has payload in it, and we expose it externally too.
*/
/**
* Internal props, combination of external props + defaultProps + private Recharts state
*/
/**
* External props, intended for end users to fill in
*/
var defaultAreaAnimateItems = (items, animationElapsedTime) => {
if (items == null) {
// First render: return items as-is, clip-path animation handles the reveal
return [];
}
if (animationElapsedTime === 1) {
return items.flatMap(item => item.status === 'removed' ? [] : [item.next]);
}
return items.flatMap(item => {
if (item.status === 'matched') {
return [_objectSpread(_objectSpread({}, item.next), {}, {
x: interpolate(item.prev.x, item.next.x, animationElapsedTime),
y: interpolate(item.prev.y, item.next.y, animationElapsedTime)
})];
}
if (item.status === 'added') {
/*
* Here we just return the final position without interpolating
* so that we can allow the default initial animation that is done by clipPath in AreaRevealShape.
* If you want your own custom animations then you may want to interpolate this one as well.
*/
return [item.next];
}
// removed: drop
return [];
});
};
export var defaultAreaProps = {
activeDot: true,
animationBegin: 0,
animationDuration: 1500,
animationEasing: 'ease',
animationMatchBy: matchByIndex,
animationInterpolateFn: defaultAreaAnimateItems,
connectNulls: false,
dot: false,
fill: '#3182bd',
fillOpacity: 0.6,
hide: false,
isAnimationActive: 'auto',
legendType: 'line',
stroke: '#3182bd',
strokeWidth: 1,
type: 'linear',
label: false,
shape: AreaRevealShape,
xAxisId: 0,
yAxisId: 0,
zIndex: DefaultZIndexes.area
};
/**
* Because of naming conflict, we are forced to ignore certain (valid) SVG attributes.
*/
function getLegendItemColor(stroke, fill) {
return stroke && stroke !== 'none' ? stroke : fill;
}
var computeLegendPayloadFromAreaData = props => {
var dataKey = props.dataKey,
name = props.name,
stroke = props.stroke,
fill = props.fill,
legendType = props.legendType,
hide = props.hide;
return [{
inactive: hide,
dataKey,
type: legendType,
color: getLegendItemColor(stroke, fill),
value: getTooltipNameProp(name, dataKey),
payload: props
}];
};
var SetAreaTooltipEntrySettings = /*#__PURE__*/React.memo(_ref => {
var dataKey = _ref.dataKey,
data = _ref.data,
stroke = _ref.stroke,
strokeWidth = _ref.strokeWidth,
fill = _ref.fill,
name = _ref.name,
hide = _ref.hide,
unit = _ref.unit,
formatter = _ref.formatter,
tooltipType = _ref.tooltipType,
id = _ref.id;
var tooltipEntrySettings = {
dataDefinedOnItem: data,
getPosition: noop,
settings: {
stroke,
strokeWidth,
fill,
dataKey,
nameKey: undefined,
name: getTooltipNameProp(name, dataKey),
hide,
type: tooltipType,
color: getLegendItemColor(stroke, fill),
unit,
formatter,
graphicalItemId: id
}
};
return /*#__PURE__*/React.createElement(SetTooltipEntrySettings, {
tooltipEntrySettings: tooltipEntrySettings
});
});
function AreaDotsWrapper(_ref2) {
var clipPathId = _ref2.clipPathId,
points = _ref2.points,
props = _ref2.props;
var needClip = props.needClip,
dot = props.dot,
dataKey = props.dataKey;
var areaProps = svgPropertiesNoEvents(props);
return /*#__PURE__*/React.createElement(Dots, {
points: points,
dot: dot,
className: "recharts-area-dots",
dotClassName: "recharts-area-dot",
dataKey: dataKey,
baseProps: areaProps,
needClip: needClip,
clipPathId: clipPathId
});
}
function AreaLabelListProvider(_ref3) {
var showLabels = _ref3.showLabels,
children = _ref3.children,
points = _ref3.points;
var labelListEntries = points.map(point => {
var _point$x, _point$y;
var viewBox = {
x: (_point$x = point.x) !== null && _point$x !== void 0 ? _point$x : 0,
y: (_point$y = point.y) !== null && _point$y !== void 0 ? _point$y : 0,
width: 0,
lowerWidth: 0,
upperWidth: 0,
height: 0
};
return _objectSpread(_objectSpread({}, viewBox), {}, {
value: point.value,
payload: point.payload,
parentViewBox: undefined,
viewBox,
fill: undefined
});
});
return /*#__PURE__*/React.createElement(CartesianLabelListContextProvider, {
value: showLabels ? labelListEntries : undefined
}, children);
}
function StaticArea(_ref4) {
var points = _ref4.points,
baseLine = _ref4.baseLine,
needClip = _ref4.needClip,
clipPathId = _ref4.clipPathId,
props = _ref4.props,
animationElapsedTime = _ref4.animationElapsedTime,
isAnimating = _ref4.isAnimating,
isEntrance = _ref4.isEntrance;
var layout = props.layout,
type = props.type,
stroke = props.stroke,
connectNulls = props.connectNulls,
isRange = props.isRange,
shape = props.shape;
var id = props.id,
propsWithoutId = _objectWithoutProperties(props, _excluded);
var propsWithEvents = svgPropertiesAndEvents(propsWithoutId);
var curveProps = _objectSpread(_objectSpread({}, propsWithEvents), {}, {
id,
points,
connectNulls,
type,
baseLine,
layout,
stroke,
isRange,
animationElapsedTime,
isAnimating,
isEntrance
});
return /*#__PURE__*/React.createElement(React.Fragment, null, (points === null || points === void 0 ? void 0 : points.length) > 1 && /*#__PURE__*/React.createElement(Layer, {
clipPath: needClip ? "url(#clipPath-".concat(clipPathId, ")") : undefined
}, /*#__PURE__*/React.createElement(Shape, {
option: shape,
DefaultShape: defaultAreaProps.shape,
shapeProps: curveProps
})), /*#__PURE__*/React.createElement(AreaDotsWrapper, {
points: points,
props: propsWithoutId,
clipPathId: clipPathId
}));
}
function interpolateScalarBaseLine(baseLine, prevBaseLine, animationElapsedTime) {
if (isNumber(baseLine)) {
var previousNumberBaseLine = isNumber(prevBaseLine) ? prevBaseLine : undefined;
return interpolate(previousNumberBaseLine, baseLine, animationElapsedTime);
}
if (isNullish(baseLine) || isNan(baseLine)) {
var _previousNumberBaseLine = isNumber(prevBaseLine) ? prevBaseLine : undefined;
return interpolate(_previousNumberBaseLine, 0, animationElapsedTime);
}
return baseLine;
}
function AreaWithAnimation(_ref5) {
var needClip = _ref5.needClip,
clipPathId = _ref5.clipPathId,
props = _ref5.props,
previousPointsRef = _ref5.previousPointsRef,
previousBaselineRef = _ref5.previousBaselineRef;
var points = props.points,
baseLine = props.baseLine,
isAnimationActive = props.isAnimationActive,
animationBegin = props.animationBegin,
animationDuration = props.animationDuration,
animationEasing = props.animationEasing,
animationMatchBy = props.animationMatchBy,
animationInterpolateFn = props.animationInterpolateFn;
var animationInput = useMemo(() => ({
points,
baseLine
}), [points, baseLine]);
var baseLineAnimationState = useAnimationStartSnapshot(animationInput, previousBaselineRef);
var layout = useCartesianChartLayout();
var _useAnimationCallback = useAnimationCallbacks(props.onAnimationStart, props.onAnimationEnd),
isAnimating = _useAnimationCallback.isAnimating,
handleAnimationStart = _useAnimationCallback.handleAnimationStart,
handleAnimationEnd = _useAnimationCallback.handleAnimationEnd;
var prevBaseLine = baseLineAnimationState.startValue;
if (layout == null) {
return null;
}
var baseLineAnimationItems;
if (Array.isArray(baseLine) && Array.isArray(prevBaseLine)) {
baseLineAnimationItems = matchAnimationItems(prevBaseLine, baseLine, animationMatchBy);
} else if (Array.isArray(baseLine)) {
baseLineAnimationItems = matchAnimationItems(null, baseLine, animationMatchBy);
} else {
baseLineAnimationItems = null;
}
return /*#__PURE__*/React.createElement(AnimatedItems, {
animationInput: animationInput,
animationIdPrefix: "recharts-area-",
items: points,
previousItemsRef: previousPointsRef,
isAnimationActive: isAnimationActive,
animationBegin: animationBegin,
animationDuration: animationDuration,
animationEasing: animationEasing,
onAnimationStart: handleAnimationStart,
onAnimationEnd: handleAnimationEnd,
animationInterpolateFn: animationInterpolateFn,
animationMatchBy: animationMatchBy,
layout: layout
}, (stepPoints, animationElapsedTime, isEntrance) => {
var stepBaseLine;
if (animationElapsedTime === 1) {
stepBaseLine = baseLine;
} else if (Array.isArray(baseLine)) {
stepBaseLine = animationInterpolateFn(baseLineAnimationItems, animationElapsedTime, layout);
} else {
stepBaseLine = isEntrance ? baseLine : interpolateScalarBaseLine(baseLine, prevBaseLine, animationElapsedTime);
}
baseLineAnimationState.syncStepValue(stepBaseLine, animationElapsedTime);
return /*#__PURE__*/React.createElement(AreaLabelListProvider, {
showLabels: !isAnimating,
points: points
}, props.children, /*#__PURE__*/React.createElement(StaticArea, {
points: stepPoints,
baseLine: stepBaseLine,
needClip: needClip,
clipPathId: clipPathId,
props: props,
animationElapsedTime: animationElapsedTime,
isAnimating: isAnimating || animationElapsedTime < 1,
isEntrance: isEntrance
}), /*#__PURE__*/React.createElement(LabelListFromLabelProp, {
label: props.label
}));
});
}
/*
* This component decides if the area should be animated or not.
* It also holds the state of the animation.
*/
function RenderArea(_ref6) {
var needClip = _ref6.needClip,
clipPathId = _ref6.clipPathId,
props = _ref6.props;
/*
* These two must be refs, not state!
* Because we want to store the most recent shape of the animation in case we have to interrupt the animation;
* that happens when user initiates another animation before the current one finishes.
*
* If this was a useState, then every step in the animation would trigger a re-render.
* So, useRef it is.
*/
var previousPointsRef = useRef(null);
var previousBaselineRef = useRef();
return /*#__PURE__*/React.createElement(AreaWithAnimation, {
needClip: needClip,
clipPathId: clipPathId,
props: props,
previousPointsRef: previousPointsRef,
previousBaselineRef: previousBaselineRef
});
}
class AreaWithState extends PureComponent {
render() {
var _this$props = this.props,
hide = _this$props.hide,
dot = _this$props.dot,
points = _this$props.points,
className = _this$props.className,
top = _this$props.top,
left = _this$props.left,
needClip = _this$props.needClip,
xAxisId = _this$props.xAxisId,
yAxisId = _this$props.yAxisId,
width = _this$props.width,
height = _this$props.height,
id = _this$props.id,
baseLine = _this$props.baseLine,
zIndex = _this$props.zIndex;
if (hide) {
return null;
}
var layerClass = clsx('recharts-area', className);
var clipPathId = id;
var _getRadiusAndStrokeWi = getRadiusAndStrokeWidthFromDot(dot),
r = _getRadiusAndStrokeWi.r,
strokeWidth = _getRadiusAndStrokeWi.strokeWidth;
var clipDot = isClipDot(dot);
var dotSize = r * 2 + strokeWidth;
var activePointsClipPath = needClip ? "url(#clipPath-".concat(clipDot ? '' : 'dots-').concat(clipPathId, ")") : undefined;
return /*#__PURE__*/React.createElement(ZIndexLayer, {
zIndex: zIndex
}, /*#__PURE__*/React.createElement(Layer, {
className: layerClass
}, needClip && /*#__PURE__*/React.createElement("defs", null, /*#__PURE__*/React.createElement(GraphicalItemClipPath, {
clipPathId: clipPathId,
xAxisId: xAxisId,
yAxisId: yAxisId
}), !clipDot && /*#__PURE__*/React.createElement("clipPath", {
id: "clipPath-dots-".concat(clipPathId)
}, /*#__PURE__*/React.createElement("rect", {
x: left - dotSize / 2,
y: top - dotSize / 2,
width: width + dotSize,
height: height + dotSize
}))), /*#__PURE__*/React.createElement(RenderArea, {
needClip: needClip,
clipPathId: clipPathId,
props: this.props
})), /*#__PURE__*/React.createElement(ActivePoints, {
points: points,
mainColor: getLegendItemColor(this.props.stroke, this.props.fill),
itemDataKey: this.props.dataKey,
activeDot: this.props.activeDot,
clipPath: activePointsClipPath
}), this.props.isRange && Array.isArray(baseLine) && /*#__PURE__*/React.createElement(ActivePoints, {
points: baseLine,
mainColor: getLegendItemColor(this.props.stroke, this.props.fill),
itemDataKey: this.props.dataKey,
activeDot: this.props.activeDot,
clipPath: activePointsClipPath
}));
}
}
function AreaImpl(props) {
var _useAppSelector;
var activeDot = props.activeDot,
animationBegin = props.animationBegin,
animationDuration = props.animationDuration,
animationEasing = props.animationEasing,
connectNulls = props.connectNulls,
dot = props.dot,
fill = props.fill,
fillOpacity = props.fillOpacity,
hide = props.hide,
isAnimationActive = props.isAnimationActive,
legendType = props.legendType,
stroke = props.stroke,
xAxisId = props.xAxisId,
yAxisId = props.yAxisId,
everythingElse = _objectWithoutProperties(props, _excluded2);
var layout = useChartLayout();
var chartName = useChartName();
var _useNeedsClip = useNeedsClip(xAxisId, yAxisId),
needClip = _useNeedsClip.needClip;
var isPanorama = useIsPanorama();
var _ref7 = (_useAppSelector = useAppSelector(state => selectArea(state, props.id, isPanorama))) !== null && _useAppSelector !== void 0 ? _useAppSelector : {},
points = _ref7.points,
isRange = _ref7.isRange,
baseLine = _ref7.baseLine;
var plotArea = usePlotArea();
if (layout !== 'horizontal' && layout !== 'vertical' || plotArea == null) {
// Can't render Area in an unsupported layout
return null;
}
if (chartName !== 'AreaChart' && chartName !== 'ComposedChart') {
// There is nothing stopping us from rendering Area in other charts, except for historical reasons. Do we want to allow that?
return null;
}
var height = plotArea.height,
width = plotArea.width,
left = plotArea.x,
top = plotArea.y;
if (!points || !points.length) {
return null;
}
return /*#__PURE__*/React.createElement(AreaWithState, _extends({}, everythingElse, {
activeDot: activeDot,
animationBegin: animationBegin,
animationDuration: animationDuration,
animationEasing: animationEasing,
baseLine: baseLine,
connectNulls: connectNulls,
dot: dot,
fill: fill,
fillOpacity: fillOpacity,
height: height,
hide: hide,
layout: layout,
isAnimationActive: isAnimationActive,
isRange: isRange,
legendType: legendType,
needClip: needClip,
points: points,
stroke: stroke,
width: width,
left: left,
top: top,
xAxisId: xAxisId,
yAxisId: yAxisId
}));
}
export var getBaseValue = (layout, chartBaseValue, itemBaseValue, xAxis, yAxis) => {
// The baseValue can be defined both on the AreaChart, and on the Area.
// The value for the item takes precedence.
var baseValue = itemBaseValue !== null && itemBaseValue !== void 0 ? itemBaseValue : chartBaseValue;
if (isNumber(baseValue)) {
return baseValue;
}
var numericAxis = layout === 'horizontal' ? yAxis : xAxis;
// @ts-expect-error d3scale .domain() returns unknown, Math.max expects number
var domain = numericAxis.scale.domain();
if (numericAxis.type === 'number') {
var domainMax = Math.max(domain[0], domain[1]);
var domainMin = Math.min(domain[0], domain[1]);
if (baseValue === 'dataMin') {
return domainMin;
}
if (baseValue === 'dataMax') {
return domainMax;
}
return domainMax < 0 ? domainMax : Math.max(Math.min(domain[0], domain[1]), 0);
}
if (baseValue === 'dataMin') {
return domain[0];
}
if (baseValue === 'dataMax') {
return domain[1];
}
return domain[0];
};
export function computeArea(_ref8) {
var _ref8$areaSettings = _ref8.areaSettings,
connectNulls = _ref8$areaSettings.connectNulls,
itemBaseValue = _ref8$areaSettings.baseValue,
dataKey = _ref8$areaSettings.dataKey,
stackedData = _ref8.stackedData,
layout = _ref8.layout,
chartBaseValue = _ref8.chartBaseValue,
xAxis = _ref8.xAxis,
yAxis = _ref8.yAxis,
displayedData = _ref8.displayedData,
dataStartIndex = _ref8.dataStartIndex,
xAxisTicks = _ref8.xAxisTicks,
yAxisTicks = _ref8.yAxisTicks,
bandSize = _ref8.bandSize;
var hasStack = stackedData && stackedData.length;
var baseValue = getBaseValue(layout, chartBaseValue, itemBaseValue, xAxis, yAxis);
var isHorizontalLayout = layout === 'horizontal';
var isRange = false;
var points = displayedData.map((entry, index) => {
var _valueAsArray$, _valueAsArray, _xAxis$scale$map;
var valueAsArray;
if (hasStack) {
valueAsArray = stackedData[dataStartIndex + index];
} else {
var rawValue = getValueByDataKey(entry, dataKey);
if (!Array.isArray(rawValue)) {
valueAsArray = [baseValue, rawValue];
} else {
valueAsArray = rawValue;
isRange = true;
}
}
var value1 = (_valueAsArray$ = (_valueAsArray = valueAsArray) === null || _valueAsArray === void 0 ? void 0 : _valueAsArray[1]) !== null && _valueAsArray$ !== void 0 ? _valueAsArray$ : null;
var isBreakPoint = value1 == null || hasStack && !connectNulls && getValueByDataKey(entry, dataKey) == null;
if (isHorizontalLayout) {
var _yAxis$scale$map;
return {
x: getCateCoordinateOfLine({
axis: xAxis,
ticks: xAxisTicks,
bandSize,
entry,
index
}),
y: isBreakPoint ? null : (_yAxis$scale$map = yAxis.scale.map(value1)) !== null && _yAxis$scale$map !== void 0 ? _yAxis$scale$map : null,
value: valueAsArray,
payload: entry
};
}
return {
x: isBreakPoint ? null : (_xAxis$scale$map = xAxis.scale.map(value1)) !== null && _xAxis$scale$map !== void 0 ? _xAxis$scale$map : null,
y: getCateCoordinateOfLine({
axis: yAxis,
ticks: yAxisTicks,
bandSize,
entry,
index
}),
value: valueAsArray,
payload: entry
};
});
var baseLine;
if (hasStack || isRange) {
baseLine = points.map(entry => {
var _xAxis$scale$map2;
var x = Array.isArray(entry.value) ? entry.value[0] : null;
if (isHorizontalLayout) {
var _yAxis$scale$map2;
return {
x: entry.x,
y: x != null && entry.y != null ? (_yAxis$scale$map2 = yAxis.scale.map(x)) !== null && _yAxis$scale$map2 !== void 0 ? _yAxis$scale$map2 : null : null,
payload: entry.payload
};
}
return {
x: x != null ? (_xAxis$scale$map2 = xAxis.scale.map(x)) !== null && _xAxis$scale$map2 !== void 0 ? _xAxis$scale$map2 : null : null,
y: entry.y,
payload: entry.payload
};
});
} else {
baseLine = isHorizontalLayout ? yAxis.scale.map(baseValue) : xAxis.scale.map(baseValue);
}
return {
points,
baseLine: baseLine !== null && baseLine !== void 0 ? baseLine : 0,
isRange
};
}
function AreaFn(outsideProps) {
var props = resolveDefaultProps(outsideProps, defaultAreaProps);
var isPanorama = useIsPanorama();
// Report all props to Redux store first, before calling hooks, to avoid circular dependencies.
return /*#__PURE__*/React.createElement(RegisterGraphicalItemId, {
id: props.id,
type: "area"
}, id => /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(SetLegendPayload, {
legendPayload: computeLegendPayloadFromAreaData(props)
}), /*#__PURE__*/React.createElement(SetAreaTooltipEntrySettings, {
dataKey: props.dataKey,
data: props.data,
stroke: props.stroke,
strokeWidth: props.strokeWidth,
fill: props.fill,
name: props.name,
hide: props.hide,
unit: props.unit,
formatter: props.formatter,
tooltipType: props.tooltipType,
id: id
}), /*#__PURE__*/React.createElement(SetCartesianGraphicalItem, {
type: "area",
id: id,
data: props.data,
dataKey: props.dataKey,
xAxisId: props.xAxisId,
yAxisId: props.yAxisId,
zAxisId: 0,
stackId: getNormalizedStackId(props.stackId),
hide: props.hide,
barSize: undefined,
baseValue: props.baseValue,
isPanorama: isPanorama,
connectNulls: props.connectNulls
}), /*#__PURE__*/React.createElement(AreaImpl, _extends({}, props, {
id: id
}))));
}
/**
* @provides LabelListContext
* @consumes CartesianChartContext
*/
export var Area = /*#__PURE__*/React.memo(AreaFn, propsAreEqual);
// @ts-expect-error we need to set the displayName for debugging purposes
Area.displayName = 'Area';

View file

@ -0,0 +1,179 @@
var _excluded = ["animationElapsedTime", "isAnimating", "isEntrance", "layout", "isRange", "stroke", "connectNulls"],
_excluded2 = ["id", "baseLine"];
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
import * as React from 'react';
import { isNumber } from '../util/DataUtils';
import { Curve } from '../shape/Curve';
import { isWellBehavedNumber } from '../util/isWellBehavedNumber';
import { Layer } from '../container/Layer';
import { svgPropertiesNoEvents } from '../util/svgPropertiesNoEvents';
import { useId } from '../util/useId';
/**
* Props for the clip-path rect computation.
* @internal
*/
function HorizontalClipRect(_ref) {
var _points$, _points;
var alpha = _ref.alpha,
baseLine = _ref.baseLine,
points = _ref.points,
strokeWidth = _ref.strokeWidth;
var startX = (_points$ = points[0]) === null || _points$ === void 0 ? void 0 : _points$.x;
var endX = (_points = points[points.length - 1]) === null || _points === void 0 ? void 0 : _points.x;
if (!isWellBehavedNumber(startX) || !isWellBehavedNumber(endX)) {
return null;
}
var width = alpha * Math.abs(startX - endX);
var maxY = Math.max(...points.map(entry => entry.y || 0));
if (isNumber(baseLine)) {
maxY = Math.max(baseLine, maxY);
} else if (baseLine && Array.isArray(baseLine) && baseLine.length) {
maxY = Math.max(...baseLine.map(entry => entry.y || 0), maxY);
}
if (isNumber(maxY)) {
return /*#__PURE__*/React.createElement("rect", {
x: startX < endX ? startX : startX - width,
y: 0,
width: width,
height: Math.floor(maxY + (strokeWidth ? parseInt("".concat(strokeWidth), 10) : 1))
});
}
return null;
}
function VerticalClipRect(_ref2) {
var _points$2, _points2;
var alpha = _ref2.alpha,
baseLine = _ref2.baseLine,
points = _ref2.points,
strokeWidth = _ref2.strokeWidth;
var startY = (_points$2 = points[0]) === null || _points$2 === void 0 ? void 0 : _points$2.y;
var endY = (_points2 = points[points.length - 1]) === null || _points2 === void 0 ? void 0 : _points2.y;
if (!isWellBehavedNumber(startY) || !isWellBehavedNumber(endY)) {
return null;
}
var height = alpha * Math.abs(startY - endY);
var maxX = Math.max(...points.map(entry => entry.x || 0));
if (isNumber(baseLine)) {
maxX = Math.max(baseLine, maxX);
} else if (baseLine && Array.isArray(baseLine) && baseLine.length) {
maxX = Math.max(...baseLine.map(entry => entry.x || 0), maxX);
}
if (isNumber(maxX)) {
return /*#__PURE__*/React.createElement("rect", {
x: 0,
y: startY < endY ? startY : startY - height,
width: maxX + (strokeWidth ? parseInt("".concat(strokeWidth), 10) : 1),
height: Math.floor(height)
});
}
return null;
}
function RevealClipRect(_ref3) {
var alpha = _ref3.alpha,
layout = _ref3.layout,
points = _ref3.points,
baseLine = _ref3.baseLine,
strokeWidth = _ref3.strokeWidth;
if (layout === 'vertical') {
return /*#__PURE__*/React.createElement(VerticalClipRect, {
alpha: alpha,
points: points,
baseLine: baseLine,
strokeWidth: strokeWidth
});
}
return /*#__PURE__*/React.createElement(HorizontalClipRect, {
alpha: alpha,
points: points,
baseLine: baseLine,
strokeWidth: strokeWidth
});
}
/**
* The default shape for Area that reveals the chart with a left-to-right (or top-to-bottom)
* clip-path animation on entrance, and renders the plain curve otherwise.
*
* This component renders the complete Area visual: the filled area curve, the stroke curve,
* and (for range areas) the baseline stroke curve. During entrance animation, all curves are
* wrapped in a clip-path that progressively reveals the area.
*
* This is the built-in entrance animation for Area. It is automatically used when no custom
* `shape` prop is provided. You can import and reuse it as a starting point for custom shapes.
*
* @example
* ```tsx
* import { Area, AreaRevealShape } from 'recharts';
*
* // Use the default shape explicitly (same as providing no shape prop)
* <Area dataKey="value" shape={AreaRevealShape} />
* ```
*
* @see {@link https://recharts.github.io/en-US/guide/animations Animation guide}
*
* @since 3.9
*/
export function AreaRevealShape(props) {
var _props$animationElaps = props.animationElapsedTime,
animationElapsedTime = _props$animationElaps === void 0 ? 1 : _props$animationElaps,
_props$isAnimating = props.isAnimating,
isAnimating = _props$isAnimating === void 0 ? false : _props$isAnimating,
_props$isEntrance = props.isEntrance,
isEntrance = _props$isEntrance === void 0 ? false : _props$isEntrance,
layoutProp = props.layout,
isRange = props.isRange,
stroke = props.stroke,
connectNulls = props.connectNulls,
restProps = _objectWithoutProperties(props, _excluded);
var layout = layoutProp === 'vertical' ? 'vertical' : 'horizontal';
var finalConnectNulls = connectNulls !== null && connectNulls !== void 0 ? connectNulls : false;
var clipId = useId();
var id = restProps.id,
baseLine = restProps.baseLine,
propsWithoutIdBaseline = _objectWithoutProperties(restProps, _excluded2);
var strokeSvgProps = svgPropertiesNoEvents(propsWithoutIdBaseline);
var fillCurve = /*#__PURE__*/React.createElement(Curve, _extends({}, restProps, {
id: id,
baseLine: baseLine,
connectNulls: finalConnectNulls,
stroke: "none",
className: "recharts-area-area",
layout: layout
}));
var strokeCurve = stroke !== 'none' && /*#__PURE__*/React.createElement(Curve, _extends({}, strokeSvgProps, {
className: "recharts-area-curve",
layout: layout,
type: restProps.type,
connectNulls: finalConnectNulls,
fill: "none",
stroke: stroke,
points: restProps.points
}));
var baselineCurve = stroke !== 'none' && isRange && Array.isArray(baseLine) && /*#__PURE__*/React.createElement(Curve, _extends({}, strokeSvgProps, {
className: "recharts-area-curve",
layout: layout,
type: restProps.type,
connectNulls: finalConnectNulls,
fill: "none",
stroke: stroke,
points: baseLine
}));
if (isEntrance && (isAnimating || animationElapsedTime < 1)) {
var _restProps$points;
return /*#__PURE__*/React.createElement(Layer, null, /*#__PURE__*/React.createElement("defs", null, /*#__PURE__*/React.createElement("clipPath", {
id: clipId
}, /*#__PURE__*/React.createElement(RevealClipRect, {
alpha: animationElapsedTime,
points: (_restProps$points = restProps.points) !== null && _restProps$points !== void 0 ? _restProps$points : [],
baseLine: baseLine,
layout: layout,
strokeWidth: restProps.strokeWidth
}))), /*#__PURE__*/React.createElement(Layer, {
clipPath: "url(#".concat(clipId, ")")
}, fillCurve, strokeCurve, baselineCurve));
}
return /*#__PURE__*/React.createElement(React.Fragment, null, fillCurve, strokeCurve, baselineCurve);
}

740
frontend/node_modules/recharts/es6/cartesian/Bar.js generated vendored Normal file
View file

@ -0,0 +1,740 @@
var _excluded = ["onMouseEnter", "onMouseLeave", "onClick"],
_excluded2 = ["value", "background", "tooltipPosition"],
_excluded3 = ["id"],
_excluded4 = ["onMouseEnter", "onClick", "onMouseLeave"];
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
import * as React from 'react';
import { PureComponent, useCallback, useEffect, useRef, useState } from 'react';
import { clsx } from 'clsx';
import { Layer } from '../container/Layer';
import { Cell } from '../component/Cell';
import { CartesianLabelListContextProvider, LabelListFromLabelProp } from '../component/LabelList';
import { interpolate, isNan, mathSign, noop } from '../util/DataUtils';
import { findAllByType } from '../util/ReactUtils';
import { getBaseValueOfBar, getCateCoordinateOfBar, getTooltipNameProp, getValueByDataKey, truncateByDomain } from '../util/ChartUtils';
import { adaptEventsOfChild } from '../util/types';
import { BarRectangle, defaultBarShape, minPointSizeCallback } from '../util/BarUtils';
import { useMouseClickItemDispatch, useMouseEnterItemDispatch, useMouseLeaveItemDispatch } from '../context/tooltipContext';
import { SetTooltipEntrySettings } from '../state/SetTooltipEntrySettings';
import { SetErrorBarContext } from '../context/ErrorBarContext';
import { GraphicalItemClipPath, useNeedsClip } from './GraphicalItemClipPath';
import { useChartLayout } from '../context/chartLayoutContext';
import { selectBarRectangles } from '../state/selectors/barSelectors';
import { useAppSelector } from '../state/hooks';
import { useIsPanorama } from '../context/PanoramaContext';
import { selectActiveTooltipDataKey, selectActiveTooltipIndex } from '../state/selectors/tooltipSelectors';
import { SetLegendPayload } from '../state/SetLegendPayload';
import { resolveDefaultProps } from '../util/resolveDefaultProps';
import { RegisterGraphicalItemId } from '../context/RegisterGraphicalItemId';
import { SetCartesianGraphicalItem } from '../state/SetGraphicalItem';
import { svgPropertiesNoEvents, svgPropertiesNoEventsFromUnknown } from '../util/svgPropertiesNoEvents';
import { AnimatedItems, useAnimationCallbacks } from '../animation/AnimatedItems';
import { matchAppend } from '../animation/matchBy';
import { ZIndexLayer } from '../zIndex/ZIndexLayer';
import { DefaultZIndexes } from '../zIndex/DefaultZIndexes';
import { getZIndexFromUnknown } from '../zIndex/getZIndexFromUnknown';
import { propsAreEqual } from '../util/propsAreEqual';
import { BarStackClipLayer, useStackId } from './BarStack';
var computeLegendPayloadFromBarData = props => {
var dataKey = props.dataKey,
name = props.name,
fill = props.fill,
legendType = props.legendType,
hide = props.hide;
return [{
inactive: hide,
dataKey,
type: legendType,
color: fill,
value: getTooltipNameProp(name, dataKey),
payload: props
}];
};
var SetBarTooltipEntrySettings = /*#__PURE__*/React.memo(_ref => {
var dataKey = _ref.dataKey,
stroke = _ref.stroke,
strokeWidth = _ref.strokeWidth,
fill = _ref.fill,
name = _ref.name,
hide = _ref.hide,
unit = _ref.unit,
formatter = _ref.formatter,
tooltipType = _ref.tooltipType,
id = _ref.id;
var tooltipEntrySettings = {
dataDefinedOnItem: undefined,
getPosition: noop,
settings: {
stroke,
strokeWidth,
fill,
dataKey,
nameKey: undefined,
name: getTooltipNameProp(name, dataKey),
hide,
type: tooltipType,
color: fill,
unit,
formatter,
graphicalItemId: id
}
};
return /*#__PURE__*/React.createElement(SetTooltipEntrySettings, {
tooltipEntrySettings: tooltipEntrySettings
});
});
function BarBackground(props) {
var activeIndex = useAppSelector(selectActiveTooltipIndex);
var data = props.data,
dataKey = props.dataKey,
backgroundFromProps = props.background,
allOtherBarProps = props.allOtherBarProps;
var onMouseEnterFromProps = allOtherBarProps.onMouseEnter,
onMouseLeaveFromProps = allOtherBarProps.onMouseLeave,
onItemClickFromProps = allOtherBarProps.onClick,
restOfAllOtherProps = _objectWithoutProperties(allOtherBarProps, _excluded);
var onMouseEnterFromContext = useMouseEnterItemDispatch(onMouseEnterFromProps, dataKey, allOtherBarProps.id);
var onMouseLeaveFromContext = useMouseLeaveItemDispatch(onMouseLeaveFromProps);
var onClickFromContext = useMouseClickItemDispatch(onItemClickFromProps, dataKey, allOtherBarProps.id);
if (!backgroundFromProps || data == null) {
return null;
}
var backgroundProps = svgPropertiesNoEventsFromUnknown(backgroundFromProps);
return /*#__PURE__*/React.createElement(ZIndexLayer, {
zIndex: getZIndexFromUnknown(backgroundFromProps, DefaultZIndexes.barBackground)
}, data.map((entry, i) => {
var value = entry.value,
backgroundFromDataEntry = entry.background,
tooltipPosition = entry.tooltipPosition,
rest = _objectWithoutProperties(entry, _excluded2);
if (!backgroundFromDataEntry) {
return null;
}
var onMouseEnter = onMouseEnterFromContext(entry, entry.originalDataIndex);
var onMouseLeave = onMouseLeaveFromContext(entry, entry.originalDataIndex);
var onClick = onClickFromContext(entry, entry.originalDataIndex);
var barRectangleProps = _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({
option: backgroundFromProps,
isActive: String(entry.originalDataIndex) === activeIndex
}, rest), {}, {
// @ts-expect-error backgroundProps is contributing unknown props
fill: '#eee'
}, backgroundFromDataEntry), backgroundProps), adaptEventsOfChild(restOfAllOtherProps, entry, i)), {}, {
onMouseEnter,
onMouseLeave,
onClick,
dataKey,
index: i,
className: 'recharts-bar-background-rectangle'
});
return /*#__PURE__*/React.createElement(BarRectangle, _extends({
key: "background-bar-".concat(i)
}, barRectangleProps));
}));
}
function BarLabelListProvider(_ref2) {
var showLabels = _ref2.showLabels,
children = _ref2.children,
rects = _ref2.rects;
var labelListEntries = rects === null || rects === void 0 ? void 0 : rects.map(entry => {
var viewBox = {
x: entry.x,
y: entry.y,
width: entry.width,
lowerWidth: entry.width,
upperWidth: entry.width,
height: entry.height
};
return _objectSpread(_objectSpread({}, viewBox), {}, {
value: entry.value,
payload: entry.payload,
parentViewBox: entry.parentViewBox,
viewBox,
fill: entry.fill
});
});
return /*#__PURE__*/React.createElement(CartesianLabelListContextProvider, {
value: showLabels ? labelListEntries : undefined
}, children);
}
function BarRectangleWithActiveState(props) {
var shape = props.shape,
activeBar = props.activeBar,
baseProps = props.baseProps,
entry = props.entry,
index = props.index,
dataKey = props.dataKey;
var activeIndex = useAppSelector(selectActiveTooltipIndex);
var activeDataKey = useAppSelector(selectActiveTooltipDataKey);
/*
* Bars support stacking, meaning that there can be multiple bars at the same x value.
* With Tooltip shared=false we only want to highlight the currently active Bar, not all.
*
* Also, if the tooltip is shared, we want to highlight all bars at the same x value
* regardless of the dataKey.
*
* With shared Tooltip, the activeDataKey is undefined.
*
* We use entry.originalDataIndex to match against activeIndex because the render index parameter
* is based on the filtered array, while activeIndex is based on the pre-filter displayed data slice.
* When entries are filtered out (for example null/zero-dimension bars), these indices can differ.
*/
var isActive = activeBar && String(entry.originalDataIndex) === activeIndex && (activeDataKey == null || dataKey === activeDataKey);
var _useState = useState(false),
_useState2 = _slicedToArray(_useState, 2),
stayInLayer = _useState2[0],
setStayInLayer = _useState2[1];
var _useState3 = useState(false),
_useState4 = _slicedToArray(_useState3, 2),
hasMountedActive = _useState4[0],
setHasMountedActive = _useState4[1];
useEffect(() => {
var rafId;
if (isActive) {
// 1. Enter the layer immediately
setStayInLayer(true);
// 2. Wait for the browser to paint the "inactive" state in the new layer,
// then switch to active to trigger the CSS transition (width grow).
rafId = requestAnimationFrame(() => {
setHasMountedActive(true);
});
} else {
setHasMountedActive(false);
}
return () => {
cancelAnimationFrame(rafId);
};
}, [isActive]);
var handleTransitionEnd = useCallback(() => {
// 4. Leave the layer only when the exit transition finishes
if (!isActive) {
setStayInLayer(false);
}
}, [isActive]);
// Determine props:
// - If entering (isActive=true) but not mounted yet (hasMountedActive=false), pass isActive=false (inactive size).
// - If exiting (isActive=false), pass isActive=false (inactive size).
var isVisuallyActive = isActive && hasMountedActive;
// Render in ZIndexLayer if active OR if we are waiting for exit transition
var shouldRenderInLayer = isActive || stayInLayer;
var option;
if (isActive) {
if (activeBar === true) {
option = shape;
} else {
option = activeBar;
}
} else {
option = shape;
}
var content = /*#__PURE__*/React.createElement(BarRectangle, _extends({}, baseProps, {
name: String(baseProps.name)
}, entry, {
isActive: isVisuallyActive,
option: option,
index: index,
dataKey: dataKey,
animationElapsedTime: props.animationElapsedTime,
isAnimating: props.isAnimating,
isEntrance: props.isEntrance,
onTransitionEnd: handleTransitionEnd
}));
if (shouldRenderInLayer) {
return /*#__PURE__*/React.createElement(ZIndexLayer, {
zIndex: DefaultZIndexes.activeBar
}, /*#__PURE__*/React.createElement(BarStackClipLayer, {
index: entry.originalDataIndex
}, content));
}
return content;
}
function BarRectangleNeverActive(props) {
var shape = props.shape,
baseProps = props.baseProps,
entry = props.entry,
index = props.index,
dataKey = props.dataKey;
return /*#__PURE__*/React.createElement(BarRectangle, _extends({}, baseProps, {
name: String(baseProps.name)
}, entry, {
isActive: false,
option: shape,
index: index,
dataKey: dataKey,
animationElapsedTime: props.animationElapsedTime,
isAnimating: props.isAnimating,
isEntrance: props.isEntrance
}));
}
function BarRectangles(_ref3) {
var _svgPropertiesNoEvent;
var data = _ref3.data,
props = _ref3.props,
animationElapsedTime = _ref3.animationElapsedTime,
isAnimating = _ref3.isAnimating,
isEntrance = _ref3.isEntrance;
var _ref4 = (_svgPropertiesNoEvent = svgPropertiesNoEvents(props)) !== null && _svgPropertiesNoEvent !== void 0 ? _svgPropertiesNoEvent : {},
id = _ref4.id,
baseProps = _objectWithoutProperties(_ref4, _excluded3);
var shape = props.shape,
dataKey = props.dataKey,
activeBar = props.activeBar;
var onMouseEnterFromProps = props.onMouseEnter,
onItemClickFromProps = props.onClick,
onMouseLeaveFromProps = props.onMouseLeave,
restOfAllOtherProps = _objectWithoutProperties(props, _excluded4);
var onMouseEnterFromContext = useMouseEnterItemDispatch(onMouseEnterFromProps, dataKey, id);
var onMouseLeaveFromContext = useMouseLeaveItemDispatch(onMouseLeaveFromProps);
var onClickFromContext = useMouseClickItemDispatch(onItemClickFromProps, dataKey, id);
if (!data) {
return null;
}
return /*#__PURE__*/React.createElement(React.Fragment, null, data.map((entry, i) => {
return /*#__PURE__*/React.createElement(BarStackClipLayer, _extends({
index: entry.originalDataIndex
// https://github.com/recharts/recharts/issues/5415
,
key: "rectangle-".concat(entry === null || entry === void 0 ? void 0 : entry.x, "-").concat(entry === null || entry === void 0 ? void 0 : entry.y, "-").concat(entry === null || entry === void 0 ? void 0 : entry.value, "-").concat(i),
className: "recharts-bar-rectangle"
}, adaptEventsOfChild(restOfAllOtherProps, entry, i), {
onMouseEnter: onMouseEnterFromContext(entry, entry.originalDataIndex),
onMouseLeave: onMouseLeaveFromContext(entry, entry.originalDataIndex),
onClick: onClickFromContext(entry, entry.originalDataIndex)
}), activeBar ? /*#__PURE__*/React.createElement(BarRectangleWithActiveState, {
shape: shape,
activeBar: activeBar,
baseProps: baseProps,
entry: entry,
index: i,
dataKey: dataKey,
animationElapsedTime: animationElapsedTime,
isAnimating: isAnimating,
isEntrance: isEntrance
}) :
/*#__PURE__*/
/*
* If the `activeBar` prop is falsy, then let's call the variant without hooks.
* Using the `selectActiveTooltipIndex` selector is usually fast
* but in charts with large-ish amount of data even the few nanoseconds add up to a noticeable jank.
* If the activeBar is false then we don't need to know which index is active - because we won't use it anyway.
* So let's just skip the hooks altogether. That way, React can skip rendering the component,
* and can skip the tree reconciliation for its children too.
* Because we can't call hooks conditionally, we need to have a separate component for that.
*/
React.createElement(BarRectangleNeverActive, {
shape: shape,
baseProps: baseProps,
entry: entry,
index: i,
dataKey: dataKey,
animationElapsedTime: animationElapsedTime,
isAnimating: isAnimating,
isEntrance: isEntrance
}));
}));
}
var defaultBarAnimateItems = (items, animationElapsedTime, layout) => {
if (items == null) return [];
if (animationElapsedTime === 1) {
return items.flatMap(item => item.status === 'removed' ? [] : [item.next]);
}
return items.flatMap(item => {
if (item.status === 'removed') {
// animate removed items to 0 height/width respective of layout
if (layout === 'horizontal') {
return [_objectSpread(_objectSpread({}, item.prev), {}, {
height: interpolate(item.prev.height, 0, animationElapsedTime),
y: interpolate(item.prev.y, item.prev.y + item.prev.height, animationElapsedTime)
})];
}
return [_objectSpread(_objectSpread({}, item.prev), {}, {
width: interpolate(item.prev.width, 0, animationElapsedTime)
})];
}
if (item.status === 'matched') {
return [_objectSpread(_objectSpread({}, item.next), {}, {
x: interpolate(item.prev.x, item.next.x, animationElapsedTime),
y: interpolate(item.prev.y, item.next.y, animationElapsedTime),
width: interpolate(item.prev.width, item.next.width, animationElapsedTime),
height: interpolate(item.prev.height, item.next.height, animationElapsedTime)
})];
}
// added
var next = item.next;
if (layout === 'horizontal') {
return [_objectSpread(_objectSpread({}, next), {}, {
height: interpolate(0, next.height, animationElapsedTime),
y: interpolate(next.stackedBarStart, next.y, animationElapsedTime)
})];
}
return [_objectSpread(_objectSpread({}, next), {}, {
width: interpolate(0, next.width, animationElapsedTime),
x: interpolate(next.stackedBarStart, next.x, animationElapsedTime)
})];
});
};
function RectanglesWithAnimation(_ref5) {
var props = _ref5.props,
previousRectanglesRef = _ref5.previousRectanglesRef;
var data = props.data,
isAnimationActive = props.isAnimationActive,
animationBegin = props.animationBegin,
animationDuration = props.animationDuration,
animationEasing = props.animationEasing,
animationInterpolateFn = props.animationInterpolateFn,
layout = props.layout;
var _useAnimationCallback = useAnimationCallbacks(props.onAnimationStart, props.onAnimationEnd),
isAnimating = _useAnimationCallback.isAnimating,
handleAnimationStart = _useAnimationCallback.handleAnimationStart,
handleAnimationEnd = _useAnimationCallback.handleAnimationEnd;
return /*#__PURE__*/React.createElement(BarLabelListProvider, {
showLabels: !isAnimating,
rects: data
}, /*#__PURE__*/React.createElement(AnimatedItems, {
animationInput: data,
animationIdPrefix: "recharts-bar-",
items: data,
previousItemsRef: previousRectanglesRef,
isAnimationActive: isAnimationActive,
animationBegin: animationBegin,
animationDuration: animationDuration,
animationEasing: animationEasing,
onAnimationStart: handleAnimationStart,
onAnimationEnd: handleAnimationEnd,
animationInterpolateFn: animationInterpolateFn,
animationMatchBy: props.animationMatchBy,
layout: layout
}, (stepData, animationElapsedTime, isEntrance) => /*#__PURE__*/React.createElement(Layer, null, /*#__PURE__*/React.createElement(BarRectangles, {
props: props,
data: stepData,
animationElapsedTime: animationElapsedTime,
isAnimating: isAnimating || animationElapsedTime < 1,
isEntrance: isEntrance
}))), /*#__PURE__*/React.createElement(LabelListFromLabelProp, {
label: props.label
}), props.children);
}
function RenderRectangles(props) {
var previousRectanglesRef = useRef(null);
return /*#__PURE__*/React.createElement(RectanglesWithAnimation, {
previousRectanglesRef: previousRectanglesRef,
props: props
});
}
var defaultMinPointSize = 0;
var errorBarDataPointFormatter = (dataPoint, dataKey) => {
/**
* if the value coming from `selectBarRectangles` is an array then this is a stacked bar chart.
* arr[1] represents end value of the bar since the data is in the form of [startValue, endValue].
* */
var value = Array.isArray(dataPoint.value) ? dataPoint.value[1] : dataPoint.value;
return {
x: dataPoint.x,
y: dataPoint.y,
value,
// getValueByDataKey does not validate the output type
errorVal: getValueByDataKey(dataPoint, dataKey)
};
};
class BarWithState extends PureComponent {
render() {
var _this$props = this.props,
hide = _this$props.hide,
data = _this$props.data,
dataKey = _this$props.dataKey,
className = _this$props.className,
xAxisId = _this$props.xAxisId,
yAxisId = _this$props.yAxisId,
needClip = _this$props.needClip,
background = _this$props.background,
id = _this$props.id;
if (hide || data == null) {
return null;
}
var layerClass = clsx('recharts-bar', className);
var clipPathId = id;
return /*#__PURE__*/React.createElement(Layer, {
className: layerClass,
id: id
}, needClip && /*#__PURE__*/React.createElement("defs", null, /*#__PURE__*/React.createElement(GraphicalItemClipPath, {
clipPathId: clipPathId,
xAxisId: xAxisId,
yAxisId: yAxisId
})), /*#__PURE__*/React.createElement(Layer, {
className: "recharts-bar-rectangles",
clipPath: needClip ? "url(#clipPath-".concat(clipPathId, ")") : undefined
}, /*#__PURE__*/React.createElement(BarBackground, {
data: data,
dataKey: dataKey,
background: background,
allOtherBarProps: this.props
}), /*#__PURE__*/React.createElement(RenderRectangles, this.props)));
}
}
export var defaultBarProps = {
activeBar: false,
animationBegin: 0,
animationDuration: 400,
animationEasing: 'ease',
animationInterpolateFn: defaultBarAnimateItems,
animationMatchBy: matchAppend,
background: false,
hide: false,
isAnimationActive: 'auto',
label: false,
legendType: 'rect',
minPointSize: defaultMinPointSize,
shape: defaultBarShape,
xAxisId: 0,
yAxisId: 0,
zIndex: DefaultZIndexes.bar
};
function BarImpl(props) {
var xAxisId = props.xAxisId,
yAxisId = props.yAxisId,
hide = props.hide,
legendType = props.legendType,
minPointSize = props.minPointSize,
activeBar = props.activeBar,
animationBegin = props.animationBegin,
animationDuration = props.animationDuration,
animationEasing = props.animationEasing,
isAnimationActive = props.isAnimationActive;
var _useNeedsClip = useNeedsClip(xAxisId, yAxisId),
needClip = _useNeedsClip.needClip;
var layout = useChartLayout();
var isPanorama = useIsPanorama();
var cells = findAllByType(props.children, Cell);
var rects = useAppSelector(state => selectBarRectangles(state, props.id, isPanorama, cells));
if (layout !== 'vertical' && layout !== 'horizontal') {
return null;
}
var errorBarOffset;
var firstDataPoint = rects === null || rects === void 0 ? void 0 : rects[0];
if (firstDataPoint == null || firstDataPoint.height == null || firstDataPoint.width == null) {
errorBarOffset = 0;
} else {
errorBarOffset = layout === 'vertical' ? firstDataPoint.height / 2 : firstDataPoint.width / 2;
}
return /*#__PURE__*/React.createElement(SetErrorBarContext, {
xAxisId: xAxisId,
yAxisId: yAxisId,
data: rects,
dataPointFormatter: errorBarDataPointFormatter,
errorBarOffset: errorBarOffset
}, /*#__PURE__*/React.createElement(BarWithState, _extends({}, props, {
layout: layout,
needClip: needClip,
data: rects,
xAxisId: xAxisId,
yAxisId: yAxisId,
hide: hide,
legendType: legendType,
minPointSize: minPointSize,
activeBar: activeBar,
animationBegin: animationBegin,
animationDuration: animationDuration,
animationEasing: animationEasing,
isAnimationActive: isAnimationActive
})));
}
export function computeBarRectangles(_ref6) {
var layout = _ref6.layout,
_ref6$barSettings = _ref6.barSettings,
dataKey = _ref6$barSettings.dataKey,
minPointSizeProp = _ref6$barSettings.minPointSize,
hasCustomShape = _ref6$barSettings.hasCustomShape,
pos = _ref6.pos,
bandSize = _ref6.bandSize,
xAxis = _ref6.xAxis,
yAxis = _ref6.yAxis,
xAxisTicks = _ref6.xAxisTicks,
yAxisTicks = _ref6.yAxisTicks,
stackedData = _ref6.stackedData,
displayedData = _ref6.displayedData,
offset = _ref6.offset,
cells = _ref6.cells,
parentViewBox = _ref6.parentViewBox,
dataStartIndex = _ref6.dataStartIndex;
var numericAxis = layout === 'horizontal' ? yAxis : xAxis;
// @ts-expect-error this assumes that the domain is always numeric, but doesn't check for it
var stackedDomain = stackedData ? numericAxis.scale.domain() : null;
var baseValue = getBaseValueOfBar({
numericAxis
});
var stackedBarStart = numericAxis.scale.map(baseValue);
return displayedData.map((entry, index) => {
var value, x, y, width, height, background;
if (stackedData) {
// Use dataStartIndex to access the correct element in the full stackedData array
var untruncatedValue = stackedData[index + dataStartIndex];
if (untruncatedValue == null) {
return null;
}
value = truncateByDomain(untruncatedValue, stackedDomain);
} else {
value = getValueByDataKey(entry, dataKey);
if (!Array.isArray(value)) {
value = [baseValue, value];
}
}
var minPointSize = minPointSizeCallback(minPointSizeProp, defaultMinPointSize)(value[1], index);
if (layout === 'horizontal') {
var _ref7;
var baseValueScale = yAxis.scale.map(value[0]);
var currentValueScale = yAxis.scale.map(value[1]);
if (baseValueScale == null || currentValueScale == null) {
return null;
}
x = getCateCoordinateOfBar({
axis: xAxis,
ticks: xAxisTicks,
bandSize,
offset: pos.offset,
entry,
index
});
y = (_ref7 = currentValueScale !== null && currentValueScale !== void 0 ? currentValueScale : baseValueScale) !== null && _ref7 !== void 0 ? _ref7 : undefined;
width = pos.size;
var computedHeight = baseValueScale - currentValueScale;
height = isNan(computedHeight) ? 0 : computedHeight;
background = {
x,
y: offset.top,
width,
height: offset.height
};
if (Math.abs(minPointSize) > 0 && Math.abs(height) < Math.abs(minPointSize)) {
var delta = mathSign(height || minPointSize) * (Math.abs(minPointSize) - Math.abs(height));
y -= delta;
height += delta;
}
} else {
var _baseValueScale = xAxis.scale.map(value[0]);
var _currentValueScale = xAxis.scale.map(value[1]);
if (_baseValueScale == null || _currentValueScale == null) {
return null;
}
x = _baseValueScale;
y = getCateCoordinateOfBar({
axis: yAxis,
ticks: yAxisTicks,
bandSize,
offset: pos.offset,
entry,
index
});
width = _currentValueScale - _baseValueScale;
height = pos.size;
background = {
x: offset.left,
y,
width: offset.width,
height
};
if (Math.abs(minPointSize) > 0 && Math.abs(width) < Math.abs(minPointSize)) {
var _delta = mathSign(width || minPointSize) * (Math.abs(minPointSize) - Math.abs(width));
width += _delta;
}
}
/*
* Filter out 0-dimension rectangles early to avoid creating unnecessary component trees.
* BarStack clip-paths use originalDataIndex, so sparse filtered arrays remain index-stable.
* Bars with a custom shape are not filtered out: the custom renderer may still draw something
* visible at zero-dimension positions (e.g. horizontal lines in a BoxPlot).
*/
if (x == null || y == null || width == null || height == null || !hasCustomShape && (width === 0 || height === 0)) {
return null;
}
var barRectangleItem = _objectSpread(_objectSpread({}, entry), {}, {
stackedBarStart,
x,
y,
width,
height,
value: stackedData ? value : value[1],
payload: entry,
background,
tooltipPosition: {
x: x + width / 2,
y: y + height / 2
},
parentViewBox,
originalDataIndex: index
}, cells && cells[index] && cells[index].props);
return barRectangleItem;
}).filter(Boolean);
}
function BarFn(outsideProps) {
var props = resolveDefaultProps(outsideProps, defaultBarProps);
// stackId may arrive from props or from BarStack context
var stackId = useStackId(props.stackId);
var isPanorama = useIsPanorama();
// Report all props to Redux store first, before calling any hooks, to avoid circular dependencies.
return /*#__PURE__*/React.createElement(RegisterGraphicalItemId, {
id: props.id,
type: "bar"
}, id => /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(SetLegendPayload, {
legendPayload: computeLegendPayloadFromBarData(props)
}), /*#__PURE__*/React.createElement(SetBarTooltipEntrySettings, {
dataKey: props.dataKey,
stroke: props.stroke,
strokeWidth: props.strokeWidth,
fill: props.fill,
name: props.name,
hide: props.hide,
unit: props.unit,
formatter: props.formatter,
tooltipType: props.tooltipType,
id: id
}), /*#__PURE__*/React.createElement(SetCartesianGraphicalItem, {
type: "bar",
id: id
// Bar does not allow setting data directly on the graphical item (why?)
,
data: undefined,
xAxisId: props.xAxisId,
yAxisId: props.yAxisId,
zAxisId: 0,
dataKey: props.dataKey,
stackId: stackId,
hide: props.hide,
barSize: props.barSize,
minPointSize: props.minPointSize,
maxBarSize: props.maxBarSize,
isPanorama: isPanorama,
hasCustomShape: props.shape != null && props.shape !== defaultBarShape
}), /*#__PURE__*/React.createElement(ZIndexLayer, {
zIndex: props.zIndex
}, /*#__PURE__*/React.createElement(BarImpl, _extends({}, props, {
id: id
})))));
}
/**
* @provides ErrorBarContext
* @provides LabelListContext
* @provides CellReader
* @consumes CartesianChartContext
* @consumes BarStackContext
*/
export var Bar = /*#__PURE__*/React.memo(BarFn, propsAreEqual);
// @ts-expect-error we need to set the displayName for debugging purposes
Bar.displayName = 'Bar';

View file

@ -0,0 +1,115 @@
var _excluded = ["index"];
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
import * as React from 'react';
import { createContext, useContext, useMemo } from 'react';
import { getNormalizedStackId } from '../util/ChartUtils';
import { useUniqueId } from '../util/useUniqueId';
import { resolveDefaultProps } from '../util/resolveDefaultProps';
import { useAppSelector } from '../state/hooks';
import { selectStackRects } from '../state/selectors/barStackSelectors';
import { useIsPanorama } from '../context/PanoramaContext';
import { Layer } from '../container/Layer';
import { Rectangle } from '../shape/Rectangle';
import { propsAreEqual } from '../util/propsAreEqual';
var BarStackContext = /*#__PURE__*/createContext(undefined);
/**
* Hook to resolve the stack ID for a Bar component.
* If a stack ID is provided via props, it is used directly.
* Otherwise, this will read stack ID from BarStack context if available.
* If both are undefined, it returns undefined.
* @param childStackId
*/
export var useStackId = childStackId => {
var stackSettings = useContext(BarStackContext);
if (stackSettings != null) {
return stackSettings.stackId;
}
if (childStackId == null) {
return undefined;
}
return getNormalizedStackId(childStackId);
};
export var defaultBarStackProps = {
radius: 0
};
var getClipPathId = (stackId, index) => {
return "recharts-bar-stack-clip-path-".concat(stackId, "-").concat(index);
};
export var useBarStackClipPathUrl = index => {
var barStackContext = useContext(BarStackContext);
if (barStackContext == null) {
return undefined;
}
var stackId = barStackContext.stackId;
return "url(#".concat(getClipPathId(stackId, index), ")");
};
export var BarStackClipLayer = _ref => {
var index = _ref.index,
rest = _objectWithoutProperties(_ref, _excluded);
var clipPathUrl = useBarStackClipPathUrl(index);
return /*#__PURE__*/React.createElement(Layer, _extends({
className: "recharts-bar-stack-layer",
clipPath: clipPathUrl
}, rest));
};
/**
* This React component will render a clipPath that the individual bars in the stack will reference
* to achieve rounded corners for the entire stack.
*/
var BarStackClipPath = _ref2 => {
var stackId = _ref2.stackId,
radius = _ref2.radius;
var isPanorama = useIsPanorama();
var positions = useAppSelector(state => selectStackRects(state, stackId, isPanorama));
if (positions == null || positions.length === 0) {
return null;
}
/*
* Render one clipPath per rectangle in the stack.
* Each rectangle corresponds to one data entry in the chart.
*/
return /*#__PURE__*/React.createElement("defs", null, positions.map((pos, index) => {
if (pos == null) {
return null;
}
var clipPathId = getClipPathId(stackId, index);
return /*#__PURE__*/React.createElement("clipPath", {
key: clipPathId,
id: clipPathId
}, /*#__PURE__*/React.createElement(Rectangle, {
isAnimationActive: false,
isUpdateAnimationActive: false,
x: pos.x,
y: pos.y,
width: pos.width,
height: pos.height,
radius: radius
}));
}));
};
var BarStackImpl = props => {
var resolvedStackId = useUniqueId('recharts-bar-stack', getNormalizedStackId(props.stackId));
var _resolveDefaultProps = resolveDefaultProps(props, defaultBarStackProps),
children = _resolveDefaultProps.children,
radius = _resolveDefaultProps.radius;
var context = useMemo(() => ({
stackId: resolvedStackId,
radius
}), [resolvedStackId, radius]);
return /*#__PURE__*/React.createElement(BarStackContext.Provider, {
value: context
}, /*#__PURE__*/React.createElement(BarStackClipPath, {
stackId: resolvedStackId,
radius: radius
}), children);
};
/**
* @provides BarStackContext
* @since 3.6
*/
export var BarStack = /*#__PURE__*/React.memo(BarStackImpl, propsAreEqual);

858
frontend/node_modules/recharts/es6/cartesian/Brush.js generated vendored Normal file
View file

@ -0,0 +1,858 @@
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
import * as React from 'react';
import { Children, PureComponent, useCallback, useContext, useEffect } from 'react';
import { clsx } from 'clsx';
import { scalePoint } from 'victory-vendor/d3-scale';
import range from 'es-toolkit/compat/range';
import { Layer } from '../container/Layer';
import { Text } from '../component/Text';
import { getValueByDataKey } from '../util/ChartUtils';
import { isNumber, isNotNil } from '../util/DataUtils';
import { generatePrefixStyle } from '../util/CssPrefixUtils';
import { useChartData, useDataIndex } from '../context/chartDataContext';
import { BrushUpdateDispatchContext } from '../context/brushUpdateContext';
import { useAppDispatch, useAppSelector } from '../state/hooks';
import { setDataStartEndIndexes } from '../state/chartDataSlice';
import { setBrushSettings } from '../state/brushSlice';
import { PanoramaContextProvider } from '../context/PanoramaContext';
import { selectBrushDimensions } from '../state/selectors/brushSelectors';
import { useBrushChartSynchronisation } from '../synchronisation/useChartSynchronisation';
import { resolveDefaultProps } from '../util/resolveDefaultProps';
import { svgPropertiesNoEvents } from '../util/svgPropertiesNoEvents';
// Why is this tickFormatter different from the other TickFormatters? This one allows to return numbers too for some reason.
function DefaultTraveller(props) {
var x = props.x,
y = props.y,
width = props.width,
height = props.height,
stroke = props.stroke;
var lineY = Math.floor(y + height / 2) - 1;
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("rect", {
x: x,
y: y,
width: width,
height: height,
fill: stroke,
stroke: "none"
}), /*#__PURE__*/React.createElement("line", {
x1: x + 1,
y1: lineY,
x2: x + width - 1,
y2: lineY,
fill: "none",
stroke: "#fff"
}), /*#__PURE__*/React.createElement("line", {
x1: x + 1,
y1: lineY + 2,
x2: x + width - 1,
y2: lineY + 2,
fill: "none",
stroke: "#fff"
}));
}
function Traveller(props) {
var travellerProps = props.travellerProps,
travellerType = props.travellerType;
if (/*#__PURE__*/React.isValidElement(travellerType)) {
// @ts-expect-error element cloning disagrees with the types (and it should)
return /*#__PURE__*/React.cloneElement(travellerType, travellerProps);
}
if (typeof travellerType === 'function') {
return travellerType(travellerProps);
}
return /*#__PURE__*/React.createElement(DefaultTraveller, travellerProps);
}
function getNameFromUnknown(value) {
if (isNotNil(value) && typeof value === 'object' && 'name' in value && typeof value.name === 'string') {
return value.name;
}
return undefined;
}
function getAriaLabel(data, startIndex, endIndex) {
var start = getNameFromUnknown(data[startIndex]);
var end = getNameFromUnknown(data[endIndex]);
return "Min value: ".concat(start, ", Max value: ").concat(end);
}
function TravellerLayer(_ref) {
var otherProps = _ref.otherProps,
travellerX = _ref.travellerX,
id = _ref.id,
onMouseEnter = _ref.onMouseEnter,
onMouseLeave = _ref.onMouseLeave,
onMouseDown = _ref.onMouseDown,
onTouchStart = _ref.onTouchStart,
onTravellerMoveKeyboard = _ref.onTravellerMoveKeyboard,
onFocus = _ref.onFocus,
onBlur = _ref.onBlur;
var y = otherProps.y,
xFromProps = otherProps.x,
travellerWidth = otherProps.travellerWidth,
height = otherProps.height,
traveller = otherProps.traveller,
ariaLabel = otherProps.ariaLabel,
data = otherProps.data,
startIndex = otherProps.startIndex,
endIndex = otherProps.endIndex;
var x = Math.max(travellerX, xFromProps);
var travellerProps = _objectSpread(_objectSpread({}, svgPropertiesNoEvents(otherProps)), {}, {
x,
y,
width: travellerWidth,
height
});
var ariaLabelBrush = ariaLabel || getAriaLabel(data, startIndex, endIndex);
return /*#__PURE__*/React.createElement(Layer, {
tabIndex: 0,
role: "slider",
"aria-label": ariaLabelBrush,
"aria-valuenow": travellerX,
className: "recharts-brush-traveller",
onMouseEnter: onMouseEnter,
onMouseLeave: onMouseLeave,
onMouseDown: onMouseDown,
onTouchStart: onTouchStart,
onKeyDown: e => {
if (!['ArrowLeft', 'ArrowRight'].includes(e.key)) {
return;
}
e.preventDefault();
e.stopPropagation();
onTravellerMoveKeyboard(e.key === 'ArrowRight' ? 1 : -1, id);
},
onFocus: onFocus,
onBlur: onBlur,
style: {
cursor: 'col-resize'
}
}, /*#__PURE__*/React.createElement(Traveller, {
travellerType: traveller,
travellerProps: travellerProps
}));
}
/*
* This one cannot be a React Component because React is not happy with it returning only string | number.
* React wants a full React.JSX.Element but that is not compatible with Text component.
*/
function getTextOfTick(props) {
var index = props.index,
data = props.data,
tickFormatter = props.tickFormatter,
dataKey = props.dataKey;
var text = getValueByDataKey(data[index], dataKey, index);
return typeof tickFormatter === 'function' ? tickFormatter(text, index) : text;
}
function getIndexInRange(valueRange, x) {
var len = valueRange.length;
var start = 0;
var end = len - 1;
while (end - start > 1) {
var middle = Math.floor((start + end) / 2);
var middleValue = valueRange[middle];
if (middleValue != null && middleValue > x) {
end = middle;
} else {
start = middle;
}
}
var endValue = valueRange[end];
return endValue != null && x >= endValue ? end : start;
}
function getIndex(_ref2) {
var startX = _ref2.startX,
endX = _ref2.endX,
scaleValues = _ref2.scaleValues,
gap = _ref2.gap,
data = _ref2.data;
var lastIndex = data.length - 1;
var min = Math.min(startX, endX);
var max = Math.max(startX, endX);
var minIndex = getIndexInRange(scaleValues, min);
var maxIndex = getIndexInRange(scaleValues, max);
return {
startIndex: minIndex - minIndex % gap,
endIndex: maxIndex === lastIndex ? lastIndex : maxIndex - maxIndex % gap
};
}
function Background(_ref3) {
var x = _ref3.x,
y = _ref3.y,
width = _ref3.width,
height = _ref3.height,
fill = _ref3.fill,
stroke = _ref3.stroke;
return /*#__PURE__*/React.createElement("rect", {
stroke: stroke,
fill: fill,
x: x,
y: y,
width: width,
height: height
});
}
function BrushText(_ref4) {
var startIndex = _ref4.startIndex,
endIndex = _ref4.endIndex,
y = _ref4.y,
height = _ref4.height,
travellerWidth = _ref4.travellerWidth,
stroke = _ref4.stroke,
tickFormatter = _ref4.tickFormatter,
dataKey = _ref4.dataKey,
data = _ref4.data,
startX = _ref4.startX,
endX = _ref4.endX;
var offset = 5;
var attrs = {
pointerEvents: 'none',
fill: stroke
};
return /*#__PURE__*/React.createElement(Layer, {
className: "recharts-brush-texts"
}, /*#__PURE__*/React.createElement(Text, _extends({
textAnchor: "end",
verticalAnchor: "middle",
x: Math.min(startX, endX) - offset,
y: y + height / 2
}, attrs), getTextOfTick({
index: startIndex,
tickFormatter,
dataKey,
data
})), /*#__PURE__*/React.createElement(Text, _extends({
textAnchor: "start",
verticalAnchor: "middle",
x: Math.max(startX, endX) + travellerWidth + offset,
y: y + height / 2
}, attrs), getTextOfTick({
index: endIndex,
tickFormatter,
dataKey,
data
})));
}
function Slide(_ref5) {
var y = _ref5.y,
height = _ref5.height,
stroke = _ref5.stroke,
travellerWidth = _ref5.travellerWidth,
startX = _ref5.startX,
endX = _ref5.endX,
onMouseEnter = _ref5.onMouseEnter,
onMouseLeave = _ref5.onMouseLeave,
onMouseDown = _ref5.onMouseDown,
onTouchStart = _ref5.onTouchStart;
var x = Math.min(startX, endX) + travellerWidth;
var width = Math.max(Math.abs(endX - startX) - travellerWidth, 0);
return /*#__PURE__*/React.createElement("rect", {
className: "recharts-brush-slide",
onMouseEnter: onMouseEnter,
onMouseLeave: onMouseLeave,
onMouseDown: onMouseDown,
onTouchStart: onTouchStart,
style: {
cursor: 'move'
},
stroke: "none",
fill: stroke,
fillOpacity: 0.2,
x: x,
y: y,
width: width,
height: height
});
}
function Panorama(_ref6) {
var x = _ref6.x,
y = _ref6.y,
width = _ref6.width,
height = _ref6.height,
data = _ref6.data,
children = _ref6.children,
padding = _ref6.padding;
var isPanoramic = React.Children.count(children) === 1;
if (!isPanoramic) {
return null;
}
var chartElement = Children.only(children);
if (!chartElement) {
return null;
}
return /*#__PURE__*/React.cloneElement(chartElement, {
x,
y,
width,
height,
margin: padding,
compact: true,
data
});
}
var createScale = _ref7 => {
var data = _ref7.data,
startIndex = _ref7.startIndex,
endIndex = _ref7.endIndex,
x = _ref7.x,
width = _ref7.width,
travellerWidth = _ref7.travellerWidth;
if (!data || !data.length) {
return {};
}
var len = data.length;
var scale = scalePoint().domain(range(0, len)).range([x, x + width - travellerWidth]);
var scaleValues = scale.domain().map(entry => scale(entry)).filter(isNotNil);
return {
isTextActive: false,
isSlideMoving: false,
isTravellerMoving: false,
isTravellerFocused: false,
startX: scale(startIndex),
endX: scale(endIndex),
scale,
scaleValues
};
};
var isTouch = e => e.changedTouches && !!e.changedTouches.length;
class BrushWithState extends PureComponent {
constructor(props) {
super(props);
_defineProperty(this, "handleDrag", e => {
if (this.leaveTimer) {
clearTimeout(this.leaveTimer);
this.leaveTimer = null;
}
if (this.state.isTravellerMoving) {
this.handleTravellerMove(e);
} else if (this.state.isSlideMoving) {
this.handleSlideDrag(e);
}
});
_defineProperty(this, "handleTouchMove", e => {
var _e$changedTouches;
var touch = (_e$changedTouches = e.changedTouches) === null || _e$changedTouches === void 0 ? void 0 : _e$changedTouches[0];
if (touch != null) {
this.handleDrag(touch);
}
});
_defineProperty(this, "handleDragEnd", () => {
this.setState({
isTravellerMoving: false,
isSlideMoving: false
}, () => {
var _this$props = this.props,
endIndex = _this$props.endIndex,
onDragEnd = _this$props.onDragEnd,
startIndex = _this$props.startIndex;
onDragEnd === null || onDragEnd === void 0 || onDragEnd({
endIndex,
startIndex
});
});
this.detachDragEndListener();
});
_defineProperty(this, "handleLeaveWrapper", () => {
if (this.state.isTravellerMoving || this.state.isSlideMoving) {
this.leaveTimer = window.setTimeout(this.handleDragEnd, this.props.leaveTimeOut);
}
});
_defineProperty(this, "handleEnterSlideOrTraveller", () => {
this.setState({
isTextActive: true
});
});
_defineProperty(this, "handleLeaveSlideOrTraveller", () => {
this.setState({
isTextActive: false
});
});
_defineProperty(this, "handleSlideDragStart", e => {
var event = isTouch(e) ? e.changedTouches[0] : e;
if (event == null) {
return;
}
this.setState({
isTravellerMoving: false,
isSlideMoving: true,
slideMoveStartX: event.pageX
});
this.attachDragEndListener();
});
_defineProperty(this, "handleTravellerMoveKeyboard", (direction, id) => {
var _this$props2 = this.props,
data = _this$props2.data,
gap = _this$props2.gap,
startIndex = _this$props2.startIndex,
endIndex = _this$props2.endIndex;
// scaleValues are a list of coordinates. For example: [65, 250, 435, 620, 805, 990].
var _this$state = this.state,
scaleValues = _this$state.scaleValues,
startX = _this$state.startX,
endX = _this$state.endX;
if (scaleValues == null) {
return;
}
// unless we search for the closest scaleValue to the current coordinate
// we need to move travelers via index when using the keyboard
var currentIndex = -1;
if (id === 'startX') {
currentIndex = startIndex;
} else if (id === 'endX') {
currentIndex = endIndex;
}
if (currentIndex < 0 || currentIndex >= data.length) {
return;
}
var newIndex = currentIndex + direction;
if (newIndex === -1 || newIndex >= scaleValues.length) {
return;
}
var newScaleValue = scaleValues[newIndex];
if (newScaleValue == null) {
return;
}
// Prevent travellers from being on top of each other or overlapping
if (id === 'startX' && newScaleValue >= endX || id === 'endX' && newScaleValue <= startX) {
return;
}
this.setState(
// @ts-expect-error not sure why typescript is not happy with this, partial update is fine in React
{
[id]: newScaleValue
}, () => {
this.props.onChange(getIndex({
startX: this.state.startX,
endX: this.state.endX,
data,
gap,
scaleValues
}));
});
});
this.travellerDragStartHandlers = {
startX: this.handleTravellerDragStart.bind(this, 'startX'),
endX: this.handleTravellerDragStart.bind(this, 'endX')
};
this.state = {
brushMoveStartX: 0,
movingTravellerId: undefined,
endX: 0,
startX: 0,
slideMoveStartX: 0
};
}
static getDerivedStateFromProps(nextProps, prevState) {
var data = nextProps.data,
width = nextProps.width,
x = nextProps.x,
travellerWidth = nextProps.travellerWidth,
startIndex = nextProps.startIndex,
endIndex = nextProps.endIndex,
startIndexControlledFromProps = nextProps.startIndexControlledFromProps,
endIndexControlledFromProps = nextProps.endIndexControlledFromProps;
if (data !== prevState.prevData) {
return _objectSpread({
prevData: data,
prevTravellerWidth: travellerWidth,
prevX: x,
prevWidth: width
}, data && data.length ? createScale({
data,
width,
x,
travellerWidth,
startIndex,
endIndex
}) : {
scale: undefined,
scaleValues: undefined
});
}
var prevScale = prevState.scale;
if (prevScale && (width !== prevState.prevWidth || x !== prevState.prevX || travellerWidth !== prevState.prevTravellerWidth)) {
prevScale.range([x, x + width - travellerWidth]);
var scaleValues = prevScale.domain().map(entry => prevScale(entry)).filter(value => value != null);
return {
prevData: data,
prevTravellerWidth: travellerWidth,
prevX: x,
prevWidth: width,
startX: prevScale(nextProps.startIndex),
endX: prevScale(nextProps.endIndex),
scaleValues
};
}
if (prevState.scale && !prevState.isSlideMoving && !prevState.isTravellerMoving && !prevState.isTravellerFocused && !prevState.isTextActive) {
/*
* If the startIndex or endIndex are controlled from the outside,
* we need to keep the startX and end up to date.
* Also we do not want to do that while user is interacting in the brush,
* because this will trigger re-render and interrupt the drag&drop.
*/
if (startIndexControlledFromProps != null && prevState.prevStartIndexControlledFromProps !== startIndexControlledFromProps) {
return {
startX: prevState.scale(startIndexControlledFromProps),
prevStartIndexControlledFromProps: startIndexControlledFromProps
};
}
if (endIndexControlledFromProps != null && prevState.prevEndIndexControlledFromProps !== endIndexControlledFromProps) {
return {
endX: prevState.scale(endIndexControlledFromProps),
prevEndIndexControlledFromProps: endIndexControlledFromProps
};
}
}
return null;
}
componentWillUnmount() {
if (this.leaveTimer) {
clearTimeout(this.leaveTimer);
this.leaveTimer = null;
}
this.detachDragEndListener();
}
attachDragEndListener() {
window.addEventListener('mouseup', this.handleDragEnd, true);
window.addEventListener('touchend', this.handleDragEnd, true);
window.addEventListener('mousemove', this.handleDrag, true);
}
detachDragEndListener() {
window.removeEventListener('mouseup', this.handleDragEnd, true);
window.removeEventListener('touchend', this.handleDragEnd, true);
window.removeEventListener('mousemove', this.handleDrag, true);
}
handleSlideDrag(e) {
var _this$state2 = this.state,
slideMoveStartX = _this$state2.slideMoveStartX,
startX = _this$state2.startX,
endX = _this$state2.endX,
scaleValues = _this$state2.scaleValues;
if (scaleValues == null) {
return;
}
var _this$props3 = this.props,
x = _this$props3.x,
width = _this$props3.width,
travellerWidth = _this$props3.travellerWidth,
startIndex = _this$props3.startIndex,
endIndex = _this$props3.endIndex,
onChange = _this$props3.onChange,
data = _this$props3.data,
gap = _this$props3.gap;
var delta = e.pageX - slideMoveStartX;
if (delta > 0) {
delta = Math.min(delta, x + width - travellerWidth - endX, x + width - travellerWidth - startX);
} else if (delta < 0) {
delta = Math.max(delta, x - startX, x - endX);
}
var newIndex = getIndex({
startX: startX + delta,
endX: endX + delta,
data,
gap,
scaleValues
});
if ((newIndex.startIndex !== startIndex || newIndex.endIndex !== endIndex) && onChange) {
onChange(newIndex);
}
this.setState({
startX: startX + delta,
endX: endX + delta,
slideMoveStartX: e.pageX
});
}
handleTravellerDragStart(id, e) {
var event = isTouch(e) ? e.changedTouches[0] : e;
if (event == null) {
return;
}
this.setState({
isSlideMoving: false,
isTravellerMoving: true,
movingTravellerId: id,
brushMoveStartX: event.pageX
});
this.attachDragEndListener();
}
handleTravellerMove(e) {
var _this$state3 = this.state,
brushMoveStartX = _this$state3.brushMoveStartX,
movingTravellerId = _this$state3.movingTravellerId,
endX = _this$state3.endX,
startX = _this$state3.startX,
scaleValues = _this$state3.scaleValues;
if (movingTravellerId == null || scaleValues == null) {
return;
}
var prevValue = this.state[movingTravellerId];
var _this$props4 = this.props,
x = _this$props4.x,
width = _this$props4.width,
travellerWidth = _this$props4.travellerWidth,
onChange = _this$props4.onChange,
gap = _this$props4.gap,
data = _this$props4.data;
var params = {
startX: this.state.startX,
endX: this.state.endX,
data,
gap,
scaleValues
};
var delta = e.pageX - brushMoveStartX;
if (delta > 0) {
delta = Math.min(delta, x + width - travellerWidth - prevValue);
} else if (delta < 0) {
delta = Math.max(delta, x - prevValue);
}
params[movingTravellerId] = prevValue + delta;
var newIndex = getIndex(params);
var startIndex = newIndex.startIndex,
endIndex = newIndex.endIndex;
var isFullGap = () => {
var lastIndex = data.length - 1;
if (movingTravellerId === 'startX' && (endX > startX ? startIndex % gap === 0 : endIndex % gap === 0) || endX < startX && endIndex === lastIndex || movingTravellerId === 'endX' && (endX > startX ? endIndex % gap === 0 : startIndex % gap === 0) || endX > startX && endIndex === lastIndex) {
return true;
}
return false;
};
this.setState(
// @ts-expect-error not sure why typescript is not happy with this, partial update is fine in React
{
[movingTravellerId]: prevValue + delta,
brushMoveStartX: e.pageX
}, () => {
if (onChange) {
if (isFullGap()) {
onChange(newIndex);
}
}
});
}
render() {
var _this$props5 = this.props,
data = _this$props5.data,
className = _this$props5.className,
children = _this$props5.children,
x = _this$props5.x,
y = _this$props5.y,
dy = _this$props5.dy,
width = _this$props5.width,
height = _this$props5.height,
alwaysShowText = _this$props5.alwaysShowText,
fill = _this$props5.fill,
stroke = _this$props5.stroke,
startIndex = _this$props5.startIndex,
endIndex = _this$props5.endIndex,
travellerWidth = _this$props5.travellerWidth,
tickFormatter = _this$props5.tickFormatter,
dataKey = _this$props5.dataKey,
padding = _this$props5.padding;
var _this$state4 = this.state,
startX = _this$state4.startX,
endX = _this$state4.endX,
isTextActive = _this$state4.isTextActive,
isSlideMoving = _this$state4.isSlideMoving,
isTravellerMoving = _this$state4.isTravellerMoving,
isTravellerFocused = _this$state4.isTravellerFocused;
if (!data || !data.length || !isNumber(x) || !isNumber(y) || !isNumber(width) || !isNumber(height) || width <= 0 || height <= 0) {
return null;
}
var layerClass = clsx('recharts-brush', className);
var style = generatePrefixStyle('userSelect', 'none');
var calculatedY = y + (dy !== null && dy !== void 0 ? dy : 0);
return /*#__PURE__*/React.createElement(Layer, {
className: layerClass,
onMouseLeave: this.handleLeaveWrapper,
onTouchMove: this.handleTouchMove,
style: style
}, /*#__PURE__*/React.createElement(Background, {
x: x,
y: calculatedY,
width: width,
height: height,
fill: fill,
stroke: stroke
}), /*#__PURE__*/React.createElement(PanoramaContextProvider, null, /*#__PURE__*/React.createElement(Panorama, {
x: x,
y: calculatedY,
width: width,
height: height,
data: data,
padding: padding
}, children)), /*#__PURE__*/React.createElement(Slide, {
y: calculatedY,
height: height,
stroke: stroke,
travellerWidth: travellerWidth,
startX: startX,
endX: endX,
onMouseEnter: this.handleEnterSlideOrTraveller,
onMouseLeave: this.handleLeaveSlideOrTraveller,
onMouseDown: this.handleSlideDragStart,
onTouchStart: this.handleSlideDragStart
}), /*#__PURE__*/React.createElement(TravellerLayer, {
travellerX: startX,
id: "startX",
otherProps: _objectSpread(_objectSpread({}, this.props), {}, {
y: calculatedY
}),
onMouseEnter: this.handleEnterSlideOrTraveller,
onMouseLeave: this.handleLeaveSlideOrTraveller,
onMouseDown: this.travellerDragStartHandlers.startX,
onTouchStart: this.travellerDragStartHandlers.startX,
onTravellerMoveKeyboard: this.handleTravellerMoveKeyboard,
onFocus: () => {
this.setState({
isTravellerFocused: true
});
},
onBlur: () => {
this.setState({
isTravellerFocused: false
});
}
}), /*#__PURE__*/React.createElement(TravellerLayer, {
travellerX: endX,
id: "endX",
otherProps: _objectSpread(_objectSpread({}, this.props), {}, {
y: calculatedY
}),
onMouseEnter: this.handleEnterSlideOrTraveller,
onMouseLeave: this.handleLeaveSlideOrTraveller,
onMouseDown: this.travellerDragStartHandlers.endX,
onTouchStart: this.travellerDragStartHandlers.endX,
onTravellerMoveKeyboard: this.handleTravellerMoveKeyboard,
onFocus: () => {
this.setState({
isTravellerFocused: true
});
},
onBlur: () => {
this.setState({
isTravellerFocused: false
});
}
}), (isTextActive || isSlideMoving || isTravellerMoving || isTravellerFocused || alwaysShowText) && /*#__PURE__*/React.createElement(BrushText, {
startIndex: startIndex,
endIndex: endIndex,
y: calculatedY,
height: height,
travellerWidth: travellerWidth,
stroke: stroke,
tickFormatter: tickFormatter,
dataKey: dataKey,
data: data,
startX: startX,
endX: endX
}));
}
}
function BrushInternal(props) {
var dispatch = useAppDispatch();
var chartData = useChartData();
var dataIndexes = useDataIndex();
var onChangeFromContext = useContext(BrushUpdateDispatchContext);
var onChangeFromProps = props.onChange;
var startIndexFromProps = props.startIndex,
endIndexFromProps = props.endIndex;
useEffect(() => {
// start and end index can be controlled from props, and we need them to stay up-to-date in the Redux state too
dispatch(setDataStartEndIndexes({
startIndex: startIndexFromProps,
endIndex: endIndexFromProps
}));
}, [dispatch, endIndexFromProps, startIndexFromProps]);
useBrushChartSynchronisation();
var onChange = useCallback(nextState => {
if (dataIndexes == null) {
return;
}
var startIndex = dataIndexes.startIndex,
endIndex = dataIndexes.endIndex;
if (nextState.startIndex !== startIndex || nextState.endIndex !== endIndex) {
onChangeFromContext === null || onChangeFromContext === void 0 || onChangeFromContext(nextState);
onChangeFromProps === null || onChangeFromProps === void 0 || onChangeFromProps(nextState);
dispatch(setDataStartEndIndexes(nextState));
}
}, [onChangeFromProps, onChangeFromContext, dispatch, dataIndexes]);
var brushDimensions = useAppSelector(selectBrushDimensions);
if (brushDimensions == null || dataIndexes == null || chartData == null || !chartData.length) {
return null;
}
var startIndex = dataIndexes.startIndex,
endIndex = dataIndexes.endIndex;
var x = brushDimensions.x,
y = brushDimensions.y,
width = brushDimensions.width;
var contextProperties = {
data: chartData,
x,
y,
width,
startIndex,
endIndex,
onChange
};
return /*#__PURE__*/React.createElement(BrushWithState, _extends({}, props, contextProperties, {
startIndexControlledFromProps: startIndexFromProps !== null && startIndexFromProps !== void 0 ? startIndexFromProps : undefined,
endIndexControlledFromProps: endIndexFromProps !== null && endIndexFromProps !== void 0 ? endIndexFromProps : undefined
}));
}
function BrushSettingsDispatcher(props) {
var dispatch = useAppDispatch();
useEffect(() => {
dispatch(setBrushSettings(props));
return () => {
dispatch(setBrushSettings(null));
};
}, [dispatch, props]);
return null;
}
export var defaultBrushProps = {
height: 40,
travellerWidth: 5,
gap: 1,
fill: '#fff',
stroke: '#666',
padding: {
top: 1,
right: 1,
bottom: 1,
left: 1
},
leaveTimeOut: 1000,
alwaysShowText: false
};
/**
* Renders a scrollbar that allows the user to zoom and pan in the chart along its XAxis.
* It also allows you to render a small overview of the chart inside the brush that is always visible
* and shows the full data set so that the user can see where they are zoomed in.
*
* If a chart is synchronized with other charts using the `syncId` prop on the chart,
* the brush will also synchronize the zooming and panning between all synchronized charts.
*
* @see {@link https://recharts.github.io/en-US/examples/BrushBarChart/ BarChart with Brush}
* @see {@link https://recharts.github.io/en-US/examples/SynchronizedLineChart/ Synchronized Brush}
*
* @consumes CartesianChartContext
*/
export function Brush(outsideProps) {
var props = resolveDefaultProps(outsideProps, defaultBrushProps);
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(BrushSettingsDispatcher, {
height: props.height,
x: props.x,
y: props.y,
width: props.width,
padding: props.padding
}), /*#__PURE__*/React.createElement(BrushInternal, props));
}
Brush.displayName = 'Brush';

View file

@ -0,0 +1,488 @@
var _excluded = ["axisLine", "width", "height", "className", "hide", "ticks", "axisType", "axisId"];
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
/**
* @fileOverview Cartesian Axis
*/
import * as React from 'react';
import { useState, useRef, useCallback, forwardRef, useImperativeHandle, useEffect } from 'react';
import get from 'es-toolkit/compat/get';
import { clsx } from 'clsx';
import { Layer } from '../container/Layer';
import { Text, isValidTextAnchor } from '../component/Text';
import { CartesianLabelContextProvider, CartesianLabelFromLabelProp } from '../component/Label';
import { isNumber, noop } from '../util/DataUtils';
import { adaptEventsOfChild } from '../util/types';
import { getTicks } from './getTicks';
import { svgPropertiesNoEvents, svgPropertiesNoEventsFromUnknown } from '../util/svgPropertiesNoEvents';
import { getCalculatedYAxisWidth } from '../util/YAxisUtils';
import { resolveDefaultProps } from '../util/resolveDefaultProps';
import { ZIndexLayer } from '../zIndex/ZIndexLayer';
import { DefaultZIndexes } from '../zIndex/DefaultZIndexes';
import { getClassNameFromUnknown } from '../util/getClassNameFromUnknown';
import { removeRenderedTicks, setRenderedTicks } from '../state/renderedTicksSlice';
import { useAppDispatch } from '../state/hooks';
/** The orientation of the axis in correspondence to the chart */
/** A unit to be appended to a value */
/** The formatter function of tick */
export var defaultCartesianAxisProps = {
x: 0,
y: 0,
width: 0,
height: 0,
viewBox: {
x: 0,
y: 0,
width: 0,
height: 0
},
// The orientation of axis
orientation: 'bottom',
// The ticks
ticks: [],
stroke: '#666',
tickLine: true,
axisLine: true,
tick: true,
mirror: false,
minTickGap: 5,
// The width or height of tick
tickSize: 6,
tickMargin: 2,
interval: 'preserveEnd',
zIndex: DefaultZIndexes.axis
};
/*
* `viewBox` and `scale` are SVG attributes.
* Recharts however - unfortunately - has its own attributes named `viewBox` and `scale`
* that are completely different data shape and different purpose.
*/
function AxisLine(axisLineProps) {
var x = axisLineProps.x,
y = axisLineProps.y,
width = axisLineProps.width,
height = axisLineProps.height,
orientation = axisLineProps.orientation,
mirror = axisLineProps.mirror,
axisLine = axisLineProps.axisLine,
otherSvgProps = axisLineProps.otherSvgProps;
if (!axisLine) {
return null;
}
var props = _objectSpread(_objectSpread(_objectSpread({}, otherSvgProps), svgPropertiesNoEvents(axisLine)), {}, {
fill: 'none'
});
if (orientation === 'top' || orientation === 'bottom') {
var needHeight = +(orientation === 'top' && !mirror || orientation === 'bottom' && mirror);
props = _objectSpread(_objectSpread({}, props), {}, {
x1: x,
y1: y + needHeight * height,
x2: x + width,
y2: y + needHeight * height
});
} else {
var needWidth = +(orientation === 'left' && !mirror || orientation === 'right' && mirror);
props = _objectSpread(_objectSpread({}, props), {}, {
x1: x + needWidth * width,
y1: y,
x2: x + needWidth * width,
y2: y + height
});
}
return /*#__PURE__*/React.createElement("line", _extends({}, props, {
className: clsx('recharts-cartesian-axis-line', get(axisLine, 'className'))
}));
}
/**
* Calculate the coordinates of endpoints in ticks.
* @param data The data of a simple tick.
* @param x The x-coordinate of the axis.
* @param y The y-coordinate of the axis.
* @param width The width of the axis.
* @param height The height of the axis.
* @param orientation The orientation of the axis.
* @param tickSize The length of the tick line.
* @param mirror If true, the ticks are mirrored.
* @param tickMargin The margin between the tick line and the tick text.
* @returns An object with `line` and `tick` coordinates.
* `line` is the coordinates for the tick line, and `tick` is the coordinate for the tick text.
*/
function getTickLineCoord(data, x, y, width, height, orientation, tickSize, mirror, tickMargin) {
var x1, x2, y1, y2, tx, ty;
var sign = mirror ? -1 : 1;
var finalTickSize = data.tickSize || tickSize;
var tickCoord = isNumber(data.tickCoord) ? data.tickCoord : data.coordinate;
switch (orientation) {
case 'top':
x1 = x2 = data.coordinate;
y2 = y + +!mirror * height;
y1 = y2 - sign * finalTickSize;
ty = y1 - sign * tickMargin;
tx = tickCoord;
break;
case 'left':
y1 = y2 = data.coordinate;
x2 = x + +!mirror * width;
x1 = x2 - sign * finalTickSize;
tx = x1 - sign * tickMargin;
ty = tickCoord;
break;
case 'right':
y1 = y2 = data.coordinate;
x2 = x + +mirror * width;
x1 = x2 + sign * finalTickSize;
tx = x1 + sign * tickMargin;
ty = tickCoord;
break;
default:
x1 = x2 = data.coordinate;
y2 = y + +mirror * height;
y1 = y2 + sign * finalTickSize;
ty = y1 + sign * tickMargin;
tx = tickCoord;
break;
}
return {
line: {
x1,
y1,
x2,
y2
},
tick: {
x: tx,
y: ty
}
};
}
/**
* @param orientation The orientation of the axis.
* @param mirror If true, the ticks are mirrored.
* @returns The text anchor of the tick.
*/
function getTickTextAnchor(orientation, mirror) {
switch (orientation) {
case 'left':
return mirror ? 'start' : 'end';
case 'right':
return mirror ? 'end' : 'start';
default:
return 'middle';
}
}
/**
* @param orientation The orientation of the axis.
* @param mirror If true, the ticks are mirrored.
* @returns The vertical text anchor of the tick.
*/
function getTickVerticalAnchor(orientation, mirror) {
switch (orientation) {
case 'left':
case 'right':
return 'middle';
case 'top':
return mirror ? 'start' : 'end';
default:
return mirror ? 'end' : 'start';
}
}
function TickItem(props) {
var option = props.option,
tickProps = props.tickProps,
value = props.value;
var tickItem;
var combinedClassName = clsx(tickProps.className, 'recharts-cartesian-axis-tick-value');
if (/*#__PURE__*/React.isValidElement(option)) {
// @ts-expect-error element cloning is not typed
tickItem = /*#__PURE__*/React.cloneElement(option, _objectSpread(_objectSpread({}, tickProps), {}, {
className: combinedClassName
}));
} else if (typeof option === 'function') {
tickItem = option(_objectSpread(_objectSpread({}, tickProps), {}, {
className: combinedClassName
}));
} else {
var className = 'recharts-cartesian-axis-tick-value';
if (typeof option !== 'boolean') {
className = clsx(className, getClassNameFromUnknown(option));
}
tickItem = /*#__PURE__*/React.createElement(Text, _extends({}, tickProps, {
className: className
}), value);
}
return tickItem;
}
function RenderedTicksReporter(_ref) {
var ticks = _ref.ticks,
axisType = _ref.axisType,
axisId = _ref.axisId;
var dispatch = useAppDispatch();
useEffect(() => {
if (axisId == null || axisType == null) {
return noop;
}
// Filter out irrelevant internal properties before exposing externally
var tickItems = ticks.map(tick => ({
value: tick.value,
coordinate: tick.coordinate,
offset: tick.offset,
index: tick.index
}));
dispatch(setRenderedTicks({
ticks: tickItems,
axisId,
axisType
}));
return () => {
dispatch(removeRenderedTicks({
axisId,
axisType
}));
};
}, [dispatch, ticks, axisId, axisType]);
return null;
}
var Ticks = /*#__PURE__*/forwardRef((props, ref) => {
var _props$ticks = props.ticks,
ticks = _props$ticks === void 0 ? [] : _props$ticks,
tick = props.tick,
tickLine = props.tickLine,
stroke = props.stroke,
tickFormatter = props.tickFormatter,
unit = props.unit,
padding = props.padding,
tickTextProps = props.tickTextProps,
orientation = props.orientation,
mirror = props.mirror,
x = props.x,
y = props.y,
width = props.width,
height = props.height,
tickSize = props.tickSize,
tickMargin = props.tickMargin,
fontSize = props.fontSize,
letterSpacing = props.letterSpacing,
getTicksConfig = props.getTicksConfig,
events = props.events,
axisType = props.axisType,
axisId = props.axisId;
// @ts-expect-error some properties are optional in props but required in getTicks
var finalTicks = getTicks(_objectSpread(_objectSpread({}, getTicksConfig), {}, {
ticks
}), fontSize, letterSpacing);
var axisProps = svgPropertiesNoEvents(getTicksConfig);
var customTickProps = svgPropertiesNoEventsFromUnknown(tick);
// Use user-provided textAnchor if available, otherwise calculate from orientation/mirror
var textAnchor = isValidTextAnchor(axisProps.textAnchor) ? axisProps.textAnchor : getTickTextAnchor(orientation, mirror);
var verticalAnchor = getTickVerticalAnchor(orientation, mirror);
var tickLinePropsObject = {};
if (typeof tickLine === 'object') {
tickLinePropsObject = tickLine;
}
var tickLineProps = _objectSpread(_objectSpread({}, axisProps), {}, {
fill: 'none'
}, tickLinePropsObject);
var tickLineCoords = finalTicks.map(entry => _objectSpread({
entry
}, getTickLineCoord(entry, x, y, width, height, orientation, tickSize, mirror, tickMargin)));
var tickLines = tickLineCoords.map(_ref2 => {
var entry = _ref2.entry,
lineCoord = _ref2.line;
return /*#__PURE__*/React.createElement(Layer, {
className: "recharts-cartesian-axis-tick",
key: "tick-".concat(entry.value, "-").concat(entry.coordinate, "-").concat(entry.tickCoord)
}, tickLine && /*#__PURE__*/React.createElement("line", _extends({}, tickLineProps, lineCoord, {
className: clsx('recharts-cartesian-axis-tick-line', get(tickLine, 'className'))
})));
});
var tickLabels = tickLineCoords.map((_ref3, i) => {
var _ref4, _tickTextProps$angle;
var entry = _ref3.entry,
tickCoord = _ref3.tick;
// @ts-expect-error we're not checking that padding and orientation types are in sync
var tickProps = _objectSpread(_objectSpread(_objectSpread(_objectSpread({
verticalAnchor
}, axisProps), {}, {
textAnchor,
stroke: 'none',
fill: stroke
}, tickCoord), {}, {
index: i,
payload: entry,
visibleTicksCount: finalTicks.length,
tickFormatter,
padding
}, tickTextProps), {}, {
angle: (_ref4 = (_tickTextProps$angle = tickTextProps === null || tickTextProps === void 0 ? void 0 : tickTextProps.angle) !== null && _tickTextProps$angle !== void 0 ? _tickTextProps$angle : axisProps.angle) !== null && _ref4 !== void 0 ? _ref4 : 0
});
// @ts-expect-error customTickProps is contributing unknown props which we don't type properly
var finalTickProps = _objectSpread(_objectSpread({}, tickProps), customTickProps);
return /*#__PURE__*/React.createElement(Layer, _extends({
className: "recharts-cartesian-axis-tick-label",
key: "tick-label-".concat(entry.value, "-").concat(entry.coordinate, "-").concat(entry.tickCoord)
}, adaptEventsOfChild(events, entry, i)), tick && /*#__PURE__*/React.createElement(TickItem, {
option: tick,
tickProps: finalTickProps,
value: "".concat(typeof tickFormatter === 'function' ? tickFormatter(entry.value, i) : entry.value).concat(unit || '')
}));
});
return /*#__PURE__*/React.createElement("g", {
className: "recharts-cartesian-axis-ticks recharts-".concat(axisType, "-ticks")
}, /*#__PURE__*/React.createElement(RenderedTicksReporter, {
ticks: finalTicks,
axisId: axisId,
axisType: axisType
}), tickLabels.length > 0 && /*#__PURE__*/React.createElement(ZIndexLayer, {
zIndex: DefaultZIndexes.label
}, /*#__PURE__*/React.createElement("g", {
className: "recharts-cartesian-axis-tick-labels recharts-".concat(axisType, "-tick-labels"),
ref: ref
}, tickLabels)), tickLines.length > 0 && /*#__PURE__*/React.createElement("g", {
className: "recharts-cartesian-axis-tick-lines recharts-".concat(axisType, "-tick-lines")
}, tickLines));
});
var CartesianAxisComponent = /*#__PURE__*/forwardRef((props, ref) => {
var axisLine = props.axisLine,
width = props.width,
height = props.height,
className = props.className,
hide = props.hide,
ticks = props.ticks,
axisType = props.axisType,
axisId = props.axisId,
rest = _objectWithoutProperties(props, _excluded);
var _useState = useState(''),
_useState2 = _slicedToArray(_useState, 2),
fontSize = _useState2[0],
setFontSize = _useState2[1];
var _useState3 = useState(''),
_useState4 = _slicedToArray(_useState3, 2),
letterSpacing = _useState4[0],
setLetterSpacing = _useState4[1];
var tickRefs = useRef(null);
useImperativeHandle(ref, () => ({
getCalculatedWidth: () => {
var _props$labelRef;
return getCalculatedYAxisWidth({
ticks: tickRefs.current,
label: (_props$labelRef = props.labelRef) === null || _props$labelRef === void 0 ? void 0 : _props$labelRef.current,
labelGapWithTick: 5,
tickSize: props.tickSize,
tickMargin: props.tickMargin
});
}
}));
var layerRef = useCallback(el => {
if (el) {
var tickNodes = el.getElementsByClassName('recharts-cartesian-axis-tick-value');
tickRefs.current = tickNodes;
var tick = tickNodes[0];
if (tick) {
var computedStyle = window.getComputedStyle(tick);
var calculatedFontSize = computedStyle.fontSize;
var calculatedLetterSpacing = computedStyle.letterSpacing;
if (calculatedFontSize !== fontSize || calculatedLetterSpacing !== letterSpacing) {
setFontSize(calculatedFontSize);
setLetterSpacing(calculatedLetterSpacing);
}
}
}
}, [fontSize, letterSpacing]);
if (hide) {
return null;
}
/*
* This is different condition from what validateWidthHeight is doing;
* the CartesianAxis does allow width or height to be undefined.
*/
if (width != null && width <= 0 || height != null && height <= 0) {
return null;
}
return /*#__PURE__*/React.createElement(ZIndexLayer, {
zIndex: props.zIndex
}, /*#__PURE__*/React.createElement(Layer, {
className: clsx('recharts-cartesian-axis', className)
}, /*#__PURE__*/React.createElement(AxisLine, {
x: props.x,
y: props.y,
width: width,
height: height,
orientation: props.orientation,
mirror: props.mirror,
axisLine: axisLine,
otherSvgProps: svgPropertiesNoEvents(props)
}), /*#__PURE__*/React.createElement(Ticks, {
ref: layerRef,
axisType: axisType,
events: rest,
fontSize: fontSize,
getTicksConfig: props,
height: props.height,
letterSpacing: letterSpacing,
mirror: props.mirror,
orientation: props.orientation,
padding: props.padding,
stroke: props.stroke,
tick: props.tick,
tickFormatter: props.tickFormatter,
tickLine: props.tickLine,
tickMargin: props.tickMargin,
tickSize: props.tickSize,
tickTextProps: props.tickTextProps,
ticks: ticks,
unit: props.unit,
width: props.width,
x: props.x,
y: props.y,
axisId: axisId
}), /*#__PURE__*/React.createElement(CartesianLabelContextProvider, {
x: props.x,
y: props.y,
width: props.width,
height: props.height,
lowerWidth: props.width,
upperWidth: props.width
}, /*#__PURE__*/React.createElement(CartesianLabelFromLabelProp, {
label: props.label,
labelRef: props.labelRef
}), props.children)));
});
/**
* @deprecated
*
* This component is not meant to be used directly in app code.
* Use XAxis or YAxis instead.
*
* Starting from Recharts v4.0 we will make this component internal only.
*/
export var CartesianAxis = /*#__PURE__*/React.forwardRef((outsideProps, ref) => {
var props = resolveDefaultProps(outsideProps, defaultCartesianAxisProps);
return /*#__PURE__*/React.createElement(CartesianAxisComponent, _extends({}, props, {
ref: ref
}));
});
CartesianAxis.displayName = 'CartesianAxis';

View file

@ -0,0 +1,385 @@
var _excluded = ["x1", "y1", "x2", "y2", "key"],
_excluded2 = ["offset"],
_excluded3 = ["xAxisId", "yAxisId"],
_excluded4 = ["xAxisId", "yAxisId"];
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
import * as React from 'react';
import { warn } from '../util/LogUtils';
import { isNumber } from '../util/DataUtils';
import { getCoordinatesOfGrid, getTicksOfAxis } from '../util/ChartUtils';
import { getTicks } from './getTicks';
import { defaultCartesianAxisProps } from './CartesianAxis';
import { useChartHeight, useChartWidth, useOffsetInternal } from '../context/chartLayoutContext';
import { selectAxisPropsNeededForCartesianGridTicksGenerator } from '../state/selectors/axisSelectors';
import { useAppSelector } from '../state/hooks';
import { useIsPanorama } from '../context/PanoramaContext';
import { resolveDefaultProps } from '../util/resolveDefaultProps';
import { svgPropertiesNoEvents } from '../util/svgPropertiesNoEvents';
import { isPositiveNumber } from '../util/isWellBehavedNumber';
import { ZIndexLayer } from '../zIndex/ZIndexLayer';
import { DefaultZIndexes } from '../zIndex/DefaultZIndexes';
/**
* The <CartesianGrid horizontal
*/
var Background = props => {
var fill = props.fill;
if (!fill || fill === 'none') {
return null;
}
var fillOpacity = props.fillOpacity,
x = props.x,
y = props.y,
width = props.width,
height = props.height,
ry = props.ry;
return /*#__PURE__*/React.createElement("rect", {
x: x,
y: y,
ry: ry,
width: width,
height: height,
stroke: "none",
fill: fill,
fillOpacity: fillOpacity,
className: "recharts-cartesian-grid-bg"
});
};
function LineItem(_ref) {
var option = _ref.option,
lineItemProps = _ref.lineItemProps;
var lineItem;
if (/*#__PURE__*/React.isValidElement(option)) {
// @ts-expect-error typescript does not see the props type when cloning an element
lineItem = /*#__PURE__*/React.cloneElement(option, lineItemProps);
} else if (typeof option === 'function') {
lineItem = option(lineItemProps);
} else {
var _svgPropertiesNoEvent;
var x1 = lineItemProps.x1,
y1 = lineItemProps.y1,
x2 = lineItemProps.x2,
y2 = lineItemProps.y2,
key = lineItemProps.key,
others = _objectWithoutProperties(lineItemProps, _excluded);
var _ref2 = (_svgPropertiesNoEvent = svgPropertiesNoEvents(others)) !== null && _svgPropertiesNoEvent !== void 0 ? _svgPropertiesNoEvent : {},
__ = _ref2.offset,
restOfFilteredProps = _objectWithoutProperties(_ref2, _excluded2);
lineItem = /*#__PURE__*/React.createElement("line", _extends({}, restOfFilteredProps, {
x1: x1,
y1: y1,
x2: x2,
y2: y2,
fill: "none",
key: key
}));
}
return lineItem;
}
function HorizontalGridLines(props) {
var x = props.x,
width = props.width,
_props$horizontal = props.horizontal,
horizontal = _props$horizontal === void 0 ? true : _props$horizontal,
horizontalPoints = props.horizontalPoints;
if (!horizontal || !horizontalPoints || !horizontalPoints.length) {
return null;
}
var xAxisId = props.xAxisId,
yAxisId = props.yAxisId,
otherLineItemProps = _objectWithoutProperties(props, _excluded3);
var items = horizontalPoints.map((entry, i) => {
var lineItemProps = _objectSpread(_objectSpread({}, otherLineItemProps), {}, {
x1: x,
y1: entry,
x2: x + width,
y2: entry,
key: "line-".concat(i),
index: i
});
return /*#__PURE__*/React.createElement(LineItem, {
key: "line-".concat(i),
option: horizontal,
lineItemProps: lineItemProps
});
});
return /*#__PURE__*/React.createElement("g", {
className: "recharts-cartesian-grid-horizontal"
}, items);
}
function VerticalGridLines(props) {
var y = props.y,
height = props.height,
_props$vertical = props.vertical,
vertical = _props$vertical === void 0 ? true : _props$vertical,
verticalPoints = props.verticalPoints;
if (!vertical || !verticalPoints || !verticalPoints.length) {
return null;
}
var xAxisId = props.xAxisId,
yAxisId = props.yAxisId,
otherLineItemProps = _objectWithoutProperties(props, _excluded4);
var items = verticalPoints.map((entry, i) => {
var lineItemProps = _objectSpread(_objectSpread({}, otherLineItemProps), {}, {
x1: entry,
y1: y,
x2: entry,
y2: y + height,
key: "line-".concat(i),
index: i
});
return /*#__PURE__*/React.createElement(LineItem, {
option: vertical,
lineItemProps: lineItemProps,
key: "line-".concat(i)
});
});
return /*#__PURE__*/React.createElement("g", {
className: "recharts-cartesian-grid-vertical"
}, items);
}
function HorizontalStripes(props) {
var horizontalFill = props.horizontalFill,
fillOpacity = props.fillOpacity,
x = props.x,
y = props.y,
width = props.width,
height = props.height,
horizontalPoints = props.horizontalPoints,
_props$horizontal2 = props.horizontal,
horizontal = _props$horizontal2 === void 0 ? true : _props$horizontal2;
if (!horizontal || !horizontalFill || !horizontalFill.length || horizontalPoints == null) {
return null;
}
var roundedSortedHorizontalPoints = horizontalPoints.map(e => Math.round(e + y - y)).sort((a, b) => a - b);
// Why is this condition `!==` instead of `<=` ?
if (y !== roundedSortedHorizontalPoints[0]) {
roundedSortedHorizontalPoints.unshift(0);
}
var items = roundedSortedHorizontalPoints.map((entry, i) => {
// Why do we strip only the last stripe if it is invisible, and not all invisible stripes?
var nextPoint = roundedSortedHorizontalPoints[i + 1];
var lastStripe = nextPoint == null;
var lineHeight = lastStripe ? y + height - entry : nextPoint - entry;
if (lineHeight <= 0) {
return null;
}
var colorIndex = i % horizontalFill.length;
return /*#__PURE__*/React.createElement("rect", {
key: "react-".concat(i),
y: entry,
x: x,
height: lineHeight,
width: width,
stroke: "none",
fill: horizontalFill[colorIndex],
fillOpacity: fillOpacity,
className: "recharts-cartesian-grid-bg"
});
});
return /*#__PURE__*/React.createElement("g", {
className: "recharts-cartesian-gridstripes-horizontal"
}, items);
}
function VerticalStripes(props) {
var _props$vertical2 = props.vertical,
vertical = _props$vertical2 === void 0 ? true : _props$vertical2,
verticalFill = props.verticalFill,
fillOpacity = props.fillOpacity,
x = props.x,
y = props.y,
width = props.width,
height = props.height,
verticalPoints = props.verticalPoints;
if (!vertical || !verticalFill || !verticalFill.length) {
return null;
}
var roundedSortedVerticalPoints = verticalPoints.map(e => Math.round(e + x - x)).sort((a, b) => a - b);
if (x !== roundedSortedVerticalPoints[0]) {
roundedSortedVerticalPoints.unshift(0);
}
var items = roundedSortedVerticalPoints.map((entry, i) => {
var nextPoint = roundedSortedVerticalPoints[i + 1];
var lastStripe = nextPoint == null;
var lineWidth = lastStripe ? x + width - entry : nextPoint - entry;
if (lineWidth <= 0) {
return null;
}
var colorIndex = i % verticalFill.length;
return /*#__PURE__*/React.createElement("rect", {
key: "react-".concat(i),
x: entry,
y: y,
width: lineWidth,
height: height,
stroke: "none",
fill: verticalFill[colorIndex],
fillOpacity: fillOpacity,
className: "recharts-cartesian-grid-bg"
});
});
return /*#__PURE__*/React.createElement("g", {
className: "recharts-cartesian-gridstripes-vertical"
}, items);
}
var defaultVerticalCoordinatesGenerator = (_ref3, syncWithTicks) => {
var xAxis = _ref3.xAxis,
width = _ref3.width,
height = _ref3.height,
offset = _ref3.offset;
return getCoordinatesOfGrid(getTicks(_objectSpread(_objectSpread(_objectSpread({}, defaultCartesianAxisProps), xAxis), {}, {
ticks: getTicksOfAxis(xAxis, true),
viewBox: {
x: 0,
y: 0,
width,
height
}
})), offset.left, offset.left + offset.width, syncWithTicks);
};
var defaultHorizontalCoordinatesGenerator = (_ref4, syncWithTicks) => {
var yAxis = _ref4.yAxis,
width = _ref4.width,
height = _ref4.height,
offset = _ref4.offset;
return getCoordinatesOfGrid(getTicks(_objectSpread(_objectSpread(_objectSpread({}, defaultCartesianAxisProps), yAxis), {}, {
ticks: getTicksOfAxis(yAxis, true),
viewBox: {
x: 0,
y: 0,
width,
height
}
})), offset.top, offset.top + offset.height, syncWithTicks);
};
export var defaultCartesianGridProps = {
horizontal: true,
vertical: true,
// The ordinates of horizontal grid lines
horizontalPoints: [],
// The abscissas of vertical grid lines
verticalPoints: [],
stroke: '#ccc',
fill: 'none',
// The fill of colors of grid lines
verticalFill: [],
horizontalFill: [],
xAxisId: 0,
yAxisId: 0,
syncWithTicks: false,
zIndex: DefaultZIndexes.grid
};
/**
* Renders background grid with lines and fill colors in a Cartesian chart.
*
* @consumes CartesianChartContext
*/
export function CartesianGrid(props) {
var chartWidth = useChartWidth();
var chartHeight = useChartHeight();
var offset = useOffsetInternal();
var propsIncludingDefaults = _objectSpread(_objectSpread({}, resolveDefaultProps(props, defaultCartesianGridProps)), {}, {
x: isNumber(props.x) ? props.x : offset.left,
y: isNumber(props.y) ? props.y : offset.top,
width: isNumber(props.width) ? props.width : offset.width,
height: isNumber(props.height) ? props.height : offset.height
});
var xAxisId = propsIncludingDefaults.xAxisId,
yAxisId = propsIncludingDefaults.yAxisId,
x = propsIncludingDefaults.x,
y = propsIncludingDefaults.y,
width = propsIncludingDefaults.width,
height = propsIncludingDefaults.height,
syncWithTicks = propsIncludingDefaults.syncWithTicks,
horizontalValues = propsIncludingDefaults.horizontalValues,
verticalValues = propsIncludingDefaults.verticalValues;
var isPanorama = useIsPanorama();
var xAxis = useAppSelector(state => selectAxisPropsNeededForCartesianGridTicksGenerator(state, 'xAxis', xAxisId, isPanorama));
var yAxis = useAppSelector(state => selectAxisPropsNeededForCartesianGridTicksGenerator(state, 'yAxis', yAxisId, isPanorama));
if (!isPositiveNumber(width) || !isPositiveNumber(height) || !isNumber(x) || !isNumber(y)) {
return null;
}
/*
* verticalCoordinatesGenerator and horizontalCoordinatesGenerator are defined
* outside the propsIncludingDefaults because they were never part of the original props
* and they were never passed as a prop down to horizontal/vertical custom elements.
* If we add these two to propsIncludingDefaults then we are changing public API.
* Not a bad thing per se but also not necessary.
*/
var verticalCoordinatesGenerator = propsIncludingDefaults.verticalCoordinatesGenerator || defaultVerticalCoordinatesGenerator;
var horizontalCoordinatesGenerator = propsIncludingDefaults.horizontalCoordinatesGenerator || defaultHorizontalCoordinatesGenerator;
var horizontalPoints = propsIncludingDefaults.horizontalPoints,
verticalPoints = propsIncludingDefaults.verticalPoints;
// No horizontal points are specified
if ((!horizontalPoints || !horizontalPoints.length) && typeof horizontalCoordinatesGenerator === 'function') {
var isHorizontalValues = horizontalValues && horizontalValues.length;
var generatorResult = horizontalCoordinatesGenerator({
yAxis: yAxis ? _objectSpread(_objectSpread({}, yAxis), {}, {
ticks: isHorizontalValues ? horizontalValues : yAxis.ticks
}) : undefined,
width: chartWidth !== null && chartWidth !== void 0 ? chartWidth : width,
height: chartHeight !== null && chartHeight !== void 0 ? chartHeight : height,
offset
}, isHorizontalValues ? true : syncWithTicks);
warn(Array.isArray(generatorResult), "horizontalCoordinatesGenerator should return Array but instead it returned [".concat(typeof generatorResult, "]"));
if (Array.isArray(generatorResult)) {
horizontalPoints = generatorResult;
}
}
// No vertical points are specified
if ((!verticalPoints || !verticalPoints.length) && typeof verticalCoordinatesGenerator === 'function') {
var isVerticalValues = verticalValues && verticalValues.length;
var _generatorResult = verticalCoordinatesGenerator({
xAxis: xAxis ? _objectSpread(_objectSpread({}, xAxis), {}, {
ticks: isVerticalValues ? verticalValues : xAxis.ticks
}) : undefined,
width: chartWidth !== null && chartWidth !== void 0 ? chartWidth : width,
height: chartHeight !== null && chartHeight !== void 0 ? chartHeight : height,
offset
}, isVerticalValues ? true : syncWithTicks);
warn(Array.isArray(_generatorResult), "verticalCoordinatesGenerator should return Array but instead it returned [".concat(typeof _generatorResult, "]"));
if (Array.isArray(_generatorResult)) {
verticalPoints = _generatorResult;
}
}
return /*#__PURE__*/React.createElement(ZIndexLayer, {
zIndex: propsIncludingDefaults.zIndex
}, /*#__PURE__*/React.createElement("g", {
className: "recharts-cartesian-grid"
}, /*#__PURE__*/React.createElement(Background, {
fill: propsIncludingDefaults.fill,
fillOpacity: propsIncludingDefaults.fillOpacity,
x: propsIncludingDefaults.x,
y: propsIncludingDefaults.y,
width: propsIncludingDefaults.width,
height: propsIncludingDefaults.height,
ry: propsIncludingDefaults.ry
}), /*#__PURE__*/React.createElement(HorizontalStripes, _extends({}, propsIncludingDefaults, {
horizontalPoints: horizontalPoints
})), /*#__PURE__*/React.createElement(VerticalStripes, _extends({}, propsIncludingDefaults, {
verticalPoints: verticalPoints
})), /*#__PURE__*/React.createElement(HorizontalGridLines, _extends({}, propsIncludingDefaults, {
offset: offset,
horizontalPoints: horizontalPoints,
xAxis: xAxis,
yAxis: yAxis
})), /*#__PURE__*/React.createElement(VerticalGridLines, _extends({}, propsIncludingDefaults, {
offset: offset,
verticalPoints: verticalPoints,
xAxis: xAxis,
yAxis: yAxis
}))));
}
CartesianGrid.displayName = 'CartesianGrid';

View file

@ -0,0 +1,255 @@
var _excluded = ["direction", "width", "dataKey", "isAnimationActive", "animationBegin", "animationDuration", "animationEasing"];
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
/**
* @fileOverview Render a group of error bar
*/
import * as React from 'react';
import { Layer } from '../container/Layer';
import { ReportErrorBarSettings, useErrorBarContext } from '../context/ErrorBarContext';
import { useXAxis, useYAxis } from '../hooks';
import { resolveDefaultProps } from '../util/resolveDefaultProps';
import { svgPropertiesNoEvents } from '../util/svgPropertiesNoEvents';
import { useChartLayout } from '../context/chartLayoutContext';
import { CSSTransitionAnimate, extractCssEasing } from '../animation/CSSTransitionAnimate';
import { ZIndexLayer } from '../zIndex/ZIndexLayer';
import { DefaultZIndexes } from '../zIndex/DefaultZIndexes';
/**
* So usually the direction is decided by the chart layout.
* Horizontal layout means error bars are vertical means direction=y
* Vertical layout means error bars are horizontal means direction=x
*
* Except! In Scatter chart, error bars can go both ways.
*
* So this property is only ever used in Scatter chart, and ignored elsewhere.
*/
/**
* External ErrorBar props, visible for users of the library
*/
/**
* Props after defaults, and required props have been applied.
*/
function ErrorBarImpl(props) {
var direction = props.direction,
width = props.width,
dataKey = props.dataKey,
isAnimationActive = props.isAnimationActive,
animationBegin = props.animationBegin,
animationDuration = props.animationDuration,
animationEasing = props.animationEasing,
others = _objectWithoutProperties(props, _excluded);
var svgProps = svgPropertiesNoEvents(others);
var _useErrorBarContext = useErrorBarContext(),
data = _useErrorBarContext.data,
dataPointFormatter = _useErrorBarContext.dataPointFormatter,
xAxisId = _useErrorBarContext.xAxisId,
yAxisId = _useErrorBarContext.yAxisId,
offset = _useErrorBarContext.errorBarOffset;
var xAxis = useXAxis(xAxisId);
var yAxis = useYAxis(yAxisId);
if ((xAxis === null || xAxis === void 0 ? void 0 : xAxis.scale) == null || (yAxis === null || yAxis === void 0 ? void 0 : yAxis.scale) == null || data == null) {
return null;
}
// ErrorBar requires type number XAxis, why?
if (direction === 'x' && xAxis.type !== 'number') {
return null;
}
var errorBars = data.map((entry, dataIndex) => {
var _dataPointFormatter = dataPointFormatter(entry, dataKey, direction),
x = _dataPointFormatter.x,
y = _dataPointFormatter.y,
value = _dataPointFormatter.value,
errorVal = _dataPointFormatter.errorVal;
if (!errorVal || x == null || y == null) {
return null;
}
var lineCoordinates = [];
var lowBound, highBound;
if (Array.isArray(errorVal)) {
var _errorVal = _slicedToArray(errorVal, 2),
low = _errorVal[0],
high = _errorVal[1];
if (low == null || high == null) {
return null;
}
lowBound = low;
highBound = high;
} else {
lowBound = highBound = errorVal;
}
if (direction === 'x') {
// error bar for horizontal charts, the y is fixed, x is a range value
var scale = xAxis.scale;
var yMid = y + offset;
var yMin = yMid + width;
var yMax = yMid - width;
var xMin = scale.map(value - lowBound);
var xMax = scale.map(value + highBound);
if (xMin != null && xMax != null) {
// the right line of |--|
lineCoordinates.push({
x1: xMax,
y1: yMin,
x2: xMax,
y2: yMax
});
// the middle line of |--|
lineCoordinates.push({
x1: xMin,
y1: yMid,
x2: xMax,
y2: yMid
});
// the left line of |--|
lineCoordinates.push({
x1: xMin,
y1: yMin,
x2: xMin,
y2: yMax
});
}
} else if (direction === 'y') {
// error bar for horizontal charts, the x is fixed, y is a range value
var _scale = yAxis.scale;
var xMid = x + offset;
var _xMin = xMid - width;
var _xMax = xMid + width;
var _yMin = _scale.map(value - lowBound);
var _yMax = _scale.map(value + highBound);
if (_yMin != null && _yMax != null) {
// the top line
lineCoordinates.push({
x1: _xMin,
y1: _yMax,
x2: _xMax,
y2: _yMax
});
// the middle line
lineCoordinates.push({
x1: xMid,
y1: _yMin,
x2: xMid,
y2: _yMax
});
// the bottom line
lineCoordinates.push({
x1: _xMin,
y1: _yMin,
x2: _xMax,
y2: _yMin
});
}
}
var scaleDirection = direction === 'x' ? 'scaleX' : 'scaleY';
var transformOrigin = "".concat(x + offset, "px ").concat(y + offset, "px");
return /*#__PURE__*/React.createElement(Layer, _extends({
className: "recharts-errorBar",
key: "bar-".concat(x, "-").concat(y, "-").concat(value, "-").concat(dataIndex)
}, svgProps), lineCoordinates.map((c, lineIndex) => {
var lineStyle = isAnimationActive ? {
transformOrigin
} : undefined;
return /*#__PURE__*/React.createElement(CSSTransitionAnimate, {
animationId: "error-bar-".concat(direction, "_").concat(c.x1, "-").concat(c.x2, "-").concat(c.y1, "-").concat(c.y2),
from: "".concat(scaleDirection, "(0)"),
to: "".concat(scaleDirection, "(1)"),
attributeName: "transform",
begin: animationBegin,
easing: extractCssEasing(animationEasing),
isActive: isAnimationActive,
duration: animationDuration,
key: "errorbar-".concat(dataIndex, "-").concat(c.x1, "-").concat(c.y1, "-").concat(c.x2, "-").concat(c.y2, "-").concat(lineIndex)
}, style => /*#__PURE__*/React.createElement("line", _extends({}, c, {
style: _objectSpread(_objectSpread({}, lineStyle), style)
})));
}));
});
return /*#__PURE__*/React.createElement(Layer, {
className: "recharts-errorBars"
}, errorBars);
}
function useErrorBarDirection(directionFromProps) {
var layout = useChartLayout();
if (directionFromProps != null) {
return directionFromProps;
}
if (layout != null) {
return layout === 'horizontal' ? 'y' : 'x';
}
return 'x';
}
export var errorBarDefaultProps = {
stroke: 'black',
strokeWidth: 1.5,
width: 5,
offset: 0,
isAnimationActive: true,
animationBegin: 0,
animationDuration: 400,
animationEasing: 'ease-in-out',
zIndex: DefaultZIndexes.line
};
/**
* ErrorBar renders whiskers to represent error margins on a chart.
*
* It must be a child of a graphical element.
*
* ErrorBar expects data in one of the following forms:
* - Symmetric error bars: a single error value representing both lower and upper bounds.
* - Asymmetric error bars: an array of two values representing lower and upper bounds separately. First value is the lower bound, second value is the upper bound.
*
* The values provided are relative to the main data value.
* For example, if the main data value is 10 and the error value is 2,
* the error bar will extend from 8 to 12 for symmetric error bars.
*
* In other words, what ErrorBar will render is:
* - For symmetric error bars: [value - errorVal, value + errorVal]
* - For asymmetric error bars: [value - errorVal[0], value + errorVal[1]]
*
* In stacked or ranged Bar charts, ErrorBar will use the higher data value
* as the reference point for calculating the error bar positions.
*
* @consumes ErrorBarContext
*/
export function ErrorBar(outsideProps) {
var realDirection = useErrorBarDirection(outsideProps.direction);
var props = resolveDefaultProps(outsideProps, errorBarDefaultProps);
var width = props.width,
isAnimationActive = props.isAnimationActive,
animationBegin = props.animationBegin,
animationDuration = props.animationDuration,
animationEasing = props.animationEasing,
zIndex = props.zIndex;
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ReportErrorBarSettings, {
dataKey: props.dataKey,
direction: realDirection
}), /*#__PURE__*/React.createElement(ZIndexLayer, {
zIndex: zIndex
}, /*#__PURE__*/React.createElement(ErrorBarImpl, _extends({}, props, {
direction: realDirection,
width: width,
isAnimationActive: isAnimationActive,
animationBegin: animationBegin,
animationDuration: animationDuration,
animationEasing: animationEasing
}))));
}
ErrorBar.displayName = 'ErrorBar';

467
frontend/node_modules/recharts/es6/cartesian/Funnel.js generated vendored Normal file
View file

@ -0,0 +1,467 @@
var _excluded = ["onMouseEnter", "onClick", "onMouseLeave", "shape", "activeShape"],
_excluded2 = ["id"],
_excluded3 = ["stroke", "fill", "legendType", "hide", "isAnimationActive", "animationBegin", "animationDuration", "animationEasing", "nameKey", "lastShapeType", "id"],
_excluded4 = ["id"];
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
import * as React from 'react';
import { useMemo, useRef } from 'react';
import omit from 'es-toolkit/compat/omit';
import { clsx } from 'clsx';
import { selectActiveIndex } from '../state/selectors/selectors';
import { useAppSelector } from '../state/hooks';
import { Layer } from '../container/Layer';
import { CartesianLabelListContextProvider, LabelListFromLabelProp } from '../component/LabelList';
import { getPercentValue, interpolate } from '../util/DataUtils';
import { getValueByDataKey } from '../util/ChartUtils';
import { adaptEventsOfChild } from '../util/types';
import { defaultFunnelShape, FunnelTrapezoid } from '../util/FunnelUtils';
import { useMouseClickItemDispatch, useMouseEnterItemDispatch, useMouseLeaveItemDispatch } from '../context/tooltipContext';
import { SetTooltipEntrySettings } from '../state/SetTooltipEntrySettings';
import { selectFunnelTrapezoids } from '../state/selectors/funnelSelectors';
import { findAllByType } from '../util/ReactUtils';
import { Cell } from '../component/Cell';
import { resolveDefaultProps } from '../util/resolveDefaultProps';
import { usePlotArea } from '../hooks';
import { svgPropertiesNoEvents } from '../util/svgPropertiesNoEvents';
import { AnimatedItems, useAnimationCallbacks } from '../animation/AnimatedItems';
import { matchAppend } from '../animation/matchBy';
import { RegisterGraphicalItemId } from '../context/RegisterGraphicalItemId';
import { useCartesianChartLayout } from '../context/chartLayoutContext';
/**
* Internal props, combination of external props + defaultProps + private Recharts state
*/
/**
* External props, intended for end users to fill in
*/
var SetFunnelTooltipEntrySettings = /*#__PURE__*/React.memo(_ref => {
var dataKey = _ref.dataKey,
nameKey = _ref.nameKey,
stroke = _ref.stroke,
strokeWidth = _ref.strokeWidth,
fill = _ref.fill,
name = _ref.name,
hide = _ref.hide,
tooltipType = _ref.tooltipType,
formatter = _ref.formatter,
data = _ref.data,
trapezoids = _ref.trapezoids,
id = _ref.id;
var tooltipEntrySettings = {
dataDefinedOnItem: data,
getPosition: index => {
var _trapezoids$Number;
return (_trapezoids$Number = trapezoids[Number(index)]) === null || _trapezoids$Number === void 0 ? void 0 : _trapezoids$Number.tooltipPosition;
},
settings: {
stroke,
strokeWidth,
fill,
dataKey,
name,
nameKey,
hide,
type: tooltipType,
color: fill,
unit: '',
// Funnel does not have unit, why?
formatter,
graphicalItemId: id
}
};
return /*#__PURE__*/React.createElement(SetTooltipEntrySettings, {
tooltipEntrySettings: tooltipEntrySettings
});
});
function FunnelLabelListProvider(_ref2) {
var showLabels = _ref2.showLabels,
trapezoids = _ref2.trapezoids,
children = _ref2.children;
var labelListEntries = useMemo(() => {
if (!showLabels) {
return undefined;
}
return trapezoids === null || trapezoids === void 0 ? void 0 : trapezoids.map(entry => {
var viewBox = entry.labelViewBox;
return _objectSpread(_objectSpread({}, viewBox), {}, {
value: entry.name,
payload: entry.payload,
parentViewBox: entry.parentViewBox,
viewBox,
fill: entry.fill
});
});
}, [showLabels, trapezoids]);
return /*#__PURE__*/React.createElement(CartesianLabelListContextProvider, {
value: labelListEntries
}, children);
}
function FunnelTrapezoids(props) {
var trapezoids = props.trapezoids,
allOtherFunnelProps = props.allOtherFunnelProps,
animationElapsedTime = props.animationElapsedTime,
isAnimating = props.isAnimating,
isEntrance = props.isEntrance;
var activeItemIndex = useAppSelector(state => selectActiveIndex(state, 'item', state.tooltip.settings.trigger, undefined));
var onMouseEnterFromProps = allOtherFunnelProps.onMouseEnter,
onItemClickFromProps = allOtherFunnelProps.onClick,
onMouseLeaveFromProps = allOtherFunnelProps.onMouseLeave,
shape = allOtherFunnelProps.shape,
activeShape = allOtherFunnelProps.activeShape,
restOfAllOtherProps = _objectWithoutProperties(allOtherFunnelProps, _excluded);
var onMouseEnterFromContext = useMouseEnterItemDispatch(onMouseEnterFromProps, allOtherFunnelProps.dataKey, allOtherFunnelProps.id);
var onMouseLeaveFromContext = useMouseLeaveItemDispatch(onMouseLeaveFromProps);
var onClickFromContext = useMouseClickItemDispatch(onItemClickFromProps, allOtherFunnelProps.dataKey, allOtherFunnelProps.id);
return /*#__PURE__*/React.createElement(React.Fragment, null, trapezoids.map((entry, i) => {
var isActiveIndex = Boolean(activeShape) && activeItemIndex === String(i);
var trapezoidOptions = isActiveIndex ? activeShape : shape;
var _entry$option$isActiv = _objectSpread(_objectSpread({}, entry), {}, {
option: trapezoidOptions,
isActive: isActiveIndex,
stroke: entry.stroke,
animationElapsedTime,
isAnimating,
isEntrance
}),
id = _entry$option$isActiv.id,
trapezoidProps = _objectWithoutProperties(_entry$option$isActiv, _excluded2);
return /*#__PURE__*/React.createElement(Layer, _extends({
key: "trapezoid-".concat(entry === null || entry === void 0 ? void 0 : entry.x, "-").concat(entry === null || entry === void 0 ? void 0 : entry.y, "-").concat(entry === null || entry === void 0 ? void 0 : entry.name, "-").concat(entry === null || entry === void 0 ? void 0 : entry.value),
className: "recharts-funnel-trapezoid"
}, adaptEventsOfChild(restOfAllOtherProps, entry, i), {
onMouseEnter: onMouseEnterFromContext(entry, i),
onMouseLeave: onMouseLeaveFromContext(entry, i),
onClick: onClickFromContext(entry, i)
}), /*#__PURE__*/React.createElement(FunnelTrapezoid, trapezoidProps));
}));
}
var defaultFunnelAnimateItems = (items, animationElapsedTime) => {
if (items == null) return [];
if (animationElapsedTime === 1) {
return items.flatMap(item => item.status === 'removed' ? [] : [item.next]);
}
return items.flatMap(item => {
if (item.status === 'removed') return [];
if (item.status === 'matched') {
return [_objectSpread(_objectSpread({}, item.next), {}, {
x: interpolate(item.prev.x, item.next.x, animationElapsedTime),
y: interpolate(item.prev.y, item.next.y, animationElapsedTime),
upperWidth: interpolate(item.prev.upperWidth, item.next.upperWidth, animationElapsedTime),
lowerWidth: interpolate(item.prev.lowerWidth, item.next.lowerWidth, animationElapsedTime),
height: interpolate(item.prev.height, item.next.height, animationElapsedTime)
})];
}
// added
var next = item.next;
return [_objectSpread(_objectSpread({}, next), {}, {
x: interpolate(next.x + next.upperWidth / 2, next.x, animationElapsedTime),
y: interpolate(next.y + next.height / 2, next.y, animationElapsedTime),
upperWidth: interpolate(0, next.upperWidth, animationElapsedTime),
lowerWidth: interpolate(0, next.lowerWidth, animationElapsedTime),
height: interpolate(0, next.height, animationElapsedTime)
})];
});
};
function TrapezoidsWithAnimation(_ref3) {
var previousTrapezoidsRef = _ref3.previousTrapezoidsRef,
props = _ref3.props;
var trapezoids = props.trapezoids,
isAnimationActive = props.isAnimationActive,
animationBegin = props.animationBegin,
animationDuration = props.animationDuration,
animationEasing = props.animationEasing,
animationInterpolateFn = props.animationInterpolateFn;
var layout = useCartesianChartLayout();
var _useAnimationCallback = useAnimationCallbacks(props.onAnimationStart, props.onAnimationEnd),
isAnimating = _useAnimationCallback.isAnimating,
handleAnimationStart = _useAnimationCallback.handleAnimationStart,
handleAnimationEnd = _useAnimationCallback.handleAnimationEnd;
if (layout == null) return null;
return /*#__PURE__*/React.createElement(FunnelLabelListProvider, {
showLabels: !isAnimating,
trapezoids: trapezoids
}, /*#__PURE__*/React.createElement(AnimatedItems, {
animationInput: trapezoids,
animationIdPrefix: "recharts-funnel-",
items: trapezoids,
previousItemsRef: previousTrapezoidsRef,
isAnimationActive: isAnimationActive,
animationBegin: animationBegin,
animationDuration: animationDuration,
animationEasing: animationEasing,
onAnimationStart: handleAnimationStart,
onAnimationEnd: handleAnimationEnd,
animationInterpolateFn: animationInterpolateFn,
animationMatchBy: props.animationMatchBy,
layout: layout
}, (stepData, animationElapsedTime, isEntrance) => /*#__PURE__*/React.createElement(Layer, null, /*#__PURE__*/React.createElement(FunnelTrapezoids, {
trapezoids: stepData,
allOtherFunnelProps: props,
animationElapsedTime: animationElapsedTime,
isAnimating: isAnimating || animationElapsedTime < 1,
isEntrance: isEntrance
}))), /*#__PURE__*/React.createElement(LabelListFromLabelProp, {
label: props.label
}), props.children);
}
function RenderTrapezoids(props) {
var previousTrapezoidsRef = useRef(undefined);
return /*#__PURE__*/React.createElement(TrapezoidsWithAnimation, {
props: props,
previousTrapezoidsRef: previousTrapezoidsRef
});
}
var getRealWidthHeight = (customWidth, offset) => {
var width = offset.width,
height = offset.height,
left = offset.left,
top = offset.top;
var realWidth = getPercentValue(customWidth, width, width);
return {
realWidth,
realHeight: height,
offsetX: left,
offsetY: top
};
};
export var defaultFunnelProps = {
animationBegin: 400,
animationDuration: 1500,
animationEasing: 'ease',
animationInterpolateFn: defaultFunnelAnimateItems,
animationMatchBy: matchAppend,
fill: '#808080',
hide: false,
isAnimationActive: 'auto',
lastShapeType: 'triangle',
legendType: 'rect',
nameKey: 'name',
reversed: false,
shape: defaultFunnelShape,
stroke: '#fff'
};
function FunnelImpl(props) {
var plotArea = usePlotArea();
var stroke = props.stroke,
fill = props.fill,
legendType = props.legendType,
hide = props.hide,
isAnimationActive = props.isAnimationActive,
animationBegin = props.animationBegin,
animationDuration = props.animationDuration,
animationEasing = props.animationEasing,
nameKey = props.nameKey,
lastShapeType = props.lastShapeType,
id = props.id,
everythingElse = _objectWithoutProperties(props, _excluded3);
var presentationProps = svgPropertiesNoEvents(props);
var cells = findAllByType(props.children, Cell);
var funnelSettings = useMemo(() => ({
dataKey: props.dataKey,
nameKey,
data: props.data,
tooltipType: props.tooltipType,
lastShapeType,
reversed: props.reversed,
customWidth: props.width,
cells,
presentationProps,
id
}), [props.dataKey, nameKey, props.data, props.tooltipType, lastShapeType, props.reversed, props.width, cells, presentationProps, id]);
var trapezoids = useAppSelector(state => selectFunnelTrapezoids(state, funnelSettings));
if (hide || !trapezoids || !trapezoids.length || !plotArea) {
return null;
}
var height = plotArea.height,
width = plotArea.width;
var layerClass = clsx('recharts-trapezoids', props.className);
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(SetFunnelTooltipEntrySettings, {
dataKey: props.dataKey,
nameKey: props.nameKey,
stroke: props.stroke,
strokeWidth: props.strokeWidth,
fill: props.fill,
name: props.name,
hide: props.hide,
tooltipType: props.tooltipType,
formatter: props.formatter,
data: props.data,
trapezoids: trapezoids,
id: id
}), /*#__PURE__*/React.createElement(Layer, {
className: layerClass
}, /*#__PURE__*/React.createElement(RenderTrapezoids, _extends({}, everythingElse, {
id: id,
stroke: stroke,
fill: fill,
nameKey: nameKey,
lastShapeType: lastShapeType,
animationBegin: animationBegin,
animationDuration: animationDuration,
animationEasing: animationEasing,
isAnimationActive: isAnimationActive,
hide: hide,
legendType: legendType,
height: height,
width: width,
trapezoids: trapezoids
}))));
}
export function computeFunnelTrapezoids(_ref4) {
var dataKey = _ref4.dataKey,
nameKey = _ref4.nameKey,
displayedData = _ref4.displayedData,
tooltipType = _ref4.tooltipType,
lastShapeType = _ref4.lastShapeType,
reversed = _ref4.reversed,
offset = _ref4.offset,
customWidth = _ref4.customWidth,
graphicalItemId = _ref4.graphicalItemId;
var _getRealWidthHeight = getRealWidthHeight(customWidth, offset),
realHeight = _getRealWidthHeight.realHeight,
realWidth = _getRealWidthHeight.realWidth,
offsetX = _getRealWidthHeight.offsetX,
offsetY = _getRealWidthHeight.offsetY;
var values = displayedData.map(entry => {
var val = getValueByDataKey(entry, dataKey, 0);
return typeof val === 'number' ? val : 0;
});
var maxValue = Math.max.apply(null, values);
var len = displayedData.length;
var rowHeight = realHeight / len;
var parentViewBox = {
x: offset.left,
y: offset.top,
width: offset.width,
height: offset.height
};
var trapezoids = displayedData.map((entry, i) => {
// getValueByDataKey does not validate the output type
var rawVal = getValueByDataKey(entry, dataKey, 0);
var name = String(getValueByDataKey(entry, nameKey, i));
var val = rawVal;
var nextVal;
if (i !== len - 1) {
var nextDataValue = getValueByDataKey(displayedData[i + 1], dataKey, 0);
if (typeof nextDataValue === 'number') {
nextVal = nextDataValue;
} else if (Array.isArray(nextDataValue)) {
var _nextDataValue = _slicedToArray(nextDataValue, 2),
first = _nextDataValue[0],
second = _nextDataValue[1];
if (typeof first === 'number') {
val = first;
}
if (typeof second === 'number') {
nextVal = second;
}
}
} else if (rawVal instanceof Array && rawVal.length === 2) {
var _rawVal = _slicedToArray(rawVal, 2),
_first = _rawVal[0],
_second = _rawVal[1];
if (typeof _first === 'number') {
val = _first;
}
if (typeof _second === 'number') {
nextVal = _second;
}
} else if (lastShapeType === 'rectangle') {
nextVal = val;
} else {
nextVal = 0;
}
// @ts-expect-error this is a problem if we have ranged values because `val` can be an array
var x = maxValue === 0 ? offsetX : (maxValue - val) * realWidth / (2 * maxValue) + offsetX;
var y = rowHeight * i + offsetY;
// @ts-expect-error getValueByDataKey does not validate the output type
var upperWidth = maxValue === 0 ? 0 : val / maxValue * realWidth;
// @ts-expect-error nextVal could be an array
var lowerWidth = maxValue === 0 ? 0 : nextVal / maxValue * realWidth;
var tooltipPayload = [{
name,
value: val,
payload: entry,
dataKey,
type: tooltipType,
graphicalItemId
}];
var tooltipPosition = {
x: x + upperWidth / 2,
y: y + rowHeight / 2
};
var trapezoidViewBox = {
x,
y,
upperWidth,
lowerWidth,
width: Math.max(upperWidth, lowerWidth),
height: rowHeight
};
return _objectSpread(_objectSpread(_objectSpread({}, trapezoidViewBox), {}, {
name,
val,
tooltipPayload,
tooltipPosition
}, entry != null && typeof entry === 'object' ? omit(entry, ['width']) : {}), {}, {
payload: entry,
parentViewBox,
labelViewBox: trapezoidViewBox
});
});
if (reversed) {
trapezoids = trapezoids.map((entry, index) => {
var reversedViewBox = {
x: entry.x - (entry.lowerWidth - entry.upperWidth) / 2,
y: entry.y - index * rowHeight + (len - 1 - index) * rowHeight,
upperWidth: entry.lowerWidth,
lowerWidth: entry.upperWidth,
width: Math.max(entry.lowerWidth, entry.upperWidth),
height: rowHeight
};
return _objectSpread(_objectSpread(_objectSpread({}, entry), reversedViewBox), {}, {
tooltipPosition: _objectSpread(_objectSpread({}, entry.tooltipPosition), {}, {
y: entry.y - index * rowHeight + (len - 1 - index) * rowHeight + rowHeight / 2
}),
labelViewBox: reversedViewBox
});
});
}
return trapezoids;
}
/**
* @consumes CartesianViewBoxContext
* @provides LabelListContext
* @provides CellReader
*/
function FunnelFn(outsideProps) {
var _resolveDefaultProps = resolveDefaultProps(outsideProps, defaultFunnelProps),
externalId = _resolveDefaultProps.id,
props = _objectWithoutProperties(_resolveDefaultProps, _excluded4);
return /*#__PURE__*/React.createElement(RegisterGraphicalItemId, {
id: externalId,
type: "funnel"
}, id => /*#__PURE__*/React.createElement(FunnelImpl, _extends({}, props, {
id: id
})));
}
export var Funnel = FunnelFn;
// @ts-expect-error we need to set the displayName for debugging purposes
Funnel.displayName = 'Funnel';

View file

@ -0,0 +1,48 @@
import * as React from 'react';
import { useAppSelector } from '../state/hooks';
import { implicitXAxis, implicitYAxis, selectXAxisRange, selectXAxisSettings, selectYAxisRange, selectYAxisSettings } from '../state/selectors/axisSelectors';
import { usePlotArea } from '../hooks';
export function useNeedsClip(xAxisId, yAxisId) {
var _xAxis$allowDataOverf, _yAxis$allowDataOverf;
var xAxis = useAppSelector(state => selectXAxisSettings(state, xAxisId));
var yAxis = useAppSelector(state => selectYAxisSettings(state, yAxisId));
var needClipX = (_xAxis$allowDataOverf = xAxis === null || xAxis === void 0 ? void 0 : xAxis.allowDataOverflow) !== null && _xAxis$allowDataOverf !== void 0 ? _xAxis$allowDataOverf : implicitXAxis.allowDataOverflow;
var needClipY = (_yAxis$allowDataOverf = yAxis === null || yAxis === void 0 ? void 0 : yAxis.allowDataOverflow) !== null && _yAxis$allowDataOverf !== void 0 ? _yAxis$allowDataOverf : implicitYAxis.allowDataOverflow;
var needClip = needClipX || needClipY;
return {
needClip,
needClipX,
needClipY
};
}
export function GraphicalItemClipPath(_ref) {
var xAxisId = _ref.xAxisId,
yAxisId = _ref.yAxisId,
clipPathId = _ref.clipPathId;
var plotArea = usePlotArea();
var _useNeedsClip = useNeedsClip(xAxisId, yAxisId),
needClipX = _useNeedsClip.needClipX,
needClipY = _useNeedsClip.needClipY,
needClip = _useNeedsClip.needClip;
var xAxisRange = useAppSelector(state => selectXAxisRange(state, xAxisId, false));
var yAxisRange = useAppSelector(state => selectYAxisRange(state, yAxisId, false));
if (!needClip || !plotArea) {
return null;
}
var x = plotArea.x,
y = plotArea.y,
width = plotArea.width,
height = plotArea.height;
var clipX = needClipX && xAxisRange ? Math.min(xAxisRange[0], xAxisRange[1]) : x - width / 2;
var clipY = needClipY && yAxisRange ? Math.min(yAxisRange[0], yAxisRange[1]) : y - height / 2;
var clipWidth = needClipX && xAxisRange ? Math.abs(xAxisRange[1] - xAxisRange[0]) : width * 2;
var clipHeight = needClipY && yAxisRange ? Math.abs(yAxisRange[1] - yAxisRange[0]) : height * 2;
return /*#__PURE__*/React.createElement("clipPath", {
id: "clipPath-".concat(clipPathId)
}, /*#__PURE__*/React.createElement("rect", {
x: clipX,
y: clipY,
width: clipWidth,
height: clipHeight
}));
}

578
frontend/node_modules/recharts/es6/cartesian/Line.js generated vendored Normal file
View file

@ -0,0 +1,578 @@
var _excluded = ["id"],
_excluded2 = ["type", "layout", "connectNulls", "needClip", "shape", "strokeDasharray"],
_excluded3 = ["activeDot", "animateNewValues", "animationBegin", "animationDuration", "animationEasing", "connectNulls", "dot", "hide", "isAnimationActive", "label", "legendType", "xAxisId", "yAxisId", "id"];
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
import * as React from 'react';
import { Component, useCallback, useMemo, useRef } from 'react';
import { clsx } from 'clsx';
import { Layer } from '../container/Layer';
import { LineDrawShape } from './LineDrawShape';
import { useAnimatedLineLength } from './useAnimatedLineLength';
import { CartesianLabelListContextProvider, LabelListFromLabelProp } from '../component/LabelList';
import { Dots } from '../component/Dots';
import { interpolate, isNullish, noop } from '../util/DataUtils';
import { isClipDot } from '../util/ReactUtils';
import { getCateCoordinateOfLine, getTooltipNameProp, getValueByDataKey } from '../util/ChartUtils';
import { ActivePoints } from '../component/ActivePoints';
import { SetTooltipEntrySettings } from '../state/SetTooltipEntrySettings';
import { SetErrorBarContext } from '../context/ErrorBarContext';
import { GraphicalItemClipPath, useNeedsClip } from './GraphicalItemClipPath';
import { useChartLayout } from '../context/chartLayoutContext';
import { useIsPanorama } from '../context/PanoramaContext';
import { selectLinePoints } from '../state/selectors/lineSelectors';
import { useAppSelector } from '../state/hooks';
import { SetLegendPayload } from '../state/SetLegendPayload';
import { AnimatedItems, useAnimationCallbacks } from '../animation/AnimatedItems';
import { matchByIndex } from '../animation/matchBy';
import { resolveDefaultProps } from '../util/resolveDefaultProps';
import { usePlotArea } from '../hooks';
import { RegisterGraphicalItemId } from '../context/RegisterGraphicalItemId';
import { SetCartesianGraphicalItem } from '../state/SetGraphicalItem';
import { svgPropertiesNoEvents } from '../util/svgPropertiesNoEvents';
import { svgPropertiesAndEvents } from '../util/svgPropertiesAndEvents';
import { getRadiusAndStrokeWidthFromDot } from '../util/getRadiusAndStrokeWidthFromDot';
import { Shape } from '../util/ActiveShapeUtils';
import { ZIndexLayer } from '../zIndex/ZIndexLayer';
import { DefaultZIndexes } from '../zIndex/DefaultZIndexes';
import { propsAreEqual } from '../util/propsAreEqual';
/**
* Internal props, combination of external props + defaultProps + private Recharts state
*/
/**
* External props, intended for end users to fill in
*/
function getTotalLength(mainCurve) {
try {
return mainCurve && mainCurve.getTotalLength && mainCurve.getTotalLength() || 0;
} catch (_unused) {
return 0;
}
}
/**
* Compute the average x-shift between matched pairs (prev next).
* This tells us the overall direction and magnitude of the data movement.
*/
function averageShift(items) {
var total = 0;
var count = 0;
for (var item of items) {
if (item.status === 'matched' && item.prev.x != null && item.next.x != null) {
total += item.next.x - item.prev.x;
count++;
}
}
return count > 0 ? total / count : 0;
}
var defaultLineAnimateItems = (items, animationElapsedTime) => {
if (items == null) {
// First render: return empty, stroke-dasharray handles the reveal
return [];
}
// At animationElapsedTime=1 return only the non-removed items
if (animationElapsedTime === 1) return items.flatMap(item => item.status === 'removed' ? [] : [item.next]);
var shift = averageShift(items);
var result = [];
for (var item of items) {
if (item.status === 'matched') {
result.push(_objectSpread(_objectSpread({}, item.next), {}, {
x: interpolate(item.prev.x, item.next.x, animationElapsedTime),
y: interpolate(item.prev.y, item.next.y, animationElapsedTime)
}));
} else if (item.status === 'added') {
if (item.next.x != null) {
// Extrapolate entry position: the point starts where it "would have been"
var entryX = item.next.x - shift;
result.push(_objectSpread(_objectSpread({}, item.next), {}, {
x: interpolate(entryX, item.next.x, animationElapsedTime),
y: item.next.y
}));
} else {
result.push(item.next);
}
} else if (item.status === 'removed') {
if (item.prev.x != null) {
var exitX = item.prev.x + shift;
result.push(_objectSpread(_objectSpread({}, item.prev), {}, {
x: interpolate(item.prev.x, exitX, animationElapsedTime),
y: item.prev.y
}));
}
// else: removed items are simply dropped
}
}
return result;
};
export var defaultLineProps = {
activeDot: true,
animateNewValues: true,
animationBegin: 0,
animationDuration: 1500,
animationEasing: 'ease',
animationInterpolateFn: defaultLineAnimateItems,
animationMatchBy: matchByIndex,
connectNulls: false,
dot: true,
fill: '#fff',
hide: false,
isAnimationActive: 'auto',
label: false,
legendType: 'line',
shape: LineDrawShape,
stroke: '#3182bd',
strokeWidth: 1,
xAxisId: 0,
yAxisId: 0,
zIndex: DefaultZIndexes.line,
type: 'linear'
};
/**
* Because of naming conflict, we are forced to ignore certain (valid) SVG attributes.
*/
var computeLegendPayloadFromAreaData = props => {
var dataKey = props.dataKey,
name = props.name,
stroke = props.stroke,
legendType = props.legendType,
hide = props.hide;
return [{
inactive: hide,
dataKey,
type: legendType,
color: stroke,
value: getTooltipNameProp(name, dataKey),
payload: props
}];
};
var SetLineTooltipEntrySettings = /*#__PURE__*/React.memo(_ref => {
var dataKey = _ref.dataKey,
data = _ref.data,
stroke = _ref.stroke,
strokeWidth = _ref.strokeWidth,
fill = _ref.fill,
name = _ref.name,
hide = _ref.hide,
unit = _ref.unit,
formatter = _ref.formatter,
tooltipType = _ref.tooltipType,
id = _ref.id;
var tooltipEntrySettings = {
dataDefinedOnItem: data,
getPosition: noop,
settings: {
stroke,
strokeWidth,
fill,
dataKey,
nameKey: undefined,
name: getTooltipNameProp(name, dataKey),
hide,
type: tooltipType,
color: stroke,
unit,
formatter,
graphicalItemId: id
}
};
return /*#__PURE__*/React.createElement(SetTooltipEntrySettings, {
tooltipEntrySettings: tooltipEntrySettings
});
});
function LineDotsWrapper(_ref2) {
var clipPathId = _ref2.clipPathId,
points = _ref2.points,
props = _ref2.props;
var dot = props.dot,
dataKey = props.dataKey,
needClip = props.needClip;
/*
* Exclude ID from the props passed to the Dots component
* because then the ID would be applied to multiple dots, and it would no longer be unique.
*/
var id = props.id,
propsWithoutId = _objectWithoutProperties(props, _excluded);
var lineProps = svgPropertiesNoEvents(propsWithoutId);
return /*#__PURE__*/React.createElement(Dots, {
points: points,
dot: dot,
className: "recharts-line-dots",
dotClassName: "recharts-line-dot",
dataKey: dataKey,
baseProps: lineProps,
needClip: needClip,
clipPathId: clipPathId
});
}
function LineLabelListProvider(_ref3) {
var showLabels = _ref3.showLabels,
children = _ref3.children,
points = _ref3.points;
var labelListEntries = useMemo(() => {
return points === null || points === void 0 ? void 0 : points.map(point => {
var _point$x, _point$y;
var viewBox = {
x: (_point$x = point.x) !== null && _point$x !== void 0 ? _point$x : 0,
y: (_point$y = point.y) !== null && _point$y !== void 0 ? _point$y : 0,
width: 0,
lowerWidth: 0,
upperWidth: 0,
height: 0
};
return _objectSpread(_objectSpread({}, viewBox), {}, {
value: point.value,
payload: point.payload,
viewBox,
/*
* Line is not passing parentViewBox to the LabelList so the labels can escape - looks like a bug, should we pass parentViewBox?
* Or should this just be the root chart viewBox?
*/
parentViewBox: undefined,
fill: undefined
});
});
}, [points]);
return /*#__PURE__*/React.createElement(CartesianLabelListContextProvider, {
value: showLabels ? labelListEntries : undefined
}, children);
}
function StaticCurve(_ref4) {
var clipPathId = _ref4.clipPathId,
pathRef = _ref4.pathRef,
points = _ref4.points,
props = _ref4.props,
animationElapsedTime = _ref4.animationElapsedTime,
isAnimating = _ref4.isAnimating,
isEntrance = _ref4.isEntrance,
visibleLength = _ref4.visibleLength;
var type = props.type,
layout = props.layout,
connectNulls = props.connectNulls,
needClip = props.needClip,
shape = props.shape,
strokeDasharray = props.strokeDasharray,
others = _objectWithoutProperties(props, _excluded2);
var curveProps = _objectSpread(_objectSpread({}, svgPropertiesAndEvents(others)), {}, {
fill: 'none',
className: 'recharts-line-curve',
clipPath: needClip ? "url(#clipPath-".concat(clipPathId, ")") : undefined,
points,
type,
layout,
connectNulls,
strokeDasharray: strokeDasharray !== null && strokeDasharray !== void 0 ? strokeDasharray : props.strokeDasharray,
pathRef,
animationElapsedTime,
isAnimating,
isEntrance: props.animateNewValues ? isEntrance : false,
visibleLength
});
return /*#__PURE__*/React.createElement(React.Fragment, null, (points === null || points === void 0 ? void 0 : points.length) > 1 && /*#__PURE__*/React.createElement(Shape, {
option: shape,
DefaultShape: defaultLineProps.shape,
shapeProps: curveProps
}), /*#__PURE__*/React.createElement(LineDotsWrapper, {
points: points,
clipPathId: clipPathId,
props: props
}));
}
function CurveWithAnimation(_ref5) {
var clipPathId = _ref5.clipPathId,
props = _ref5.props,
pathRef = _ref5.pathRef,
previousPointsRef = _ref5.previousPointsRef;
var points = props.points,
isAnimationActive = props.isAnimationActive,
animationBegin = props.animationBegin,
animationDuration = props.animationDuration,
animationEasing = props.animationEasing,
animationMatchBy = props.animationMatchBy,
animationInterpolateFn = props.animationInterpolateFn,
layout = props.layout;
var totalLength = getTotalLength(pathRef.current);
var _useAnimationCallback = useAnimationCallbacks(props.onAnimationStart, props.onAnimationEnd),
isAnimating = _useAnimationCallback.isAnimating,
handleAnimationStart = _useAnimationCallback.handleAnimationStart,
handleAnimationEnd = _useAnimationCallback.handleAnimationEnd;
var showLabels = !isAnimating;
var getVisibleLength = useAnimatedLineLength(points);
// Guard for totalLength: don't update previousPointsRef before SVG path is measured
var shouldUpdatePreviousRef = useCallback(animationElapsedTime => animationElapsedTime > 0 && totalLength > 0, [totalLength]);
return /*#__PURE__*/React.createElement(LineLabelListProvider, {
points: points,
showLabels: showLabels
}, props.children, /*#__PURE__*/React.createElement(AnimatedItems, {
animationInput: points,
animationIdPrefix: "recharts-line-",
items: points,
previousItemsRef: previousPointsRef,
isAnimationActive: isAnimationActive,
animationBegin: animationBegin,
animationDuration: animationDuration,
animationEasing: animationEasing,
onAnimationStart: handleAnimationStart,
onAnimationEnd: handleAnimationEnd,
animationInterpolateFn: animationInterpolateFn,
animationMatchBy: animationMatchBy,
shouldUpdatePreviousRef: shouldUpdatePreviousRef,
layout: layout
}, (stepData, animationElapsedTime, isEntrance) => {
var animationActive = isAnimating || animationElapsedTime < 1;
var visibleLength = animationActive ? getVisibleLength(animationElapsedTime, totalLength) : null;
return /*#__PURE__*/React.createElement(StaticCurve, {
props: props,
points: stepData,
clipPathId: clipPathId,
pathRef: pathRef,
animationElapsedTime: animationElapsedTime,
isAnimating: animationActive,
isEntrance: isEntrance,
visibleLength: visibleLength
});
}), /*#__PURE__*/React.createElement(LabelListFromLabelProp, {
label: props.label
}));
}
function RenderCurve(_ref6) {
var clipPathId = _ref6.clipPathId,
props = _ref6.props;
var previousPointsRef = useRef(null);
var pathRef = useRef(null);
return /*#__PURE__*/React.createElement(CurveWithAnimation, {
props: props,
clipPathId: clipPathId,
previousPointsRef: previousPointsRef,
pathRef: pathRef
});
}
var errorBarDataPointFormatter = (dataPoint, dataKey) => {
var _dataPoint$x, _dataPoint$y;
return {
x: (_dataPoint$x = dataPoint.x) !== null && _dataPoint$x !== void 0 ? _dataPoint$x : undefined,
y: (_dataPoint$y = dataPoint.y) !== null && _dataPoint$y !== void 0 ? _dataPoint$y : undefined,
value: dataPoint.value,
// getValueByDataKey does not validate the output type
errorVal: getValueByDataKey(dataPoint.payload, dataKey)
};
};
// eslint-disable-next-line react/prefer-stateless-function
class LineWithState extends Component {
render() {
var _this$props = this.props,
hide = _this$props.hide,
dot = _this$props.dot,
points = _this$props.points,
className = _this$props.className,
xAxisId = _this$props.xAxisId,
yAxisId = _this$props.yAxisId,
top = _this$props.top,
left = _this$props.left,
width = _this$props.width,
height = _this$props.height,
id = _this$props.id,
needClip = _this$props.needClip,
zIndex = _this$props.zIndex;
if (hide) {
return null;
}
var layerClass = clsx('recharts-line', className);
var clipPathId = id;
var _getRadiusAndStrokeWi = getRadiusAndStrokeWidthFromDot(dot),
r = _getRadiusAndStrokeWi.r,
strokeWidth = _getRadiusAndStrokeWi.strokeWidth;
var clipDot = isClipDot(dot);
var dotSize = r * 2 + strokeWidth;
var activePointsClipPath = needClip ? "url(#clipPath-".concat(clipDot ? '' : 'dots-').concat(clipPathId, ")") : undefined;
return /*#__PURE__*/React.createElement(ZIndexLayer, {
zIndex: zIndex
}, /*#__PURE__*/React.createElement(Layer, {
className: layerClass
}, needClip && /*#__PURE__*/React.createElement("defs", null, /*#__PURE__*/React.createElement(GraphicalItemClipPath, {
clipPathId: clipPathId,
xAxisId: xAxisId,
yAxisId: yAxisId
}), !clipDot && /*#__PURE__*/React.createElement("clipPath", {
id: "clipPath-dots-".concat(clipPathId)
}, /*#__PURE__*/React.createElement("rect", {
x: left - dotSize / 2,
y: top - dotSize / 2,
width: width + dotSize,
height: height + dotSize
}))), /*#__PURE__*/React.createElement(SetErrorBarContext, {
xAxisId: xAxisId,
yAxisId: yAxisId,
data: points,
dataPointFormatter: errorBarDataPointFormatter,
errorBarOffset: 0
}, /*#__PURE__*/React.createElement(RenderCurve, {
props: this.props,
clipPathId: clipPathId
}))), /*#__PURE__*/React.createElement(ActivePoints, {
activeDot: this.props.activeDot,
points: points,
mainColor: this.props.stroke,
itemDataKey: this.props.dataKey,
clipPath: activePointsClipPath
}));
}
}
function LineImpl(props) {
var _resolveDefaultProps = resolveDefaultProps(props, defaultLineProps),
activeDot = _resolveDefaultProps.activeDot,
animateNewValues = _resolveDefaultProps.animateNewValues,
animationBegin = _resolveDefaultProps.animationBegin,
animationDuration = _resolveDefaultProps.animationDuration,
animationEasing = _resolveDefaultProps.animationEasing,
connectNulls = _resolveDefaultProps.connectNulls,
dot = _resolveDefaultProps.dot,
hide = _resolveDefaultProps.hide,
isAnimationActive = _resolveDefaultProps.isAnimationActive,
label = _resolveDefaultProps.label,
legendType = _resolveDefaultProps.legendType,
xAxisId = _resolveDefaultProps.xAxisId,
yAxisId = _resolveDefaultProps.yAxisId,
id = _resolveDefaultProps.id,
everythingElse = _objectWithoutProperties(_resolveDefaultProps, _excluded3);
var _useNeedsClip = useNeedsClip(xAxisId, yAxisId),
needClip = _useNeedsClip.needClip;
var plotArea = usePlotArea();
var layout = useChartLayout();
var isPanorama = useIsPanorama();
var points = useAppSelector(state => selectLinePoints(state, xAxisId, yAxisId, isPanorama, id));
if (layout !== 'horizontal' && layout !== 'vertical' || points == null || plotArea == null) {
// Cannot render Line in an unsupported layout
return null;
}
var height = plotArea.height,
width = plotArea.width,
left = plotArea.x,
top = plotArea.y;
return /*#__PURE__*/React.createElement(LineWithState, _extends({}, everythingElse, {
id: id,
connectNulls: connectNulls,
dot: dot,
activeDot: activeDot,
animateNewValues: animateNewValues,
animationBegin: animationBegin,
animationDuration: animationDuration,
animationEasing: animationEasing,
isAnimationActive: isAnimationActive,
hide: hide,
label: label,
legendType: legendType,
xAxisId: xAxisId,
yAxisId: yAxisId,
points: points,
layout: layout,
height: height,
width: width,
left: left,
top: top,
needClip: needClip
}));
}
export function computeLinePoints(_ref7) {
var layout = _ref7.layout,
xAxis = _ref7.xAxis,
yAxis = _ref7.yAxis,
xAxisTicks = _ref7.xAxisTicks,
yAxisTicks = _ref7.yAxisTicks,
dataKey = _ref7.dataKey,
bandSize = _ref7.bandSize,
displayedData = _ref7.displayedData;
return displayedData.map((entry, index) => {
// getValueByDataKey does not validate the output type
var value = getValueByDataKey(entry, dataKey);
if (layout === 'horizontal') {
var _x = getCateCoordinateOfLine({
axis: xAxis,
ticks: xAxisTicks,
bandSize,
entry,
index
});
var _y = isNullish(value) ? null : yAxis.scale.map(value);
return {
x: _x,
y: _y !== null && _y !== void 0 ? _y : null,
value,
payload: entry
};
}
var x = isNullish(value) ? null : xAxis.scale.map(value);
var y = getCateCoordinateOfLine({
axis: yAxis,
ticks: yAxisTicks,
bandSize,
entry,
index
});
if (x == null || y == null) {
return null;
}
return {
x,
y,
value,
payload: entry
};
}).filter(Boolean);
}
function LineFn(outsideProps) {
var props = resolveDefaultProps(outsideProps, defaultLineProps);
var isPanorama = useIsPanorama();
return /*#__PURE__*/React.createElement(RegisterGraphicalItemId, {
id: props.id,
type: "line"
}, id => /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(SetLegendPayload, {
legendPayload: computeLegendPayloadFromAreaData(props)
}), /*#__PURE__*/React.createElement(SetLineTooltipEntrySettings, {
dataKey: props.dataKey,
data: props.data,
stroke: props.stroke,
strokeWidth: props.strokeWidth,
fill: props.fill,
name: props.name,
hide: props.hide,
unit: props.unit,
formatter: props.formatter,
tooltipType: props.tooltipType,
id: id
}), /*#__PURE__*/React.createElement(SetCartesianGraphicalItem, {
type: "line",
id: id,
data: props.data,
xAxisId: props.xAxisId,
yAxisId: props.yAxisId,
zAxisId: 0,
dataKey: props.dataKey,
hide: props.hide,
isPanorama: isPanorama
}), /*#__PURE__*/React.createElement(LineImpl, _extends({}, props, {
id: id
}))));
}
/**
* @provides LabelListContext
* @provides ErrorBarContext
* @consumes CartesianChartContext
*/
export var Line = /*#__PURE__*/React.memo(LineFn, propsAreEqual);
// @ts-expect-error we need to set the displayName for debugging purposes
Line.displayName = 'Line';

View file

@ -0,0 +1,161 @@
var _excluded = ["animationElapsedTime", "isAnimating", "isEntrance", "visibleLength", "strokeDasharray", "connectNulls"];
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
import * as React from 'react';
import { Curve } from '../shape/Curve';
/**
* Reads the total length of an SVG path element, returning 0 if the element
* is null or the measurement fails (e.g. in JSDOM).
*/
function getTotalLength(path) {
try {
return path && path.getTotalLength && path.getTotalLength() || 0;
} catch (_unused) {
return 0;
}
}
/**
* Generates a simple stroke-dasharray string for animating a line draw effect.
*
* Uses `totalLength` as the gap (instead of `totalLength - length`) to prevent a floating-point
* precision artifact: when fractional dash and gap values are serialized to a string attribute
* and reparsed by the SVG renderer, their sum can differ from the actual path length by a ULP,
* causing the dasharray pattern to repeat and render a phantom dot at the path endpoint
* with round or square strokeLinecap.
*
* @param totalLength The total length of the SVG path
* @param length The currently visible portion of the path
* @returns A stroke-dasharray string like "50px 200px"
*/
function generateSimpleStrokeDasharray(totalLength, length) {
return "".concat(length, "px ").concat(totalLength, "px");
}
/**
* Normalizes a dash pattern to the even-length sequence used by SVG renderers.
* Odd-length stroke-dasharray values repeat once, so "5" behaves like "5 5".
*
* @param lines Array of dash/gap lengths to repeat
* @returns An even-length dash pattern
*/
function normalizeDashPattern(lines) {
return lines.length % 2 !== 0 ? [...lines, ...lines] : lines;
}
/**
* Repeats a dash pattern array a given number of times.
*
* @param lines Array of dash/gap lengths to repeat
* @param count Number of times to repeat the pattern
* @returns A new array with the pattern repeated `count` times
*/
function repeat(lines, count) {
var result = [];
for (var i = 0; i < count; ++i) {
result.push(...lines);
}
return result;
}
/**
* Computes a stroke-dasharray string for animating a custom-dashed line draw effect.
*
* Given a user-specified dash pattern (e.g. `"7,3"`), this function builds a dasharray
* that reveals exactly `length` pixels of that pattern, followed by a gap of `totalLength`
* to hide the remainder of the path.
*
* Like {@link generateSimpleStrokeDasharray}, the trailing gap uses `totalLength` rather than
* `totalLength - length` to avoid floating-point precision artifacts with round/square strokeLinecap.
*
* @param length The currently visible portion of the path
* @param totalLength The total length of the SVG path
* @param lines The user-specified dash pattern as an array of numbers (e.g. [7, 3])
* @returns A stroke-dasharray string incorporating the custom dash pattern
*/
function getStrokeDasharray(length, totalLength, lines) {
var normalizedLines = normalizeDashPattern(lines);
var lineLength = normalizedLines.reduce((pre, next) => pre + next, 0);
// if lineLength is 0 return the default when no strokeDasharray is provided
if (!lineLength) {
return generateSimpleStrokeDasharray(totalLength, length);
}
var count = Math.floor(length / lineLength);
var remainLength = length % lineLength;
var remainLines = [];
for (var i = 0, sum = 0; i < normalizedLines.length; sum += (_normalizedLines$i = normalizedLines[i]) !== null && _normalizedLines$i !== void 0 ? _normalizedLines$i : 0, ++i) {
var _normalizedLines$i;
var lineValue = normalizedLines[i];
if (lineValue != null && sum + lineValue > remainLength) {
remainLines = [...normalizedLines.slice(0, i), remainLength - sum];
break;
}
}
var emptyLines = remainLines.length % 2 === 0 ? [0, totalLength] : [totalLength];
return [...repeat(normalizedLines, count), ...remainLines, ...emptyLines].map(line => "".concat(line, "px")).join(', ');
}
/**
* Computes the animated stroke-dasharray for a line's entrance animation.
*
* @param userStrokeDasharray The user-specified stroke-dasharray (e.g. "5,3"), if any
* @param totalLength Total SVG path length
* @param visibleLength How much of the path should be visible
* @returns A stroke-dasharray string for the current animation frame
*/
function computeAnimatedStrokeDasharray(userStrokeDasharray, totalLength, visibleLength) {
if (userStrokeDasharray) {
var lines = "".concat(userStrokeDasharray).split(/[,\s]+/gim).map(num => parseFloat(num));
return getStrokeDasharray(visibleLength, totalLength, lines);
}
return generateSimpleStrokeDasharray(totalLength, visibleLength);
}
/**
* The default shape for Line. During the entrance animation, the line is progressively
* revealed using the `strokeDasharray` SVG attribute: the visible portion grows from
* 0 to the full path length as `animationElapsedTime` progresses from 0 to 1.
*
* This is the built-in shape for Line. It is automatically used when no custom `shape` prop
* is provided. You can import and reuse it as a starting point for custom shapes,
* or use it as a reference for building your own.
*
* The animation progress props (`animationElapsedTime`, `isAnimating`, `isEntrance`) are available
* for custom shapes that want to add their own effects on top.
*
* @example
* ```tsx
* import { Line, LineDrawShape } from 'recharts';
*
* // Use the default shape explicitly (same as providing no shape prop)
* <Line dataKey="value" shape={LineDrawShape} />
* ```
*
* @see {@link https://recharts.github.io/en-US/guide/animations Animation guide}
*
* @since 3.9
*/
export function LineDrawShape(props) {
var _animationElapsedTime = props.animationElapsedTime,
isAnimating = props.isAnimating,
isEntrance = props.isEntrance,
visibleLength = props.visibleLength,
userStrokeDasharray = props.strokeDasharray,
connectNulls = props.connectNulls,
curveProps = _objectWithoutProperties(props, _excluded);
var finalConnectNulls = connectNulls !== null && connectNulls !== void 0 ? connectNulls : false;
var strokeDasharray;
if (visibleLength != null) {
var _pathRef$current;
var pathRef = curveProps.pathRef;
var totalLength = getTotalLength((_pathRef$current = pathRef === null || pathRef === void 0 ? void 0 : pathRef.current) !== null && _pathRef$current !== void 0 ? _pathRef$current : null);
strokeDasharray = computeAnimatedStrokeDasharray(userStrokeDasharray, totalLength, visibleLength);
} else if (userStrokeDasharray != null) {
strokeDasharray = String(userStrokeDasharray);
}
return /*#__PURE__*/React.createElement(Curve, _extends({}, curveProps, {
connectNulls: finalConnectNulls,
strokeDasharray: strokeDasharray
}));
}

View file

@ -0,0 +1,171 @@
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
import * as React from 'react';
import { useEffect } from 'react';
import { clsx } from 'clsx';
import { Layer } from '../container/Layer';
import { CartesianLabelContextProvider, CartesianLabelFromLabelProp } from '../component/Label';
import { rectWithPoints } from '../util/CartesianUtils';
import { isNumOrStr } from '../util/DataUtils';
import { Rectangle } from '../shape/Rectangle';
import { addArea, removeArea } from '../state/referenceElementsSlice';
import { useAppDispatch, useAppSelector } from '../state/hooks';
import { selectAxisScale } from '../state/selectors/axisSelectors';
import { useIsPanorama } from '../context/PanoramaContext';
import { useClipPathId } from '../container/ClipPathProvider';
import { svgPropertiesAndEvents } from '../util/svgPropertiesAndEvents';
import { resolveDefaultProps } from '../util/resolveDefaultProps';
import { ZIndexLayer } from '../zIndex/ZIndexLayer';
import { DefaultZIndexes } from '../zIndex/DefaultZIndexes';
import { CartesianScaleHelperImpl } from '../util/scale/CartesianScaleHelper';
/*
* Omit width, height, x, y from SVGPropsAndEvents because ReferenceArea receives x1, x2, y1, y2 instead.
* The position is calculated internally instead.
*/
var getRect = (hasX1, hasX2, hasY1, hasY2, xAxisScale, yAxisScale, props) => {
var _xAxisScale$map, _yAxisScale$map, _xAxisScale$map2, _yAxisScale$map2;
var xValue1 = props.x1,
xValue2 = props.x2,
yValue1 = props.y1,
yValue2 = props.y2;
if (xAxisScale == null || yAxisScale == null) {
return null;
}
var scales = new CartesianScaleHelperImpl({
x: xAxisScale,
y: yAxisScale
});
var p1 = {
x: hasX1 ? (_xAxisScale$map = xAxisScale.map(xValue1, {
position: 'start'
})) !== null && _xAxisScale$map !== void 0 ? _xAxisScale$map : null : xAxisScale.rangeMin(),
y: hasY1 ? (_yAxisScale$map = yAxisScale.map(yValue1, {
position: 'start'
})) !== null && _yAxisScale$map !== void 0 ? _yAxisScale$map : null : yAxisScale.rangeMin()
};
var p2 = {
x: hasX2 ? (_xAxisScale$map2 = xAxisScale.map(xValue2, {
position: 'end'
})) !== null && _xAxisScale$map2 !== void 0 ? _xAxisScale$map2 : null : xAxisScale.rangeMax(),
y: hasY2 ? (_yAxisScale$map2 = yAxisScale.map(yValue2, {
position: 'end'
})) !== null && _yAxisScale$map2 !== void 0 ? _yAxisScale$map2 : null : yAxisScale.rangeMax()
};
if (props.ifOverflow === 'discard' && (!scales.isInRange(p1) || !scales.isInRange(p2))) {
return null;
}
// @ts-expect-error we're sending nullable coordinates but rectWithPoints expects non-nullable Coordinate
return rectWithPoints(p1, p2);
};
var renderRect = (option, props) => {
var rect;
if (/*#__PURE__*/React.isValidElement(option)) {
// @ts-expect-error element cloning is not typed
rect = /*#__PURE__*/React.cloneElement(option, props);
} else if (typeof option === 'function') {
rect = option(props);
} else {
rect = /*#__PURE__*/React.createElement(Rectangle, _extends({}, props, {
className: "recharts-reference-area-rect"
}));
}
return rect;
};
function ReportReferenceArea(props) {
var dispatch = useAppDispatch();
useEffect(() => {
dispatch(addArea(props));
return () => {
dispatch(removeArea(props));
};
});
return null;
}
function ReferenceAreaImpl(props) {
var x1 = props.x1,
x2 = props.x2,
y1 = props.y1,
y2 = props.y2,
className = props.className,
shape = props.shape,
xAxisId = props.xAxisId,
yAxisId = props.yAxisId;
var clipPathId = useClipPathId();
var isPanorama = useIsPanorama();
var xAxisScale = useAppSelector(state => selectAxisScale(state, 'xAxis', xAxisId, isPanorama));
var yAxisScale = useAppSelector(state => selectAxisScale(state, 'yAxis', yAxisId, isPanorama));
if (xAxisScale == null || yAxisScale == null) {
return null;
}
var hasX1 = isNumOrStr(x1);
var hasX2 = isNumOrStr(x2);
var hasY1 = isNumOrStr(y1);
var hasY2 = isNumOrStr(y2);
if (!hasX1 && !hasX2 && !hasY1 && !hasY2 && !shape) {
return null;
}
var rect = getRect(hasX1, hasX2, hasY1, hasY2, xAxisScale, yAxisScale, props);
if (!rect && !shape) {
return null;
}
var isOverflowHidden = props.ifOverflow === 'hidden';
var clipPath = isOverflowHidden ? "url(#".concat(clipPathId, ")") : undefined;
return /*#__PURE__*/React.createElement(ZIndexLayer, {
zIndex: props.zIndex
}, /*#__PURE__*/React.createElement(Layer, {
className: clsx('recharts-reference-area', className)
}, renderRect(shape, _objectSpread(_objectSpread({
clipPath
}, svgPropertiesAndEvents(props)), rect)), rect != null && /*#__PURE__*/React.createElement(CartesianLabelContextProvider, _extends({}, rect, {
lowerWidth: rect.width,
upperWidth: rect.width
}), /*#__PURE__*/React.createElement(CartesianLabelFromLabelProp, {
label: props.label
}), props.children)));
}
export var referenceAreaDefaultProps = {
ifOverflow: 'discard',
xAxisId: 0,
yAxisId: 0,
radius: 0,
fill: '#ccc',
label: false,
fillOpacity: 0.5,
stroke: 'none',
strokeWidth: 1,
zIndex: DefaultZIndexes.area
};
/**
* Draws a rectangular area on the chart to highlight a specific range.
*
* This component, unlike {@link Rectangle} or {@link https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Element/rect rect}, is aware of the cartesian coordinate system,
* so you specify the area by using data coordinates instead of pixels.
*
* ReferenceArea will calculate the pixels based on the provided data coordinates.
*
* If you prefer to render rectangles using pixels rather than data coordinates,
* consider using the {@link Rectangle} component instead.
*
* @provides CartesianLabelContext
* @consumes CartesianChartContext
*/
export function ReferenceArea(outsideProps) {
var props = resolveDefaultProps(outsideProps, referenceAreaDefaultProps);
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ReportReferenceArea, {
yAxisId: props.yAxisId,
xAxisId: props.xAxisId,
ifOverflow: props.ifOverflow,
x1: props.x1,
x2: props.x2,
y1: props.y1,
y2: props.y2
}), /*#__PURE__*/React.createElement(ReferenceAreaImpl, props));
}
ReferenceArea.displayName = 'ReferenceArea';

View file

@ -0,0 +1,153 @@
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
import * as React from 'react';
import { useEffect } from 'react';
import { clsx } from 'clsx';
import { Layer } from '../container/Layer';
import { Dot } from '../shape/Dot';
import { CartesianLabelContextProvider, CartesianLabelFromLabelProp } from '../component/Label';
import { isNumOrStr } from '../util/DataUtils';
import { addDot, removeDot } from '../state/referenceElementsSlice';
import { useAppDispatch, useAppSelector } from '../state/hooks';
import { selectAxisScale } from '../state/selectors/axisSelectors';
import { useIsPanorama } from '../context/PanoramaContext';
import { useClipPathId } from '../container/ClipPathProvider';
import { svgPropertiesAndEvents } from '../util/svgPropertiesAndEvents';
import { resolveDefaultProps } from '../util/resolveDefaultProps';
import { ZIndexLayer } from '../zIndex/ZIndexLayer';
import { DefaultZIndexes } from '../zIndex/DefaultZIndexes';
import { CartesianScaleHelperImpl } from '../util/scale/CartesianScaleHelper';
var useCoordinate = (x, y, xAxisId, yAxisId, ifOverflow) => {
var isX = isNumOrStr(x);
var isY = isNumOrStr(y);
var isPanorama = useIsPanorama();
var xAxisScale = useAppSelector(state => selectAxisScale(state, 'xAxis', xAxisId, isPanorama));
var yAxisScale = useAppSelector(state => selectAxisScale(state, 'yAxis', yAxisId, isPanorama));
if (!isX || !isY || xAxisScale == null || yAxisScale == null) {
return null;
}
var scales = new CartesianScaleHelperImpl({
x: xAxisScale,
y: yAxisScale
});
var result = scales.map({
x,
y
}, {
position: 'middle'
});
if (ifOverflow === 'discard' && !scales.isInRange(result)) {
return null;
}
return result;
};
function ReportReferenceDot(props) {
var dispatch = useAppDispatch();
useEffect(() => {
dispatch(addDot(props));
return () => {
dispatch(removeDot(props));
};
});
return null;
}
var renderDot = (option, props) => {
var dot;
if (/*#__PURE__*/React.isValidElement(option)) {
// @ts-expect-error element cloning is not typed
dot = /*#__PURE__*/React.cloneElement(option, props);
} else if (typeof option === 'function') {
dot = option(props);
} else {
dot = /*#__PURE__*/React.createElement(Dot, _extends({}, props, {
cx: props.cx,
cy: props.cy,
className: "recharts-reference-dot-dot"
}));
}
return dot;
};
function ReferenceDotImpl(props) {
var x = props.x,
y = props.y,
r = props.r;
var clipPathId = useClipPathId();
var coordinate = useCoordinate(x, y, props.xAxisId, props.yAxisId, props.ifOverflow);
if (!coordinate) {
return null;
}
var cx = coordinate.x,
cy = coordinate.y;
var shape = props.shape,
className = props.className,
ifOverflow = props.ifOverflow;
var clipPath = ifOverflow === 'hidden' ? "url(#".concat(clipPathId, ")") : undefined;
var dotProps = _objectSpread(_objectSpread({
clipPath
}, svgPropertiesAndEvents(props)), {}, {
cx: cx !== null && cx !== void 0 ? cx : undefined,
cy: cy !== null && cy !== void 0 ? cy : undefined
});
return /*#__PURE__*/React.createElement(ZIndexLayer, {
zIndex: props.zIndex
}, /*#__PURE__*/React.createElement(Layer, {
className: clsx('recharts-reference-dot', className)
}, renderDot(shape, dotProps), /*#__PURE__*/React.createElement(CartesianLabelContextProvider, {
x: cx - r,
y: cy - r,
width: 2 * r,
height: 2 * r,
upperWidth: 2 * r,
lowerWidth: 2 * r
}, /*#__PURE__*/React.createElement(CartesianLabelFromLabelProp, {
label: props.label
}), props.children)));
}
export var referenceDotDefaultProps = {
ifOverflow: 'discard',
xAxisId: 0,
yAxisId: 0,
r: 10,
label: false,
fill: '#fff',
stroke: '#ccc',
fillOpacity: 1,
strokeWidth: 1,
zIndex: DefaultZIndexes.scatter
};
/**
* Draws a circle on the chart to highlight a specific point.
*
* This component, unlike {@link Dot} or {@link https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Element/circle circle}, is aware of the cartesian coordinate system,
* so you specify its center by using data coordinates instead of pixels.
*
* ReferenceDot will calculate the pixels based on the provided data coordinates.
*
* If you prefer to render dots using pixels rather than data coordinates,
* consider using the {@link Dot} component instead.
*
* @provides CartesianLabelContext
* @consumes CartesianChartContext
*/
export function ReferenceDot(outsideProps) {
var props = resolveDefaultProps(outsideProps, referenceDotDefaultProps);
var x = props.x,
y = props.y,
r = props.r,
ifOverflow = props.ifOverflow,
yAxisId = props.yAxisId,
xAxisId = props.xAxisId;
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ReportReferenceDot, {
y: y,
x: x,
r: r,
yAxisId: yAxisId,
xAxisId: xAxisId,
ifOverflow: ifOverflow
}), /*#__PURE__*/React.createElement(ReferenceDotImpl, props));
}
ReferenceDot.displayName = 'ReferenceDot';

View file

@ -0,0 +1,247 @@
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
/**
* @fileOverview Reference Line
*/
import * as React from 'react';
import { useEffect } from 'react';
import { clsx } from 'clsx';
import { Layer } from '../container/Layer';
import { CartesianLabelContextProvider, CartesianLabelFromLabelProp } from '../component/Label';
import { isNumOrStr } from '../util/DataUtils';
import { rectWithCoords } from '../util/CartesianUtils';
import { useViewBox } from '../context/chartLayoutContext';
import { addLine, removeLine } from '../state/referenceElementsSlice';
import { useAppDispatch, useAppSelector } from '../state/hooks';
import { selectAxisScale, selectXAxisSettings, selectYAxisSettings } from '../state/selectors/axisSelectors';
import { useIsPanorama } from '../context/PanoramaContext';
import { useClipPathId } from '../container/ClipPathProvider';
import { svgPropertiesAndEvents } from '../util/svgPropertiesAndEvents';
import { resolveDefaultProps } from '../util/resolveDefaultProps';
import { ZIndexLayer } from '../zIndex/ZIndexLayer';
import { DefaultZIndexes } from '../zIndex/DefaultZIndexes';
import { isWellBehavedNumber } from '../util/isWellBehavedNumber';
import { CartesianScaleHelperImpl } from '../util/scale/CartesianScaleHelper';
/**
* Single point that defines one end of a segment.
* These coordinates are in data space, meaning that you should provide
* values that correspond to the data domain of the axes.
* So you would provide a value of `Page A` to indicate the data value `Page A`
* and then recharts will convert that to pixels.
*
* Likewise for numbers. If your x-axis goes from 0 to 100,
* and you want the line to end at 50, you would provide `50` here.
*
* @inline
*/
/**
* This excludes `viewBox` prop from svg for two reasons:
* 1. The components wants viewBox of object type, and svg wants string
* - so there's a conflict, and the component will throw if it gets string
* 2. Internally the component calls `svgPropertiesNoEvents` which filters the viewBox away anyway
*/
var renderLine = (option, props) => {
var line;
if (/*#__PURE__*/React.isValidElement(option)) {
// @ts-expect-error element cloning is not typed
line = /*#__PURE__*/React.cloneElement(option, props);
} else if (typeof option === 'function') {
line = option(props);
} else {
if (!isWellBehavedNumber(props.x1) || !isWellBehavedNumber(props.y1) || !isWellBehavedNumber(props.x2) || !isWellBehavedNumber(props.y2)) {
return null;
}
line = /*#__PURE__*/React.createElement("line", _extends({}, props, {
className: "recharts-reference-line-line"
}));
}
return line;
};
var getHorizontalLineEndPoints = (yCoord, ifOverflow, position, yAxisOrientation, yAxisScale, viewBox) => {
var x = viewBox.x,
width = viewBox.width;
var coord = yAxisScale.map(yCoord, {
position
});
// don't render the line if the scale can't compute a result that makes sense
if (!isWellBehavedNumber(coord)) {
return null;
}
if (ifOverflow === 'discard' && !yAxisScale.isInRange(coord)) {
return null;
}
var points = [{
x: x + width,
y: coord
}, {
x,
y: coord
}];
return yAxisOrientation === 'left' ? points.reverse() : points;
};
var getVerticalLineEndPoints = (xCoord, ifOverflow, position, xAxisOrientation, xAxisScale, viewBox) => {
var y = viewBox.y,
height = viewBox.height;
var coord = xAxisScale.map(xCoord, {
position
});
// don't render the line if the scale can't compute a result that makes sense
if (!isWellBehavedNumber(coord)) {
return null;
}
if (ifOverflow === 'discard' && !xAxisScale.isInRange(coord)) {
return null;
}
var points = [{
x: coord,
y: y + height
}, {
x: coord,
y
}];
return xAxisOrientation === 'top' ? points.reverse() : points;
};
var getSegmentLineEndPoints = (segment, ifOverflow, position, scales) => {
var points = [scales.mapWithFallback(segment[0], {
position,
fallback: 'rangeMin'
}), scales.mapWithFallback(segment[1], {
position,
fallback: 'rangeMax'
})];
if (ifOverflow === 'discard' && points.some(p => !scales.isInRange(p))) {
return null;
}
return points;
};
export var getEndPoints = (xAxisScale, yAxisScale, viewBox, position, xAxisOrientation, yAxisOrientation, props) => {
var xCoord = props.x,
yCoord = props.y,
segment = props.segment,
ifOverflow = props.ifOverflow;
var isFixedX = isNumOrStr(xCoord);
var isFixedY = isNumOrStr(yCoord);
if (isFixedY) {
return getHorizontalLineEndPoints(yCoord, ifOverflow, position, yAxisOrientation, yAxisScale, viewBox);
}
if (isFixedX) {
return getVerticalLineEndPoints(xCoord, ifOverflow, position, xAxisOrientation, xAxisScale, viewBox);
}
if (segment != null && segment.length === 2) {
return getSegmentLineEndPoints(segment, ifOverflow, position, new CartesianScaleHelperImpl({
x: xAxisScale,
y: yAxisScale
}));
}
return null;
};
function ReportReferenceLine(props) {
var dispatch = useAppDispatch();
useEffect(() => {
dispatch(addLine(props));
return () => {
dispatch(removeLine(props));
};
});
return null;
}
function ReferenceLineImpl(props) {
var xAxisId = props.xAxisId,
yAxisId = props.yAxisId,
shape = props.shape,
className = props.className,
ifOverflow = props.ifOverflow;
var isPanorama = useIsPanorama();
var clipPathId = useClipPathId();
var xAxis = useAppSelector(state => selectXAxisSettings(state, xAxisId));
var yAxis = useAppSelector(state => selectYAxisSettings(state, yAxisId));
var xAxisScale = useAppSelector(state => selectAxisScale(state, 'xAxis', xAxisId, isPanorama));
var yAxisScale = useAppSelector(state => selectAxisScale(state, 'yAxis', yAxisId, isPanorama));
var viewBox = useViewBox();
if (!clipPathId || !viewBox || xAxis == null || yAxis == null || xAxisScale == null || yAxisScale == null) {
return null;
}
var endPoints = getEndPoints(xAxisScale, yAxisScale, viewBox, props.position, xAxis.orientation, yAxis.orientation, props);
if (!endPoints) {
return null;
}
var point1 = endPoints[0];
var point2 = endPoints[1];
if (point1 == null || point2 == null) {
return null;
}
var x1 = point1.x,
y1 = point1.y;
var x2 = point2.x,
y2 = point2.y;
var clipPath = ifOverflow === 'hidden' ? "url(#".concat(clipPathId, ")") : undefined;
var lineProps = _objectSpread(_objectSpread({
clipPath
}, svgPropertiesAndEvents(props)), {}, {
x1,
y1,
x2,
y2
});
var rect = rectWithCoords({
x1,
y1,
x2,
y2
});
return /*#__PURE__*/React.createElement(ZIndexLayer, {
zIndex: props.zIndex
}, /*#__PURE__*/React.createElement(Layer, {
className: clsx('recharts-reference-line', className)
}, renderLine(shape, lineProps), /*#__PURE__*/React.createElement(CartesianLabelContextProvider, _extends({}, rect, {
lowerWidth: rect.width,
upperWidth: rect.width
}), /*#__PURE__*/React.createElement(CartesianLabelFromLabelProp, {
label: props.label
}), props.children)));
}
export var referenceLineDefaultProps = {
ifOverflow: 'discard',
xAxisId: 0,
yAxisId: 0,
fill: 'none',
label: false,
stroke: '#ccc',
fillOpacity: 1,
strokeWidth: 1,
position: 'middle',
zIndex: DefaultZIndexes.line
};
/**
* Draws a line on the chart connecting two points.
*
* This component, unlike {@link https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Element/line line}, is aware of the cartesian coordinate system,
* so you specify the dimensions by using data coordinates instead of pixels.
*
* ReferenceLine will calculate the pixels based on the provided data coordinates.
*
* If you prefer to render using pixels rather than data coordinates,
* consider using the {@link https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Element/line line SVG element} instead.
*
* @provides CartesianLabelContext
* @consumes CartesianChartContext
*/
export function ReferenceLine(outsideProps) {
var props = resolveDefaultProps(outsideProps, referenceLineDefaultProps);
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ReportReferenceLine, {
yAxisId: props.yAxisId,
xAxisId: props.xAxisId,
ifOverflow: props.ifOverflow,
x: props.x,
y: props.y,
segment: props.segment
}), /*#__PURE__*/React.createElement(ReferenceLineImpl, props));
}
ReferenceLine.displayName = 'ReferenceLine';

636
frontend/node_modules/recharts/es6/cartesian/Scatter.js generated vendored Normal file
View file

@ -0,0 +1,636 @@
var _excluded = ["id"],
_excluded2 = ["onMouseEnter", "onClick", "onMouseLeave"],
_excluded3 = ["animationBegin", "animationDuration", "animationEasing", "hide", "isAnimationActive", "legendType", "lineJointType", "lineType", "shape", "xAxisId", "yAxisId", "zAxisId"];
function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
import * as React from 'react';
import { useMemo, useRef } from 'react';
import { clsx } from 'clsx';
import { Layer } from '../container/Layer';
import { CartesianLabelListContextProvider, LabelListFromLabelProp } from '../component/LabelList';
import { findAllByType } from '../util/ReactUtils';
import { Curve } from '../shape/Curve';
import { Cell } from '../component/Cell';
import { getLinearRegression, interpolate, isNullish } from '../util/DataUtils';
import { getCateCoordinateOfLine, getTooltipNameProp, getValueByDataKey } from '../util/ChartUtils';
import { adaptEventsOfChild, isNonEmptyArray } from '../util/types';
import { ScatterSymbol } from '../util/ScatterUtils';
import { useMouseClickItemDispatch, useMouseEnterItemDispatch, useMouseLeaveItemDispatch } from '../context/tooltipContext';
import { SetTooltipEntrySettings } from '../state/SetTooltipEntrySettings';
import { SetErrorBarContext } from '../context/ErrorBarContext';
import { GraphicalItemClipPath, useNeedsClip } from './GraphicalItemClipPath';
import { selectScatterPoints } from '../state/selectors/scatterSelectors';
import { useAppSelector } from '../state/hooks';
import { implicitZAxis } from '../state/selectors/axisSelectors';
import { useIsPanorama } from '../context/PanoramaContext';
import { selectActiveTooltipIndex } from '../state/selectors/tooltipSelectors';
import { SetLegendPayload } from '../state/SetLegendPayload';
import { DATA_ITEM_GRAPHICAL_ITEM_ID_ATTRIBUTE_NAME } from '../util/Constants';
import { resolveDefaultProps } from '../util/resolveDefaultProps';
import { RegisterGraphicalItemId } from '../context/RegisterGraphicalItemId';
import { SetCartesianGraphicalItem } from '../state/SetGraphicalItem';
import { svgPropertiesNoEvents, svgPropertiesNoEventsFromUnknown } from '../util/svgPropertiesNoEvents';
import { useCartesianChartLayout, useViewBox } from '../context/chartLayoutContext';
import { AnimatedItems, useAnimationCallbacks } from '../animation/AnimatedItems';
import { matchAppend } from '../animation/matchBy';
import { ZIndexLayer } from '../zIndex/ZIndexLayer';
import { DefaultZIndexes } from '../zIndex/DefaultZIndexes';
import { propsAreEqual } from '../util/propsAreEqual';
/**
* Scatter coordinates are nullable because sometimes the point value is out of the domain,
* and we can't compute a valid coordinate for it.
*
* Scatter -> Symbol ignores points with null cx or cy so those won't render if using the default shapes.
* However: the points are exposed via various props and can be used in custom shapes so we keep them around.
*/
/**
* Internal props, combination of external props + defaultProps + private Recharts state
*/
/**
* External props, intended for end users to fill in
*/
/**
* Because of naming conflict, we are forced to ignore certain (valid) SVG attributes.
*/
var computeLegendPayloadFromScatterProps = props => {
var dataKey = props.dataKey,
name = props.name,
fill = props.fill,
legendType = props.legendType,
hide = props.hide;
return [{
inactive: hide,
dataKey,
type: legendType,
color: fill,
value: getTooltipNameProp(name, dataKey),
payload: props
}];
};
var SetScatterTooltipEntrySettings = /*#__PURE__*/React.memo(_ref => {
var dataKey = _ref.dataKey,
points = _ref.points,
stroke = _ref.stroke,
strokeWidth = _ref.strokeWidth,
fill = _ref.fill,
name = _ref.name,
hide = _ref.hide,
formatter = _ref.formatter,
tooltipType = _ref.tooltipType,
id = _ref.id;
var tooltipEntrySettings = {
dataDefinedOnItem: points === null || points === void 0 ? void 0 : points.map(p => p.tooltipPayload),
getPosition: index => {
var _points$Number;
return points === null || points === void 0 || (_points$Number = points[Number(index)]) === null || _points$Number === void 0 ? void 0 : _points$Number.tooltipPosition;
},
settings: {
stroke,
strokeWidth,
fill,
nameKey: undefined,
dataKey,
name: getTooltipNameProp(name, dataKey),
hide,
type: tooltipType,
color: fill,
unit: '',
// why doesn't Scatter support unit?
formatter,
graphicalItemId: id
}
};
return /*#__PURE__*/React.createElement(SetTooltipEntrySettings, {
tooltipEntrySettings: tooltipEntrySettings
});
});
function ScatterLine(_ref2) {
var points = _ref2.points,
props = _ref2.props;
var line = props.line,
lineType = props.lineType,
lineJointType = props.lineJointType;
if (!line) {
return null;
}
var scatterProps = svgPropertiesNoEvents(props);
var customLineProps = svgPropertiesNoEventsFromUnknown(line);
var linePoints, lineItem;
if (lineType === 'joint') {
linePoints = points.map(entry => {
var _entry$cx, _entry$cy;
return {
x: (_entry$cx = entry.cx) !== null && _entry$cx !== void 0 ? _entry$cx : null,
y: (_entry$cy = entry.cy) !== null && _entry$cy !== void 0 ? _entry$cy : null
};
});
} else if (lineType === 'fitting') {
var _getLinearRegression = getLinearRegression(points),
xmin = _getLinearRegression.xmin,
xmax = _getLinearRegression.xmax,
a = _getLinearRegression.a,
b = _getLinearRegression.b;
var linearExp = x => a * x + b;
linePoints = [{
x: xmin,
y: linearExp(xmin)
}, {
x: xmax,
y: linearExp(xmax)
}];
}
var lineProps = _objectSpread(_objectSpread(_objectSpread({}, scatterProps), {}, {
// @ts-expect-error customLineProps is contributing unknown props
fill: 'none',
// @ts-expect-error customLineProps is contributing unknown props
stroke: scatterProps && scatterProps.fill
}, customLineProps), {}, {
// @ts-expect-error linePoints is used before it is assigned (???)
points: linePoints
});
if (/*#__PURE__*/React.isValidElement(line)) {
lineItem = /*#__PURE__*/React.cloneElement(line, lineProps);
} else if (typeof line === 'function') {
lineItem = line(lineProps);
} else {
lineItem = /*#__PURE__*/React.createElement(Curve, _extends({}, lineProps, {
type: lineJointType
}));
}
return /*#__PURE__*/React.createElement(Layer, {
className: "recharts-scatter-line",
key: "recharts-scatter-line"
}, lineItem);
}
function ScatterLabelListProvider(_ref3) {
var showLabels = _ref3.showLabels,
points = _ref3.points,
children = _ref3.children;
var chartViewBox = useViewBox();
var labelListEntries = useMemo(() => {
return points === null || points === void 0 ? void 0 : points.map(point => {
var _point$x, _point$y;
var viewBox = {
/*
* Scatter label uses x and y as the reference point for the label,
* not cx and cy.
*/
x: (_point$x = point.x) !== null && _point$x !== void 0 ? _point$x : 0,
/*
* Scatter label uses x and y as the reference point for the label,
* not cx and cy.
*/
y: (_point$y = point.y) !== null && _point$y !== void 0 ? _point$y : 0,
width: point.width,
height: point.height,
lowerWidth: point.width,
upperWidth: point.width
};
return _objectSpread(_objectSpread({}, viewBox), {}, {
/*
* Here we put undefined because Scatter shows two values usually, one for X and one for Y.
* LabelList will see this undefined and will use its own `dataKey` prop to determine which value to show,
* using the payload below.
*/
value: undefined,
payload: point.payload,
viewBox,
parentViewBox: chartViewBox,
fill: undefined
});
});
}, [chartViewBox, points]);
return /*#__PURE__*/React.createElement(CartesianLabelListContextProvider, {
value: showLabels ? labelListEntries : undefined
}, children);
}
/**
* Individual scatter point component that subscribes to its own isActive state.
* This avoids re-rendering all points when the active index changes
* only the point becoming active and the point becoming inactive re-render.
*
* @param entry The scatter point data including coordinates, size, and tooltip payload
* @param index The index of this point in the points array
* @param shape The default shape to render for inactive points
* @param activeShape The shape to render when this point is active, or undefined if no active shape
* @param baseProps SVG presentation attributes (fill, stroke, etc.) shared across all points
* @param id The graphical item ID of the parent Scatter component
* @param restOfAllOtherProps Remaining Scatter props for user-provided event handlers via adaptEventsOfChild
* @param onMouseEnterFromContext Curried mouse enter handler that dispatches tooltip activation
* @param onMouseLeaveFromContext Curried mouse leave handler that dispatches tooltip deactivation
* @param onClickFromContext Curried click handler that dispatches tooltip click activation
*/
function ScatterPoint(_ref4) {
var _useAppSelector;
var entry = _ref4.entry,
index = _ref4.index,
shape = _ref4.shape,
activeShape = _ref4.activeShape,
baseProps = _ref4.baseProps,
id = _ref4.id,
restOfAllOtherProps = _ref4.restOfAllOtherProps,
animationElapsedTime = _ref4.animationElapsedTime,
isAnimating = _ref4.isAnimating,
isEntrance = _ref4.isEntrance,
onMouseEnterFromContext = _ref4.onMouseEnterFromContext,
onMouseLeaveFromContext = _ref4.onMouseLeaveFromContext,
onClickFromContext = _ref4.onClickFromContext;
var hasActiveShape = activeShape != null && activeShape !== false;
var selectIsActive = useMemo(() => {
var strIndex = String(index);
return state => hasActiveShape && selectActiveTooltipIndex(state) === strIndex;
}, [hasActiveShape, index]);
var isActive = (_useAppSelector = useAppSelector(selectIsActive)) !== null && _useAppSelector !== void 0 ? _useAppSelector : false;
// isActive is only true when hasActiveShape is true, so activeShape is defined here
var option = isActive && activeShape != null && activeShape !== false ? activeShape : shape;
var symbolProps = _objectSpread(_objectSpread(_objectSpread({}, baseProps), entry), {}, {
isActive,
index,
animationElapsedTime,
isAnimating,
isEntrance,
[DATA_ITEM_GRAPHICAL_ITEM_ID_ATTRIBUTE_NAME]: String(id)
});
return /*#__PURE__*/React.createElement(ZIndexLayer
/*
* inactive Scatters use the parent zIndex, which is represented by undefined here.
* ZIndexLayer will render undefined zIndex as-is, as regular children, without portals.
* Active Scatters use the activeDot zIndex so they render above other elements.
*/, {
zIndex: isActive ? DefaultZIndexes.activeDot : undefined
}, /*#__PURE__*/React.createElement(Layer, _extends({
className: "recharts-scatter-symbol"
}, adaptEventsOfChild(restOfAllOtherProps, entry, index), {
onMouseEnter: onMouseEnterFromContext(entry, index),
onMouseLeave: onMouseLeaveFromContext(entry, index),
onClick: onClickFromContext(entry, index)
}), /*#__PURE__*/React.createElement(ScatterSymbol, _extends({
option: option
}, symbolProps))));
}
function ScatterSymbols(props) {
var points = props.points,
allOtherScatterProps = props.allOtherScatterProps,
animationElapsedTime = props.animationElapsedTime,
isAnimating = props.isAnimating,
isEntrance = props.isEntrance;
var shape = allOtherScatterProps.shape,
activeShape = allOtherScatterProps.activeShape,
dataKey = allOtherScatterProps.dataKey;
var id = allOtherScatterProps.id,
allOtherPropsWithoutId = _objectWithoutProperties(allOtherScatterProps, _excluded);
var onMouseEnterFromProps = allOtherScatterProps.onMouseEnter,
onItemClickFromProps = allOtherScatterProps.onClick,
onMouseLeaveFromProps = allOtherScatterProps.onMouseLeave,
restOfAllOtherProps = _objectWithoutProperties(allOtherScatterProps, _excluded2);
var onMouseEnterFromContext = useMouseEnterItemDispatch(onMouseEnterFromProps, dataKey, id);
var onMouseLeaveFromContext = useMouseLeaveItemDispatch(onMouseLeaveFromProps);
var onClickFromContext = useMouseClickItemDispatch(onItemClickFromProps, dataKey, id);
if (!isNonEmptyArray(points)) {
return null;
}
var baseProps = svgPropertiesNoEvents(allOtherPropsWithoutId);
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ScatterLine, {
points: points,
props: allOtherPropsWithoutId
}), points.map((entry, i) => /*#__PURE__*/React.createElement(ScatterPoint, {
key: "symbol-".concat(entry === null || entry === void 0 ? void 0 : entry.cx, "-").concat(entry === null || entry === void 0 ? void 0 : entry.cy, "-").concat(entry === null || entry === void 0 ? void 0 : entry.size, "-").concat(i),
entry: entry,
index: i,
shape: shape,
activeShape: activeShape,
baseProps: baseProps,
id: id,
restOfAllOtherProps: restOfAllOtherProps,
animationElapsedTime: animationElapsedTime,
isAnimating: isAnimating,
isEntrance: isEntrance,
onMouseEnterFromContext: onMouseEnterFromContext,
onMouseLeaveFromContext: onMouseLeaveFromContext,
onClickFromContext: onClickFromContext
})));
}
var defaultScatterAnimateItems = (items, animationElapsedTime) => {
if (items == null) return [];
if (animationElapsedTime === 1) {
return items.flatMap(item => item.status === 'removed' ? [] : [item.next]);
}
return items.flatMap(item => {
if (item.status === 'removed') return [];
if (item.status === 'matched') {
return [_objectSpread(_objectSpread({}, item.next), {}, {
cx: item.next.cx == null ? undefined : interpolate(item.prev.cx, item.next.cx, animationElapsedTime),
cy: item.next.cy == null ? undefined : interpolate(item.prev.cy, item.next.cy, animationElapsedTime),
size: interpolate(item.prev.size, item.next.size, animationElapsedTime)
})];
}
// added
return [_objectSpread(_objectSpread({}, item.next), {}, {
size: interpolate(0, item.next.size, animationElapsedTime)
})];
});
};
function SymbolsWithAnimation(_ref5) {
var previousPointsRef = _ref5.previousPointsRef,
props = _ref5.props;
var points = props.points,
isAnimationActive = props.isAnimationActive,
animationBegin = props.animationBegin,
animationDuration = props.animationDuration,
animationEasing = props.animationEasing,
animationInterpolateFn = props.animationInterpolateFn;
var _useAnimationCallback = useAnimationCallbacks(),
isAnimating = _useAnimationCallback.isAnimating,
handleAnimationStart = _useAnimationCallback.handleAnimationStart,
handleAnimationEnd = _useAnimationCallback.handleAnimationEnd;
var layout = useCartesianChartLayout();
if (layout == null) return null;
return /*#__PURE__*/React.createElement(ScatterLabelListProvider, {
showLabels: !isAnimating,
points: points
}, /*#__PURE__*/React.createElement(AnimatedItems, {
animationInput: props,
animationIdPrefix: "recharts-scatter-",
items: points,
previousItemsRef: previousPointsRef,
isAnimationActive: isAnimationActive,
animationBegin: animationBegin,
animationDuration: animationDuration,
animationEasing: animationEasing,
onAnimationStart: handleAnimationStart,
onAnimationEnd: handleAnimationEnd,
animationInterpolateFn: animationInterpolateFn,
animationMatchBy: props.animationMatchBy,
layout: layout
}, (stepData, animationElapsedTime, isEntrance) => /*#__PURE__*/React.createElement(Layer, null, /*#__PURE__*/React.createElement(ScatterSymbols, {
points: stepData,
allOtherScatterProps: props,
showLabels: !isAnimating,
animationElapsedTime: animationElapsedTime,
isAnimating: isAnimating || animationElapsedTime < 1,
isEntrance: isEntrance
}))), props.children, /*#__PURE__*/React.createElement(LabelListFromLabelProp, {
label: props.label
}));
}
export function computeScatterPoints(_ref6) {
var displayedData = _ref6.displayedData,
xAxis = _ref6.xAxis,
yAxis = _ref6.yAxis,
zAxis = _ref6.zAxis,
scatterSettings = _ref6.scatterSettings,
xAxisTicks = _ref6.xAxisTicks,
yAxisTicks = _ref6.yAxisTicks,
cells = _ref6.cells;
var xAxisDataKey = isNullish(xAxis.dataKey) ? scatterSettings.dataKey : xAxis.dataKey;
var yAxisDataKey = isNullish(yAxis.dataKey) ? scatterSettings.dataKey : yAxis.dataKey;
var zAxisDataKey = zAxis && zAxis.dataKey;
var defaultRangeZ = zAxis ? zAxis.range : implicitZAxis.range;
var defaultZ = defaultRangeZ && defaultRangeZ[0];
var xBandSize = xAxis.scale.bandwidth ? xAxis.scale.bandwidth() : 0;
var yBandSize = yAxis.scale.bandwidth ? yAxis.scale.bandwidth() : 0;
return displayedData.map((entry, index) => {
var x = getValueByDataKey(entry, xAxisDataKey);
var y = getValueByDataKey(entry, yAxisDataKey);
var z = !isNullish(zAxisDataKey) && getValueByDataKey(entry, zAxisDataKey) || '-';
var tooltipPayload = [{
name: isNullish(xAxis.dataKey) ? scatterSettings.name : xAxis.name || String(xAxis.dataKey),
unit: xAxis.unit || '',
// @ts-expect-error getValueByDataKey does not validate the output type
value: x,
payload: entry,
dataKey: xAxisDataKey,
type: scatterSettings.tooltipType,
graphicalItemId: scatterSettings.id
}, {
name: isNullish(yAxis.dataKey) ? scatterSettings.name : yAxis.name || String(yAxis.dataKey),
unit: yAxis.unit || '',
// @ts-expect-error getValueByDataKey does not validate the output type
value: y,
payload: entry,
dataKey: yAxisDataKey,
type: scatterSettings.tooltipType,
graphicalItemId: scatterSettings.id
}];
if (z !== '-' && zAxis != null) {
tooltipPayload.push({
// @ts-expect-error name prop should not have dataKey in it
name: zAxis.name || zAxis.dataKey,
unit: zAxis.unit || '',
// @ts-expect-error getValueByDataKey does not validate the output type
value: z,
payload: entry,
dataKey: zAxisDataKey,
type: scatterSettings.tooltipType,
graphicalItemId: scatterSettings.id
});
}
var cx = getCateCoordinateOfLine({
axis: xAxis,
ticks: xAxisTicks,
bandSize: xBandSize,
entry,
index,
dataKey: xAxisDataKey
});
var cy = getCateCoordinateOfLine({
axis: yAxis,
ticks: yAxisTicks,
bandSize: yBandSize,
entry,
index,
dataKey: yAxisDataKey
});
var size = z !== '-' && zAxis != null ? zAxis.scale.map(z) : defaultZ;
var radius = size == null ? 0 : Math.sqrt(Math.max(size, 0) / Math.PI);
return _objectSpread(_objectSpread({}, entry), {}, {
cx,
cy,
x: cx == null ? undefined : cx - radius,
y: cy == null ? undefined : cy - radius,
width: 2 * radius,
height: 2 * radius,
size,
node: {
x,
y,
z
},
tooltipPayload,
tooltipPosition: {
x: cx,
y: cy
},
payload: entry
}, cells && cells[index] && cells[index].props);
});
}
var errorBarDataPointFormatter = (dataPoint, dataKey, direction) => {
return {
x: dataPoint.cx,
y: dataPoint.cy,
value: direction === 'x' ? Number(dataPoint.node.x) : Number(dataPoint.node.y),
// @ts-expect-error getValueByDataKey does not validate the output type
errorVal: getValueByDataKey(dataPoint, dataKey)
};
};
function ScatterWithId(props) {
var hide = props.hide,
points = props.points,
className = props.className,
needClip = props.needClip,
xAxisId = props.xAxisId,
yAxisId = props.yAxisId,
id = props.id;
var previousPointsRef = useRef(null);
if (hide) {
return null;
}
var layerClass = clsx('recharts-scatter', className);
var clipPathId = id;
return /*#__PURE__*/React.createElement(ZIndexLayer, {
zIndex: props.zIndex
}, /*#__PURE__*/React.createElement(Layer, {
className: layerClass,
clipPath: needClip ? "url(#clipPath-".concat(clipPathId, ")") : undefined,
id: id
}, needClip && /*#__PURE__*/React.createElement("defs", null, /*#__PURE__*/React.createElement(GraphicalItemClipPath, {
clipPathId: clipPathId,
xAxisId: xAxisId,
yAxisId: yAxisId
})), /*#__PURE__*/React.createElement(SetErrorBarContext, {
xAxisId: xAxisId,
yAxisId: yAxisId,
data: points,
dataPointFormatter: errorBarDataPointFormatter,
errorBarOffset: 0
}, /*#__PURE__*/React.createElement(Layer, {
key: "recharts-scatter-symbols"
}, /*#__PURE__*/React.createElement(SymbolsWithAnimation, {
props: props,
previousPointsRef: previousPointsRef
})))));
}
export var defaultScatterProps = {
xAxisId: 0,
yAxisId: 0,
zAxisId: 0,
label: false,
line: false,
legendType: 'circle',
lineType: 'joint',
lineJointType: 'linear',
shape: 'circle',
hide: false,
isAnimationActive: 'auto',
animationBegin: 0,
animationDuration: 400,
animationEasing: 'linear',
animationMatchBy: matchAppend,
animationInterpolateFn: defaultScatterAnimateItems,
zIndex: DefaultZIndexes.scatter
};
function ScatterImpl(props) {
var _resolveDefaultProps = resolveDefaultProps(props, defaultScatterProps),
animationBegin = _resolveDefaultProps.animationBegin,
animationDuration = _resolveDefaultProps.animationDuration,
animationEasing = _resolveDefaultProps.animationEasing,
hide = _resolveDefaultProps.hide,
isAnimationActive = _resolveDefaultProps.isAnimationActive,
legendType = _resolveDefaultProps.legendType,
lineJointType = _resolveDefaultProps.lineJointType,
lineType = _resolveDefaultProps.lineType,
shape = _resolveDefaultProps.shape,
xAxisId = _resolveDefaultProps.xAxisId,
yAxisId = _resolveDefaultProps.yAxisId,
zAxisId = _resolveDefaultProps.zAxisId,
everythingElse = _objectWithoutProperties(_resolveDefaultProps, _excluded3);
var _useNeedsClip = useNeedsClip(xAxisId, yAxisId),
needClip = _useNeedsClip.needClip;
var cells = useMemo(() => findAllByType(props.children, Cell), [props.children]);
var isPanorama = useIsPanorama();
var points = useAppSelector(state => {
return selectScatterPoints(state, xAxisId, yAxisId, zAxisId, props.id, cells, isPanorama);
});
if (needClip == null) {
return null;
}
if (points == null) {
return null;
}
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(SetScatterTooltipEntrySettings, {
dataKey: props.dataKey,
points: points,
stroke: props.stroke,
strokeWidth: props.strokeWidth,
fill: props.fill,
name: props.name,
hide: props.hide,
formatter: props.formatter,
tooltipType: props.tooltipType,
id: props.id
}), /*#__PURE__*/React.createElement(ScatterWithId, _extends({}, everythingElse, {
xAxisId: xAxisId,
yAxisId: yAxisId,
zAxisId: zAxisId,
lineType: lineType,
lineJointType: lineJointType,
legendType: legendType,
shape: shape,
hide: hide,
isAnimationActive: isAnimationActive,
animationBegin: animationBegin,
animationDuration: animationDuration,
animationEasing: animationEasing,
points: points,
needClip: needClip
})));
}
function ScatterFn(outsideProps) {
var props = resolveDefaultProps(outsideProps, defaultScatterProps);
var isPanorama = useIsPanorama();
return /*#__PURE__*/React.createElement(RegisterGraphicalItemId, {
id: props.id,
type: "scatter"
}, id => /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(SetLegendPayload, {
legendPayload: computeLegendPayloadFromScatterProps(props)
}), /*#__PURE__*/React.createElement(SetCartesianGraphicalItem, {
type: "scatter",
id: id,
data: props.data,
xAxisId: props.xAxisId,
yAxisId: props.yAxisId,
zAxisId: props.zAxisId,
dataKey: props.dataKey,
hide: props.hide,
name: props.name,
tooltipType: props.tooltipType,
isPanorama: isPanorama
}), /*#__PURE__*/React.createElement(ScatterImpl, _extends({}, props, {
id: id
}))));
}
/**
* @provides LabelListContext
* @provides ErrorBarContext
* @provides CellReader
* @consumes CartesianChartContext
*/
export var Scatter = /*#__PURE__*/React.memo(ScatterFn, propsAreEqual);
// @ts-expect-error we need to set the displayName for debugging purposes
Scatter.displayName = 'Scatter';

168
frontend/node_modules/recharts/es6/cartesian/XAxis.js generated vendored Normal file
View file

@ -0,0 +1,168 @@
var _excluded = ["type"],
_excluded2 = ["dangerouslySetInnerHTML", "ticks", "scale"],
_excluded3 = ["id", "scale"];
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
/**
* @fileOverview X Axis
*/
import * as React from 'react';
import { useLayoutEffect, useMemo, useRef } from 'react';
import { clsx } from 'clsx';
import { CartesianAxis, defaultCartesianAxisProps } from './CartesianAxis';
import { useAppDispatch, useAppSelector } from '../state/hooks';
import { addXAxis, replaceXAxis, removeXAxis } from '../state/cartesianAxisSlice';
import { implicitXAxis, selectTicksOfAxis, selectXAxisPosition, selectXAxisSettingsNoDefaults, selectXAxisSize } from '../state/selectors/axisSelectors';
import { selectAxisViewBox } from '../state/selectors/selectChartOffsetInternal';
import { useIsPanorama } from '../context/PanoramaContext';
import { resolveDefaultProps } from '../util/resolveDefaultProps';
import { axisPropsAreEqual } from '../util/axisPropsAreEqual';
import { useCartesianChartLayout } from '../context/chartLayoutContext';
import { getAxisTypeBasedOnLayout } from '../util/getAxisTypeBasedOnLayout';
function SetXAxisSettings(props) {
var dispatch = useAppDispatch();
var prevSettingsRef = useRef(null);
var layout = useCartesianChartLayout();
var typeFromProps = props.type,
restProps = _objectWithoutProperties(props, _excluded);
var evaluatedType = getAxisTypeBasedOnLayout(layout, 'xAxis', typeFromProps);
var settings = useMemo(() => {
if (evaluatedType == null) {
return undefined;
}
return _objectSpread(_objectSpread({}, restProps), {}, {
type: evaluatedType
});
}, [restProps, evaluatedType]);
useLayoutEffect(() => {
if (settings == null) {
return;
}
if (prevSettingsRef.current === null) {
dispatch(addXAxis(settings));
} else if (prevSettingsRef.current !== settings) {
dispatch(replaceXAxis({
prev: prevSettingsRef.current,
next: settings
}));
}
prevSettingsRef.current = settings;
}, [settings, dispatch]);
useLayoutEffect(() => {
return () => {
if (prevSettingsRef.current) {
dispatch(removeXAxis(prevSettingsRef.current));
prevSettingsRef.current = null;
}
};
}, [dispatch]);
return null;
}
var XAxisImpl = props => {
var xAxisId = props.xAxisId,
className = props.className;
var viewBox = useAppSelector(selectAxisViewBox);
var isPanorama = useIsPanorama();
var axisType = 'xAxis';
var cartesianTickItems = useAppSelector(state => selectTicksOfAxis(state, axisType, xAxisId, isPanorama));
var axisSize = useAppSelector(state => selectXAxisSize(state, xAxisId));
var position = useAppSelector(state => selectXAxisPosition(state, xAxisId));
/*
* Here we select settings from the store and prefer to use them instead of the actual props
* so that the chart is consistent. If we used the props directly, some components will use axis settings
* from state and some from props and because there is a render step between these two, they might be showing different things.
* https://github.com/recharts/recharts/issues/6257
*/
var synchronizedSettings = useAppSelector(state => selectXAxisSettingsNoDefaults(state, xAxisId));
if (axisSize == null || position == null || synchronizedSettings == null) {
return null;
}
var dangerouslySetInnerHTML = props.dangerouslySetInnerHTML,
ticks = props.ticks,
del = props.scale,
allOtherProps = _objectWithoutProperties(props, _excluded2);
var id = synchronizedSettings.id,
del2 = synchronizedSettings.scale,
restSynchronizedSettings = _objectWithoutProperties(synchronizedSettings, _excluded3);
return /*#__PURE__*/React.createElement(CartesianAxis, _extends({}, allOtherProps, restSynchronizedSettings, {
x: position.x,
y: position.y,
width: axisSize.width,
height: axisSize.height,
className: clsx("recharts-".concat(axisType, " ").concat(axisType), className),
viewBox: viewBox,
ticks: cartesianTickItems,
axisType: axisType,
axisId: xAxisId
}));
};
export var xAxisDefaultProps = {
allowDataOverflow: implicitXAxis.allowDataOverflow,
allowDecimals: implicitXAxis.allowDecimals,
allowDuplicatedCategory: implicitXAxis.allowDuplicatedCategory,
angle: implicitXAxis.angle,
axisLine: defaultCartesianAxisProps.axisLine,
height: implicitXAxis.height,
hide: false,
includeHidden: implicitXAxis.includeHidden,
interval: implicitXAxis.interval,
label: false,
minTickGap: implicitXAxis.minTickGap,
mirror: implicitXAxis.mirror,
orientation: implicitXAxis.orientation,
padding: implicitXAxis.padding,
reversed: implicitXAxis.reversed,
scale: implicitXAxis.scale,
tick: implicitXAxis.tick,
tickCount: implicitXAxis.tickCount,
tickLine: defaultCartesianAxisProps.tickLine,
tickSize: defaultCartesianAxisProps.tickSize,
type: implicitXAxis.type,
niceTicks: implicitXAxis.niceTicks,
xAxisId: 0
};
var XAxisSettingsDispatcher = outsideProps => {
var props = resolveDefaultProps(outsideProps, xAxisDefaultProps);
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(SetXAxisSettings, {
allowDataOverflow: props.allowDataOverflow,
allowDecimals: props.allowDecimals,
allowDuplicatedCategory: props.allowDuplicatedCategory,
angle: props.angle,
dataKey: props.dataKey,
domain: props.domain,
height: props.height,
hide: props.hide,
id: props.xAxisId,
includeHidden: props.includeHidden,
interval: props.interval,
minTickGap: props.minTickGap,
mirror: props.mirror,
name: props.name,
orientation: props.orientation,
padding: props.padding,
reversed: props.reversed,
scale: props.scale,
tick: props.tick,
tickCount: props.tickCount,
tickFormatter: props.tickFormatter,
ticks: props.ticks,
type: props.type,
unit: props.unit,
niceTicks: props.niceTicks
}), /*#__PURE__*/React.createElement(XAxisImpl, props));
};
/**
* @consumes CartesianViewBoxContext
* @provides CartesianLabelContext
*/
export var XAxis = /*#__PURE__*/React.memo(XAxisSettingsDispatcher, axisPropsAreEqual);
// @ts-expect-error we need to set the displayName for debugging purposes
XAxis.displayName = 'XAxis';

202
frontend/node_modules/recharts/es6/cartesian/YAxis.js generated vendored Normal file
View file

@ -0,0 +1,202 @@
var _excluded = ["type"],
_excluded2 = ["dangerouslySetInnerHTML", "ticks", "scale"],
_excluded3 = ["id", "scale"];
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
import * as React from 'react';
import { isValidElement, useLayoutEffect, useMemo, useRef } from 'react';
import { clsx } from 'clsx';
import { CartesianAxis, defaultCartesianAxisProps } from './CartesianAxis';
import { addYAxis, replaceYAxis, removeYAxis, updateYAxisWidth } from '../state/cartesianAxisSlice';
import { useAppDispatch, useAppSelector } from '../state/hooks';
import { implicitYAxis, selectTicksOfAxis, selectYAxisPosition, selectYAxisSettingsNoDefaults, selectYAxisSize } from '../state/selectors/axisSelectors';
import { selectAxisViewBox } from '../state/selectors/selectChartOffsetInternal';
import { useIsPanorama } from '../context/PanoramaContext';
import { isLabelContentAFunction } from '../component/Label';
import { resolveDefaultProps } from '../util/resolveDefaultProps';
import { axisPropsAreEqual } from '../util/axisPropsAreEqual';
import { useCartesianChartLayout } from '../context/chartLayoutContext';
import { getAxisTypeBasedOnLayout } from '../util/getAxisTypeBasedOnLayout';
function SetYAxisSettings(props) {
var dispatch = useAppDispatch();
var prevSettingsRef = useRef(null);
var layout = useCartesianChartLayout();
var typeFromProps = props.type,
restProps = _objectWithoutProperties(props, _excluded);
var evaluatedType = getAxisTypeBasedOnLayout(layout, 'yAxis', typeFromProps);
var settings = useMemo(() => {
if (evaluatedType == null) {
return undefined;
}
return _objectSpread(_objectSpread({}, restProps), {}, {
type: evaluatedType
});
}, [evaluatedType, restProps]);
useLayoutEffect(() => {
if (settings == null) {
return;
}
if (prevSettingsRef.current === null) {
dispatch(addYAxis(settings));
} else if (prevSettingsRef.current !== settings) {
dispatch(replaceYAxis({
prev: prevSettingsRef.current,
next: settings
}));
}
prevSettingsRef.current = settings;
}, [settings, dispatch]);
useLayoutEffect(() => {
return () => {
if (prevSettingsRef.current) {
dispatch(removeYAxis(prevSettingsRef.current));
prevSettingsRef.current = null;
}
};
}, [dispatch]);
return null;
}
function YAxisImpl(props) {
var yAxisId = props.yAxisId,
className = props.className,
width = props.width,
label = props.label;
var cartesianAxisRef = useRef(null);
var labelRef = useRef(null);
var viewBox = useAppSelector(selectAxisViewBox);
var isPanorama = useIsPanorama();
var dispatch = useAppDispatch();
var axisType = 'yAxis';
var axisSize = useAppSelector(state => selectYAxisSize(state, yAxisId));
var position = useAppSelector(state => selectYAxisPosition(state, yAxisId));
var cartesianTickItems = useAppSelector(state => selectTicksOfAxis(state, axisType, yAxisId, isPanorama));
/*
* Here we select settings from the store and prefer to use them instead of the actual props
* so that the chart is consistent. If we used the props directly, some components will use axis settings
* from state and some from props and because there is a render step between these two, they might be showing different things.
* https://github.com/recharts/recharts/issues/6257
*/
var synchronizedSettings = useAppSelector(state => selectYAxisSettingsNoDefaults(state, yAxisId));
useLayoutEffect(() => {
// No dynamic width calculation is done when width !== 'auto'
// or when a function/react element is used for label
if (width !== 'auto' || !axisSize || isLabelContentAFunction(label) || /*#__PURE__*/isValidElement(label) || synchronizedSettings == null) {
return;
}
var axisComponent = cartesianAxisRef.current;
if (!axisComponent) {
return;
}
var updatedYAxisWidth = axisComponent.getCalculatedWidth();
// if the width has changed, dispatch an action to update the width
if (Math.round(axisSize.width) !== Math.round(updatedYAxisWidth)) {
dispatch(updateYAxisWidth({
id: yAxisId,
width: updatedYAxisWidth
}));
}
}, [
// The dependency on cartesianAxisRef.current is not needed because useLayoutEffect will run after every render.
// The ref will be populated by then.
// To re-run this effect when ticks change, we can depend on the ticks array from the store.
cartesianTickItems, axisSize, dispatch, label, yAxisId, width, synchronizedSettings]);
if (axisSize == null || position == null || synchronizedSettings == null) {
return null;
}
var dangerouslySetInnerHTML = props.dangerouslySetInnerHTML,
ticks = props.ticks,
del = props.scale,
allOtherProps = _objectWithoutProperties(props, _excluded2);
var id = synchronizedSettings.id,
del2 = synchronizedSettings.scale,
restSynchronizedSettings = _objectWithoutProperties(synchronizedSettings, _excluded3);
return /*#__PURE__*/React.createElement(CartesianAxis, _extends({}, allOtherProps, restSynchronizedSettings, {
ref: cartesianAxisRef,
labelRef: labelRef,
x: position.x,
y: position.y,
tickTextProps: width === 'auto' ? {
width: undefined
} : {
width
},
width: axisSize.width,
height: axisSize.height,
className: clsx("recharts-".concat(axisType, " ").concat(axisType), className),
viewBox: viewBox,
ticks: cartesianTickItems,
axisType: axisType,
axisId: yAxisId
}));
}
export var yAxisDefaultProps = {
allowDataOverflow: implicitYAxis.allowDataOverflow,
allowDecimals: implicitYAxis.allowDecimals,
allowDuplicatedCategory: implicitYAxis.allowDuplicatedCategory,
angle: implicitYAxis.angle,
axisLine: defaultCartesianAxisProps.axisLine,
hide: false,
includeHidden: implicitYAxis.includeHidden,
interval: implicitYAxis.interval,
label: false,
minTickGap: implicitYAxis.minTickGap,
mirror: implicitYAxis.mirror,
orientation: implicitYAxis.orientation,
padding: implicitYAxis.padding,
reversed: implicitYAxis.reversed,
scale: implicitYAxis.scale,
tick: implicitYAxis.tick,
tickCount: implicitYAxis.tickCount,
tickLine: defaultCartesianAxisProps.tickLine,
tickSize: defaultCartesianAxisProps.tickSize,
type: implicitYAxis.type,
niceTicks: implicitYAxis.niceTicks,
width: implicitYAxis.width,
yAxisId: 0
};
var YAxisSettingsDispatcher = outsideProps => {
var props = resolveDefaultProps(outsideProps, yAxisDefaultProps);
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(SetYAxisSettings, {
interval: props.interval,
id: props.yAxisId,
scale: props.scale,
type: props.type,
domain: props.domain,
allowDataOverflow: props.allowDataOverflow,
dataKey: props.dataKey,
allowDuplicatedCategory: props.allowDuplicatedCategory,
allowDecimals: props.allowDecimals,
tickCount: props.tickCount,
padding: props.padding,
includeHidden: props.includeHidden,
reversed: props.reversed,
ticks: props.ticks,
width: props.width,
orientation: props.orientation,
mirror: props.mirror,
hide: props.hide,
unit: props.unit,
name: props.name,
angle: props.angle,
minTickGap: props.minTickGap,
tick: props.tick,
tickFormatter: props.tickFormatter,
niceTicks: props.niceTicks
}), /*#__PURE__*/React.createElement(YAxisImpl, props));
};
/**
* @consumes CartesianViewBoxContext
* @provides CartesianLabelContext
*/
export var YAxis = /*#__PURE__*/React.memo(YAxisSettingsDispatcher, axisPropsAreEqual);
// @ts-expect-error we need to set the displayName for debugging purposes
YAxis.displayName = 'YAxis';

61
frontend/node_modules/recharts/es6/cartesian/ZAxis.js generated vendored Normal file
View file

@ -0,0 +1,61 @@
import * as React from 'react';
import { useLayoutEffect, useRef } from 'react';
import { addZAxis, removeZAxis, replaceZAxis } from '../state/cartesianAxisSlice';
import { useAppDispatch } from '../state/hooks';
import { implicitZAxis } from '../state/selectors/axisSelectors';
import { resolveDefaultProps } from '../util/resolveDefaultProps';
function SetZAxisSettings(settings) {
var dispatch = useAppDispatch();
var prevSettingsRef = useRef(null);
useLayoutEffect(() => {
if (prevSettingsRef.current === null) {
dispatch(addZAxis(settings));
} else if (prevSettingsRef.current !== settings) {
dispatch(replaceZAxis({
prev: prevSettingsRef.current,
next: settings
}));
}
prevSettingsRef.current = settings;
}, [settings, dispatch]);
useLayoutEffect(() => {
return () => {
if (prevSettingsRef.current) {
dispatch(removeZAxis(prevSettingsRef.current));
prevSettingsRef.current = null;
}
};
}, [dispatch]);
return null;
}
export var zAxisDefaultProps = {
zAxisId: 0,
range: implicitZAxis.range,
scale: implicitZAxis.scale,
type: implicitZAxis.type
};
/**
* Virtual axis, does not render anything itself. Has no ticks, grid lines, or labels.
* Useful for dynamically setting Scatter point size, based on data.
*
* @consumes CartesianViewBoxContext
*/
export function ZAxis(outsideProps) {
var props = resolveDefaultProps(outsideProps, zAxisDefaultProps);
return /*#__PURE__*/React.createElement(SetZAxisSettings, {
domain: props.domain,
id: props.zAxisId,
dataKey: props.dataKey,
name: props.name,
unit: props.unit,
range: props.range,
scale: props.scale,
type: props.type,
allowDuplicatedCategory: implicitZAxis.allowDuplicatedCategory,
allowDataOverflow: implicitZAxis.allowDataOverflow,
reversed: implicitZAxis.reversed,
includeHidden: implicitZAxis.includeHidden
});
}
ZAxis.displayName = 'ZAxis';

View file

@ -0,0 +1,193 @@
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
import { getPercentValue, isNumber, isPercent } from '../util/DataUtils';
import { cartesianViewBoxToTrapezoid } from '../context/chartLayoutContext';
/**
* Calculates the position and alignment for a generic element in a Cartesian coordinate system.
*
* @param options - The options including viewBox, position, and offset.
* @returns The calculated x, y, alignment and size.
*/
export var getCartesianPosition = options => {
var viewBox = options.viewBox,
position = options.position,
_options$offset = options.offset,
offset = _options$offset === void 0 ? 0 : _options$offset,
parentViewBoxFromOptions = options.parentViewBox,
clamp = options.clamp;
var _cartesianViewBoxToTr = cartesianViewBoxToTrapezoid(viewBox),
x = _cartesianViewBoxToTr.x,
y = _cartesianViewBoxToTr.y,
height = _cartesianViewBoxToTr.height,
upperWidth = _cartesianViewBoxToTr.upperWidth,
lowerWidth = _cartesianViewBoxToTr.lowerWidth;
// Funnel.tsx provides a viewBox where `x` is the top-left of the trapezoid shape.
var upperX = x;
// The trapezoid is centered, so we can calculate the other corners from the top-left.
var lowerX = x + (upperWidth - lowerWidth) / 2;
// middleX is the x-coordinate of the left edge at the vertical midpoint of the trapezoid.
var middleX = (upperX + lowerX) / 2;
// The width of the trapezoid at its vertical midpoint.
var midHeightWidth = (upperWidth + lowerWidth) / 2;
// The center x-coordinate is constant for the entire height of the trapezoid.
var centerX = upperX + upperWidth / 2;
// Define vertical offsets and position inverts based on the value being positive or negative.
// This allows labels to be positioned correctly for bars with negative height.
var verticalSign = height >= 0 ? 1 : -1;
var verticalOffset = verticalSign * offset;
var verticalEnd = verticalSign > 0 ? 'end' : 'start';
var verticalStart = verticalSign > 0 ? 'start' : 'end';
// Define horizontal offsets and position inverts based on the value being positive or negative.
// This allows labels to be positioned correctly for bars with negative width.
var horizontalSign = upperWidth >= 0 ? 1 : -1;
var horizontalOffset = horizontalSign * offset;
var horizontalEnd = horizontalSign > 0 ? 'end' : 'start';
var horizontalStart = horizontalSign > 0 ? 'start' : 'end';
// We assume parentViewBox is generic if provided.
// The user has asserted that parentViewBox will be CartesianViewBoxRequired if present.
var parentViewBox = parentViewBoxFromOptions;
if (position === 'top') {
var result = {
x: upperX + upperWidth / 2,
y: y - verticalOffset,
horizontalAnchor: 'middle',
verticalAnchor: verticalEnd
};
if (clamp && parentViewBox) {
result.height = Math.max(y - parentViewBox.y, 0);
result.width = upperWidth;
}
return result;
}
if (position === 'bottom') {
var _result = {
x: lowerX + lowerWidth / 2,
y: y + height + verticalOffset,
horizontalAnchor: 'middle',
verticalAnchor: verticalStart
};
if (clamp && parentViewBox) {
_result.height = Math.max(parentViewBox.y + parentViewBox.height - (y + height), 0);
_result.width = lowerWidth;
}
return _result;
}
if (position === 'left') {
var _result2 = {
x: middleX - horizontalOffset,
y: y + height / 2,
horizontalAnchor: horizontalEnd,
verticalAnchor: 'middle'
};
if (clamp && parentViewBox) {
_result2.width = Math.max(_result2.x - parentViewBox.x, 0);
_result2.height = height;
}
return _result2;
}
if (position === 'right') {
var _result3 = {
x: middleX + midHeightWidth + horizontalOffset,
y: y + height / 2,
horizontalAnchor: horizontalStart,
verticalAnchor: 'middle'
};
if (clamp && parentViewBox) {
_result3.width = Math.max(parentViewBox.x + parentViewBox.width - _result3.x, 0);
_result3.height = height;
}
return _result3;
}
var sizeAttrs = clamp && parentViewBox ? {
width: midHeightWidth,
height
} : {};
if (position === 'insideLeft') {
return _objectSpread({
x: middleX + horizontalOffset,
y: y + height / 2,
horizontalAnchor: horizontalStart,
verticalAnchor: 'middle'
}, sizeAttrs);
}
if (position === 'insideRight') {
return _objectSpread({
x: middleX + midHeightWidth - horizontalOffset,
y: y + height / 2,
horizontalAnchor: horizontalEnd,
verticalAnchor: 'middle'
}, sizeAttrs);
}
if (position === 'insideTop') {
return _objectSpread({
x: upperX + upperWidth / 2,
y: y + verticalOffset,
horizontalAnchor: 'middle',
verticalAnchor: verticalStart
}, sizeAttrs);
}
if (position === 'insideBottom') {
return _objectSpread({
x: lowerX + lowerWidth / 2,
y: y + height - verticalOffset,
horizontalAnchor: 'middle',
verticalAnchor: verticalEnd
}, sizeAttrs);
}
if (position === 'insideTopLeft') {
return _objectSpread({
x: upperX + horizontalOffset,
y: y + verticalOffset,
horizontalAnchor: horizontalStart,
verticalAnchor: verticalStart
}, sizeAttrs);
}
if (position === 'insideTopRight') {
return _objectSpread({
x: upperX + upperWidth - horizontalOffset,
y: y + verticalOffset,
horizontalAnchor: horizontalEnd,
verticalAnchor: verticalStart
}, sizeAttrs);
}
if (position === 'insideBottomLeft') {
return _objectSpread({
x: lowerX + horizontalOffset,
y: y + height - verticalOffset,
horizontalAnchor: horizontalStart,
verticalAnchor: verticalEnd
}, sizeAttrs);
}
if (position === 'insideBottomRight') {
return _objectSpread({
x: lowerX + lowerWidth - horizontalOffset,
y: y + height - verticalOffset,
horizontalAnchor: horizontalEnd,
verticalAnchor: verticalEnd
}, sizeAttrs);
}
if (!!position && typeof position === 'object' && (isNumber(position.x) || isPercent(position.x)) && (isNumber(position.y) || isPercent(position.y))) {
// TODO: This is not quite right. The width of the trapezoid changes with y.
// A percentage-based x should be relative to the width at that y.
// For now, we use the mid-height width as a reasonable approximation.
return _objectSpread({
x: x + getPercentValue(position.x, midHeightWidth),
y: y + getPercentValue(position.y, height),
horizontalAnchor: 'end',
verticalAnchor: 'end'
}, sizeAttrs);
}
return _objectSpread({
x: centerX,
y: y + height / 2,
horizontalAnchor: 'middle',
verticalAnchor: 'middle'
}, sizeAttrs);
};

View file

@ -0,0 +1,131 @@
import { isVisible } from '../util/TickUtils';
import { getEveryNth } from '../util/getEveryNth';
export function getEquidistantTicks(sign, boundaries, getTickSize, ticks, minTickGap) {
// If the ticks are readonly, then the slice might not be necessary
var result = (ticks || []).slice();
var initialStart = boundaries.start,
end = boundaries.end;
var index = 0;
// Premature optimisation idea 1: Estimate a lower bound, and start from there.
// For now, start from every tick
var stepsize = 1;
var start = initialStart;
var _loop = function _loop() {
// Given stepsize, evaluate whether every stepsize-th tick can be shown.
// If it can not, then increase the stepsize by 1, and try again.
var entry = ticks === null || ticks === void 0 ? void 0 : ticks[index];
// Break condition - If we have evaluated all the ticks, then we are done.
if (entry === undefined) {
return {
v: getEveryNth(ticks, stepsize)
};
}
// Check if the element collides with the next element
var i = index;
var size;
var getSize = () => {
if (size === undefined) {
size = getTickSize(entry, i);
}
return size;
};
var tickCoord = entry.coordinate;
// We will always show the first tick.
var isShow = index === 0 || isVisible(sign, tickCoord, getSize, start, end);
if (!isShow) {
// Start all over with a larger stepsize
index = 0;
start = initialStart;
stepsize += 1;
}
if (isShow) {
// If it can be shown, update the start
start = tickCoord + sign * (getSize() / 2 + minTickGap);
index += stepsize;
}
},
_ret;
while (stepsize <= result.length) {
_ret = _loop();
if (_ret) return _ret.v;
}
return [];
}
export function getEquidistantPreserveEndTicks(sign, boundaries, getTickSize, ticks, minTickGap) {
// If the ticks are readonly, then the slice might not be necessary
// Reworked logic for getEquidistantPreserveEndTicks
var result = (ticks || []).slice();
var len = result.length;
if (len === 0) {
return [];
}
var initialStart = boundaries.start,
end = boundaries.end;
// Start with stepsize = 1 (every tick) up to the maximum possible stepsize (len)
for (var stepsize = 1; stepsize <= len; stepsize++) {
// 1. Calculate the offset so the last tick (index len - 1) is always included in the sequence.
var offset = (len - 1) % stepsize;
var start = initialStart; // `start` tracks the coordinate of the last successfully drawn tick + gap
var ok = true;
// 2. Iterate through the end-anchored sequence: offset, offset + stepsize, ..., len - 1
var _loop2 = function _loop2() {
var entry = ticks[index];
if (entry == null) {
return 0; // continue
}
var i = index;
var size;
// Use a function to get size, as in the original code
var getSize = () => {
if (size === undefined) {
size = getTickSize(entry, i);
}
return size;
};
var tickCoord = entry.coordinate;
// 3. Apply visibility logic (including the first tick special case)
// The reviewer says *not* to unconditionally bypass checks for the last tick.
var isShow = index === offset || isVisible(sign, tickCoord, getSize, start, end);
if (!isShow) {
// If any tick in this end-anchored sequence fails visibility/collision,
// reject this stepsize and move to the next iteration (larger stepsize).
ok = false;
return 1; // break
}
// 4. If showable, update the 'start' coordinate for the next collision check
if (isShow) {
start = tickCoord + sign * (getSize() / 2 + minTickGap);
}
},
_ret2;
for (var index = offset; index < len; index += stepsize) {
_ret2 = _loop2();
if (_ret2 === 0) continue;
if (_ret2 === 1) break;
}
// 5. If the entire sequence for this stepsize passed the visibility check, return the result
if (ok) {
// Build the final result array explicitly using the validated stepsize and offset.
var finalTicks = [];
for (var _index = offset; _index < len; _index += stepsize) {
var tick = ticks[_index];
if (tick != null) {
finalTicks.push(tick);
}
}
return finalTicks;
}
}
// If no stepsize works (this shouldn't happen unless minTickGap is huge), return an empty array.
return [];
}

View file

@ -0,0 +1,172 @@
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
import { mathSign, isNumber } from '../util/DataUtils';
import { getStringSize } from '../util/DOMUtils';
import { Global } from '../util/Global';
import { isVisible, getTickBoundaries, getNumberIntervalTicks, getAngledTickWidth } from '../util/TickUtils';
import { getEquidistantTicks, getEquidistantPreserveEndTicks } from './getEquidistantTicks';
function getTicksEnd(sign, boundaries, getTickSize, ticks, minTickGap) {
var result = (ticks || []).slice();
var len = result.length;
var start = boundaries.start;
var end = boundaries.end;
var _loop = function _loop(i) {
var initialEntry = result[i];
if (initialEntry == null) {
return 1; // continue
}
var entry = initialEntry;
var size;
var getSize = () => {
if (size === undefined) {
size = getTickSize(initialEntry, i);
}
return size;
};
if (i === len - 1) {
var gap = sign * (entry.coordinate + sign * getSize() / 2 - end);
result[i] = entry = _objectSpread(_objectSpread({}, entry), {}, {
tickCoord: gap > 0 ? entry.coordinate - gap * sign : entry.coordinate
});
} else {
result[i] = entry = _objectSpread(_objectSpread({}, entry), {}, {
tickCoord: entry.coordinate
});
}
if (entry.tickCoord != null) {
var isShow = isVisible(sign, entry.tickCoord, getSize, start, end);
if (isShow) {
end = entry.tickCoord - sign * (getSize() / 2 + minTickGap);
result[i] = _objectSpread(_objectSpread({}, entry), {}, {
isShow: true
});
}
}
};
for (var i = len - 1; i >= 0; i--) {
if (_loop(i)) continue;
}
return result;
}
function getTicksStart(sign, boundaries, getTickSize, ticks, minTickGap, preserveEnd) {
// This method is mutating the array so clone is indeed necessary here
var result = (ticks || []).slice();
var len = result.length;
var start = boundaries.start,
end = boundaries.end;
if (preserveEnd) {
// Try to guarantee the tail to be displayed
var tail = ticks[len - 1];
if (tail != null) {
var tailSize = getTickSize(tail, len - 1);
var tailGap = sign * (tail.coordinate + sign * tailSize / 2 - end);
result[len - 1] = tail = _objectSpread(_objectSpread({}, tail), {}, {
tickCoord: tailGap > 0 ? tail.coordinate - tailGap * sign : tail.coordinate
});
if (tail.tickCoord != null) {
var isTailShow = isVisible(sign, tail.tickCoord, () => tailSize, start, end);
if (isTailShow) {
end = tail.tickCoord - sign * (tailSize / 2 + minTickGap);
result[len - 1] = _objectSpread(_objectSpread({}, tail), {}, {
isShow: true
});
}
}
}
}
var count = preserveEnd ? len - 1 : len;
var _loop2 = function _loop2(i) {
var initialEntry = result[i];
if (initialEntry == null) {
return 1; // continue
}
var entry = initialEntry;
var size;
var getSize = () => {
if (size === undefined) {
size = getTickSize(initialEntry, i);
}
return size;
};
if (i === 0) {
var gap = sign * (entry.coordinate - sign * getSize() / 2 - start);
result[i] = entry = _objectSpread(_objectSpread({}, entry), {}, {
tickCoord: gap < 0 ? entry.coordinate - gap * sign : entry.coordinate
});
} else {
result[i] = entry = _objectSpread(_objectSpread({}, entry), {}, {
tickCoord: entry.coordinate
});
}
if (entry.tickCoord != null) {
var isShow = isVisible(sign, entry.tickCoord, getSize, start, end);
if (isShow) {
start = entry.tickCoord + sign * (getSize() / 2 + minTickGap);
result[i] = _objectSpread(_objectSpread({}, entry), {}, {
isShow: true
});
}
}
};
for (var i = 0; i < count; i++) {
if (_loop2(i)) continue;
}
return result;
}
export function getTicks(props, fontSize, letterSpacing) {
var tick = props.tick,
ticks = props.ticks,
viewBox = props.viewBox,
minTickGap = props.minTickGap,
orientation = props.orientation,
interval = props.interval,
tickFormatter = props.tickFormatter,
unit = props.unit,
angle = props.angle;
if (!ticks || !ticks.length || !tick) {
return [];
}
if (isNumber(interval) || Global.isSsr) {
var _getNumberIntervalTic;
return (_getNumberIntervalTic = getNumberIntervalTicks(ticks, isNumber(interval) ? interval : 0)) !== null && _getNumberIntervalTic !== void 0 ? _getNumberIntervalTic : [];
}
var candidates = [];
var sizeKey = orientation === 'top' || orientation === 'bottom' ? 'width' : 'height';
var unitSize = unit && sizeKey === 'width' ? getStringSize(unit, {
fontSize,
letterSpacing
}) : {
width: 0,
height: 0
};
var getTickSize = (content, index) => {
var value = typeof tickFormatter === 'function' ? tickFormatter(content.value, index) : content.value;
// Recharts only supports angles when sizeKey === 'width'
return sizeKey === 'width' ? getAngledTickWidth(getStringSize(value, {
fontSize,
letterSpacing
}), unitSize, angle) : getStringSize(value, {
fontSize,
letterSpacing
})[sizeKey];
};
var tick0 = ticks[0];
var tick1 = ticks[1];
var sign = ticks.length >= 2 && tick0 != null && tick1 != null ? mathSign(tick1.coordinate - tick0.coordinate) : 1;
var boundaries = getTickBoundaries(viewBox, sign, sizeKey);
if (interval === 'equidistantPreserveStart') {
return getEquidistantTicks(sign, boundaries, getTickSize, ticks, minTickGap);
}
if (interval === 'equidistantPreserveEnd') {
return getEquidistantPreserveEndTicks(sign, boundaries, getTickSize, ticks, minTickGap);
}
if (interval === 'preserveStart' || interval === 'preserveStartEnd') {
candidates = getTicksStart(sign, boundaries, getTickSize, ticks, minTickGap, interval === 'preserveStartEnd');
} else {
candidates = getTicksEnd(sign, boundaries, getTickSize, ticks, minTickGap);
}
return candidates.filter(entry => entry.isShow);
}

View file

@ -0,0 +1,48 @@
import { useCallback, useRef } from 'react';
import { round } from '../util/round';
/**
* Tracks the animated visible length of a Line's SVG path across data changes.
*
* Invariants:
* 1. The visible length only grows (monotonically non-decreasing with animationElapsedTime).
* 2. The visible length changes continuously no jumps when data changes mid-animation.
* This is achieved by tracking the maximum animated length in pixels and using it
* as the starting point for the next animation.
* 3. Once the line reaches 100% visibility, it never becomes partially visible again.
* In that case the hook returns `null`, meaning no animation stroke-dasharray is needed.
*
* @param points The current set of points for the line. When this reference changes,
* the hook detects a data change and starts a new animation from the current visible length.
* @returns A stable callback `(animationElapsedTime, totalLength) => number | null` where:
* - `animationElapsedTime` is the animation progress (0 to 1)
* - `totalLength` is the current total length of the SVG path in pixels
* - returns the visible length in pixels, or `null` if the line is fully visible
*/
export function useAnimatedLineLength(points) {
var startingLengthRef = useRef(0);
var maxAnimatedLengthRef = useRef(0);
var reachedFullRef = useRef(false);
var prevPointsRef = useRef(points);
if (prevPointsRef.current !== points) {
startingLengthRef.current = maxAnimatedLengthRef.current;
prevPointsRef.current = points;
}
// The callback is stable (never changes identity) because it only reads from refs.
// This avoids triggering unnecessary re-renders in consumers.
return useCallback((animationElapsedTime, totalLength) => {
if (reachedFullRef.current) {
return null;
}
var visibleLength = Math.min(round(startingLengthRef.current + animationElapsedTime * totalLength), totalLength);
if (animationElapsedTime > 0 && totalLength > 0) {
maxAnimatedLengthRef.current = Math.max(maxAnimatedLengthRef.current, visibleLength);
if (visibleLength >= totalLength) {
reachedFullRef.current = true;
return null;
}
}
return visibleLength;
}, []);
}