solid-recharts 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NEXT_SESSION_PROMPT.md +114 -0
- package/package.json +28 -0
- package/src/animation/AnimatedItems.tsx +169 -0
- package/src/animation/AnimationController.ts +24 -0
- package/src/animation/AnimationControllerImpl.ts +37 -0
- package/src/animation/AnimationHandle.ts +273 -0
- package/src/animation/CSSTransitionAnimate.tsx +142 -0
- package/src/animation/JavascriptAnimate.tsx +107 -0
- package/src/animation/easing.ts +261 -0
- package/src/animation/matchBy.ts +211 -0
- package/src/animation/timeoutController.ts +51 -0
- package/src/animation/useAnimationController.tsx +31 -0
- package/src/animation/useAnimationStartSnapshot.ts +73 -0
- package/src/animation/util.ts +16 -0
- package/src/cartesian/Area.tsx +810 -0
- package/src/cartesian/AreaRevealShape.tsx +250 -0
- package/src/cartesian/Bar.tsx +1216 -0
- package/src/cartesian/BarStack.tsx +148 -0
- package/src/cartesian/Brush.tsx +653 -0
- package/src/cartesian/CartesianAxis.tsx +541 -0
- package/src/cartesian/CartesianGrid.tsx +605 -0
- package/src/cartesian/ErrorBar.tsx +319 -0
- package/src/cartesian/Funnel.tsx +594 -0
- package/src/cartesian/GraphicalItemClipPath.tsx +75 -0
- package/src/cartesian/Line.tsx +742 -0
- package/src/cartesian/LineDrawShape.tsx +190 -0
- package/src/cartesian/ReferenceArea.tsx +275 -0
- package/src/cartesian/ReferenceDot.tsx +286 -0
- package/src/cartesian/ReferenceLine.tsx +414 -0
- package/src/cartesian/RenderedTicksReporter.tsx +49 -0
- package/src/cartesian/Scatter.tsx +741 -0
- package/src/cartesian/XAxis.tsx +293 -0
- package/src/cartesian/YAxis.tsx +333 -0
- package/src/cartesian/ZAxis.tsx +80 -0
- package/src/cartesian/getCartesianPosition.ts +255 -0
- package/src/cartesian/getEquidistantTicks.ts +126 -0
- package/src/cartesian/getTicks.ts +225 -0
- package/src/cartesian/useAnimatedLineLength.ts +84 -0
- package/src/chart/AreaChart.tsx +30 -0
- package/src/chart/BarChart.tsx +27 -0
- package/src/chart/CartesianChart.tsx +91 -0
- package/src/chart/CategoricalChart.tsx +60 -0
- package/src/chart/ComposedChart.tsx +29 -0
- package/src/chart/FunnelChart.tsx +29 -0
- package/src/chart/LineChart.tsx +29 -0
- package/src/chart/PieChart.tsx +41 -0
- package/src/chart/PolarChart.tsx +97 -0
- package/src/chart/RadarChart.tsx +37 -0
- package/src/chart/RadialBarChart.tsx +39 -0
- package/src/chart/RechartsWrapper.tsx +486 -0
- package/src/chart/Sankey.tsx +992 -0
- package/src/chart/ScatterChart.tsx +29 -0
- package/src/chart/SunburstChart.tsx +394 -0
- package/src/chart/Treemap.tsx +874 -0
- package/src/chart/types.ts +37 -0
- package/src/component/ActivePoints.tsx +136 -0
- package/src/component/Cell.tsx +72 -0
- package/src/component/Cursor.tsx +249 -0
- package/src/component/Customized.tsx +8 -0
- package/src/component/DefaultLegendContent.tsx +205 -0
- package/src/component/DefaultTooltipContent.tsx +247 -0
- package/src/component/Dots.tsx +128 -0
- package/src/component/Label.tsx +507 -0
- package/src/component/LabelList.tsx +270 -0
- package/src/component/Legend.tsx +273 -0
- package/src/component/ResponsiveContainer.tsx +397 -0
- package/src/component/Text.tsx +436 -0
- package/src/component/Tooltip.tsx +309 -0
- package/src/component/TooltipBoundingBox.tsx +152 -0
- package/src/component/responsiveContainerUtils.ts +128 -0
- package/src/container/ClipPathProvider.tsx +40 -0
- package/src/container/Layer.tsx +38 -0
- package/src/container/RootSurface.tsx +124 -0
- package/src/container/Surface.tsx +70 -0
- package/src/context/ErrorBarContext.tsx +85 -0
- package/src/context/PanoramaContext.tsx +13 -0
- package/src/context/RegisterGraphicalItemId.tsx +41 -0
- package/src/context/accessibilityContext.tsx +10 -0
- package/src/context/brushUpdateContext.ts +14 -0
- package/src/context/chartDataContext.tsx +79 -0
- package/src/context/chartLayoutContext.tsx +158 -0
- package/src/context/legendPayloadContext.ts +11 -0
- package/src/context/legendPortalContext.ts +11 -0
- package/src/context/tooltipContext.ts +72 -0
- package/src/context/tooltipPortalContext.ts +14 -0
- package/src/context/useTooltipAxis.ts +24 -0
- package/src/hooks.ts +312 -0
- package/src/index.ts +288 -0
- package/src/polar/Pie.tsx +912 -0
- package/src/polar/PolarAngleAxis.tsx +494 -0
- package/src/polar/PolarGrid.tsx +269 -0
- package/src/polar/PolarRadiusAxis.tsx +422 -0
- package/src/polar/Radar.tsx +652 -0
- package/src/polar/RadialBar.tsx +767 -0
- package/src/polar/defaultPolarAngleAxisProps.tsx +33 -0
- package/src/polar/defaultPolarRadiusAxisProps.tsx +28 -0
- package/src/shape/Cross.tsx +83 -0
- package/src/shape/Curve.tsx +335 -0
- package/src/shape/Dot.tsx +49 -0
- package/src/shape/Polygon.tsx +168 -0
- package/src/shape/Rectangle.tsx +301 -0
- package/src/shape/Sector.tsx +304 -0
- package/src/shape/Symbols.tsx +144 -0
- package/src/shape/Trapezoid.tsx +228 -0
- package/src/state/RechartsReduxContext.tsx +8 -0
- package/src/state/RechartsStoreContext.ts +15 -0
- package/src/state/RechartsStoreProvider.tsx +27 -0
- package/src/state/ReportChartProps.tsx +19 -0
- package/src/state/ReportEventSettings.tsx +19 -0
- package/src/state/ReportMainChartProps.tsx +35 -0
- package/src/state/ReportPolarOptions.tsx +28 -0
- package/src/state/SetLegendPayload.ts +50 -0
- package/src/state/SetTooltipEntrySettings.tsx +46 -0
- package/src/state/brushSlice.ts +60 -0
- package/src/state/cartesianAxisSlice.ts +288 -0
- package/src/state/chartDataSlice.ts +115 -0
- package/src/state/errorBarSlice.ts +84 -0
- package/src/state/eventSettingsSlice.ts +41 -0
- package/src/state/externalEventsMiddleware.ts +136 -0
- package/src/state/graphicalItemsSlice.ts +162 -0
- package/src/state/hooks.ts +42 -0
- package/src/state/keyboardEventsMiddleware.ts +213 -0
- package/src/state/layoutSlice.ts +71 -0
- package/src/state/legendSlice.ts +107 -0
- package/src/state/mouseEventsMiddleware.ts +103 -0
- package/src/state/optionsSlice.ts +64 -0
- package/src/state/polarAxisSlice.ts +65 -0
- package/src/state/polarOptionsSlice.ts +54 -0
- package/src/state/reduxDevtoolsJsonStringifyReplacer.ts +15 -0
- package/src/state/referenceElementsSlice.ts +121 -0
- package/src/state/renderedTicksSlice.ts +61 -0
- package/src/state/rootPropsSlice.ts +70 -0
- package/src/state/selectors/areaSelectors.ts +169 -0
- package/src/state/selectors/arrayEqualityCheck.ts +8 -0
- package/src/state/selectors/axisSelectors.ts +2196 -0
- package/src/state/selectors/barSelectors.ts +319 -0
- package/src/state/selectors/barStackSelectors.ts +79 -0
- package/src/state/selectors/brushSelectors.ts +40 -0
- package/src/state/selectors/combiners/combineActiveLabel.ts +21 -0
- package/src/state/selectors/combiners/combineActiveTooltipIndex.ts +93 -0
- package/src/state/selectors/combiners/combineAllBarPositions.ts +131 -0
- package/src/state/selectors/combiners/combineAxisRangeWithReverse.ts +17 -0
- package/src/state/selectors/combiners/combineBarPosition.ts +24 -0
- package/src/state/selectors/combiners/combineBarSizeList.ts +75 -0
- package/src/state/selectors/combiners/combineCheckedDomain.ts +49 -0
- package/src/state/selectors/combiners/combineConfiguredScale.ts +121 -0
- package/src/state/selectors/combiners/combineCoordinateForDefaultIndex.ts +43 -0
- package/src/state/selectors/combiners/combineDisplayedStackedData.ts +50 -0
- package/src/state/selectors/combiners/combineInverseScaleFunction.ts +17 -0
- package/src/state/selectors/combiners/combineRealScaleType.ts +48 -0
- package/src/state/selectors/combiners/combineStackedData.ts +28 -0
- package/src/state/selectors/combiners/combineTooltipInteractionState.ts +86 -0
- package/src/state/selectors/combiners/combineTooltipPayload.ts +203 -0
- package/src/state/selectors/combiners/combineTooltipPayloadConfigurations.ts +45 -0
- package/src/state/selectors/containerSelectors.ts +12 -0
- package/src/state/selectors/dataSelectors.ts +90 -0
- package/src/state/selectors/funnelSelectors.ts +83 -0
- package/src/state/selectors/graphicalItemSelectors.ts +23 -0
- package/src/state/selectors/legendSelectors.ts +29 -0
- package/src/state/selectors/lineSelectors.ts +111 -0
- package/src/state/selectors/numberDomainEqualityCheck.ts +8 -0
- package/src/state/selectors/pickAxisId.ts +6 -0
- package/src/state/selectors/pickAxisType.ts +4 -0
- package/src/state/selectors/pieSelectors.ts +103 -0
- package/src/state/selectors/polarAxisSelectors.ts +202 -0
- package/src/state/selectors/polarGridSelectors.ts +24 -0
- package/src/state/selectors/polarScaleSelectors.ts +149 -0
- package/src/state/selectors/polarSelectors.ts +211 -0
- package/src/state/selectors/radarSelectors.ts +152 -0
- package/src/state/selectors/radialBarSelectors.ts +328 -0
- package/src/state/selectors/rootPropsSelectors.ts +36 -0
- package/src/state/selectors/scatterSelectors.ts +77 -0
- package/src/state/selectors/selectAllAxes.ts +10 -0
- package/src/state/selectors/selectChartOffset.ts +15 -0
- package/src/state/selectors/selectChartOffsetInternal.ts +111 -0
- package/src/state/selectors/selectPlotArea.ts +27 -0
- package/src/state/selectors/selectTooltipAxisId.ts +6 -0
- package/src/state/selectors/selectTooltipAxisType.ts +33 -0
- package/src/state/selectors/selectTooltipEventType.ts +45 -0
- package/src/state/selectors/selectTooltipPayloadSearcher.ts +7 -0
- package/src/state/selectors/selectTooltipSettings.ts +6 -0
- package/src/state/selectors/selectTooltipState.ts +5 -0
- package/src/state/selectors/tooltipSelectors.ts +690 -0
- package/src/state/selectors/touchSelectors.ts +29 -0
- package/src/state/store.ts +167 -0
- package/src/state/tooltipSlice.ts +289 -0
- package/src/state/types/AreaSettings.ts +17 -0
- package/src/state/types/BarSettings.ts +16 -0
- package/src/state/types/LineSettings.ts +12 -0
- package/src/state/types/PieSettings.ts +32 -0
- package/src/state/types/RadarSettings.ts +6 -0
- package/src/state/types/RadialBarSettings.ts +10 -0
- package/src/state/types/ScatterSettings.ts +13 -0
- package/src/state/types/StackedGraphicalItem.ts +33 -0
- package/src/state/unregisterOnCleanup.ts +26 -0
- package/src/state/zIndexSlice.ts +128 -0
- package/src/synchronisation/syncRegistry.ts +131 -0
- package/src/synchronisation/syncSelectors.ts +7 -0
- package/src/synchronisation/types.ts +42 -0
- package/src/synchronisation/useChartSynchronisation.tsx +372 -0
- package/src/types.ts +39 -0
- package/src/util/ActiveShapeUtils.tsx +80 -0
- package/src/util/BarUtils.tsx +74 -0
- package/src/util/CartesianUtils.ts +53 -0
- package/src/util/ChartUtils.ts +696 -0
- package/src/util/Constants.ts +42 -0
- package/src/util/CssPrefixUtils.ts +24 -0
- package/src/util/DOMUtils.ts +141 -0
- package/src/util/DataUtils.ts +205 -0
- package/src/util/FunnelUtils.tsx +37 -0
- package/src/util/Global.ts +15 -0
- package/src/util/IfOverflow.ts +17 -0
- package/src/util/LRUCache.ts +46 -0
- package/src/util/LogUtils.ts +26 -0
- package/src/util/PolarUtils.ts +134 -0
- package/src/util/RadialBarUtils.tsx +35 -0
- package/src/util/ReduceCSSCalc.ts +186 -0
- package/src/util/ShallowEqual.ts +43 -0
- package/src/util/TickUtils.ts +61 -0
- package/src/util/YAxisUtils.ts +49 -0
- package/src/util/adaptEventHandlers.ts +69 -0
- package/src/util/axisPropsAreEqual.ts +42 -0
- package/src/util/collectionUtils.ts +83 -0
- package/src/util/createCartesianCharts.tsx +101 -0
- package/src/util/createEventProxy.ts +24 -0
- package/src/util/createPolarCharts.tsx +86 -0
- package/src/util/cursor/getCursorPoints.ts +48 -0
- package/src/util/cursor/getCursorRectangle.ts +31 -0
- package/src/util/cursor/getRadialCursorPoints.ts +34 -0
- package/src/util/excludeEventProps.ts +172 -0
- package/src/util/getActiveCoordinate.ts +205 -0
- package/src/util/getAxisTypeBasedOnLayout.ts +21 -0
- package/src/util/getEveryNth.ts +30 -0
- package/src/util/getRadiusAndStrokeWidthFromDot.ts +35 -0
- package/src/util/getRelativeCoordinate.ts +84 -0
- package/src/util/getSliced.ts +21 -0
- package/src/util/isDomainSpecifiedByUser.ts +217 -0
- package/src/util/isWellBehavedNumber.ts +10 -0
- package/src/util/objectPath.ts +129 -0
- package/src/util/payload/getUniqPayload.ts +31 -0
- package/src/util/propsAreEqual.ts +137 -0
- package/src/util/resolveDefaultProps.tsx +8 -0
- package/src/util/round.ts +35 -0
- package/src/util/scale/CartesianScaleHelper.ts +72 -0
- package/src/util/scale/CustomScaleDefinition.ts +82 -0
- package/src/util/scale/RechartsScale.ts +131 -0
- package/src/util/scale/createCategoricalInverse.ts +83 -0
- package/src/util/scale/getNiceTickValues.ts +334 -0
- package/src/util/scale/index.ts +3 -0
- package/src/util/scale/util/DecimalLite.ts +194 -0
- package/src/util/scale/util/arithmetic.ts +56 -0
- package/src/util/stacks/getStackSeriesIdentifier.ts +20 -0
- package/src/util/stacks/stackTypes.ts +53 -0
- package/src/util/svgPropertiesAndEvents.ts +84 -0
- package/src/util/svgPropertiesNoEvents.ts +520 -0
- package/src/util/tooltip/translate.ts +179 -0
- package/src/util/typedDataKey.ts +8 -0
- package/src/util/types.ts +724 -0
- package/src/util/useAnimationId.tsx +31 -0
- package/src/util/useElementOffset.ts +164 -0
- package/src/util/useId.ts +20 -0
- package/src/util/usePrefersReducedMotion.ts +44 -0
- package/src/util/useUniqueId.ts +34 -0
- package/src/zIndex/DefaultZIndexes.tsx +87 -0
- package/src/zIndex/ZIndexLayer.tsx +126 -0
- package/src/zIndex/ZIndexPortal.tsx +69 -0
- package/src/zIndex/getZIndexFromUnknown.tsx +17 -0
- package/src/zIndex/zIndexSelectors.ts +46 -0
- package/test/_data.ts +408 -0
- package/test/animation/AnimationController.typed.spec.ts +53 -0
- package/test/animation/AnimationControllerImpl.spec.ts +271 -0
- package/test/animation/CSSTransitionAnimate.timing.spec.tsx +473 -0
- package/test/animation/JavascriptAnimate.spec.tsx +62 -0
- package/test/animation/RechartsAnimation.spec.ts +636 -0
- package/test/animation/easing.spec.ts +218 -0
- package/test/animation/legacyAnimationLengthChange.spec.tsx +803 -0
- package/test/animation/matchBy.spec.ts +467 -0
- package/test/animation/mockAnimationController.ts +40 -0
- package/test/animation/mockControllerAnimationManager.ts +143 -0
- package/test/animation/mockTimeoutController.ts +114 -0
- package/test/animation/timeoutController.spec.ts +138 -0
- package/test/animation/useAnimationStartSnapshot.spec.ts +147 -0
- package/test/animation/util.spec.ts +28 -0
- package/test/cartesian/Area.animation.spec.tsx +363 -0
- package/test/cartesian/Area.range.spec.tsx +54 -0
- package/test/cartesian/Area.spec.tsx +1202 -0
- package/test/cartesian/Area.stacked.render.spec.tsx +69 -0
- package/test/cartesian/Area.typed.spec.tsx +209 -0
- package/test/cartesian/Axis.integration.spec.tsx +158 -0
- package/test/cartesian/Bar/Bar.csstransition.spec.tsx +299 -0
- package/test/cartesian/Bar/Bar.spec.tsx +2314 -0
- package/test/cartesian/Bar/Bar.typed.spec.tsx +192 -0
- package/test/cartesian/Bar.animation.spec.tsx +426 -0
- package/test/cartesian/Bar.stackDomain.spec.tsx +66 -0
- package/test/cartesian/Bar.stacked.render.spec.tsx +53 -0
- package/test/cartesian/Bar.truncateByDomain.spec.tsx +237 -0
- package/test/cartesian/Bar.zeroDimensionFiltering.spec.tsx +336 -0
- package/test/cartesian/BarStack.spec.tsx +91 -0
- package/test/cartesian/Brush.keyboard.spec.tsx +88 -0
- package/test/cartesian/Brush.panorama.spec.tsx +41 -0
- package/test/cartesian/Brush.props.spec.tsx +63 -0
- package/test/cartesian/Brush.render.spec.tsx +117 -0
- package/test/cartesian/Brush.spec.tsx +522 -0
- package/test/cartesian/Brush.stacked.spec.tsx +221 -0
- package/test/cartesian/CartesianAxis.render.spec.tsx +50 -0
- package/test/cartesian/CartesianAxis.spec.tsx +396 -0
- package/test/cartesian/CartesianGrid.render.spec.tsx +39 -0
- package/test/cartesian/CartesianGrid.spec.tsx +2103 -0
- package/test/cartesian/ErrorBar.render.spec.tsx +69 -0
- package/test/cartesian/ErrorBar.spec.tsx +2414 -0
- package/test/cartesian/Funnel.animation.spec.tsx +241 -0
- package/test/cartesian/Funnel.spec.tsx +226 -0
- package/test/cartesian/Funnel.typed.spec.tsx +221 -0
- package/test/cartesian/GraphicalItemClipPath.scale-behavior.spec.tsx +627 -0
- package/test/cartesian/GraphicalItemClipPath.spec.tsx +427 -0
- package/test/cartesian/Line.animation.spec.tsx +643 -0
- package/test/cartesian/Line.sparseAnimationPath.spec.tsx +98 -0
- package/test/cartesian/Line.spec.tsx +471 -0
- package/test/cartesian/Line.typed.spec.tsx +152 -0
- package/test/cartesian/ReferenceArea.render.spec.tsx +63 -0
- package/test/cartesian/ReferenceArea.spec.tsx +663 -0
- package/test/cartesian/ReferenceArea.typed.spec.tsx +74 -0
- package/test/cartesian/ReferenceDot.render.spec.tsx +55 -0
- package/test/cartesian/ReferenceDot.spec.tsx +462 -0
- package/test/cartesian/ReferenceDot.typed.spec.tsx +76 -0
- package/test/cartesian/ReferenceLine/ReferenceLine.panorama.spec.tsx +184 -0
- package/test/cartesian/ReferenceLine/ReferenceLine.spec.tsx +744 -0
- package/test/cartesian/ReferenceLine/ReferenceLine.typed.spec.tsx +74 -0
- package/test/cartesian/ReferenceLine/getEndPoints.spec.ts +399 -0
- package/test/cartesian/ReferenceLine.render.spec.tsx +134 -0
- package/test/cartesian/Scatter.animation.spec.tsx +381 -0
- package/test/cartesian/Scatter.render.spec.tsx +61 -0
- package/test/cartesian/Scatter.spec.tsx +406 -0
- package/test/cartesian/Scatter.typed.spec.tsx +153 -0
- package/test/cartesian/XAxis/XAxis.barSize.spec.tsx +336 -0
- package/test/cartesian/XAxis/XAxis.brush.spec.tsx +266 -0
- package/test/cartesian/XAxis/XAxis.categorydomain.spec.tsx +872 -0
- package/test/cartesian/XAxis/XAxis.dataKey.spec.tsx +86 -0
- package/test/cartesian/XAxis/XAxis.datatypes.spec.tsx +127 -0
- package/test/cartesian/XAxis/XAxis.hide.spec.tsx +106 -0
- package/test/cartesian/XAxis/XAxis.multiaxis.spec.tsx +336 -0
- package/test/cartesian/XAxis/XAxis.numberdomain.spec.tsx +1466 -0
- package/test/cartesian/XAxis/XAxis.padding.spec.tsx +758 -0
- package/test/cartesian/XAxis/XAxis.padding_clip.spec.tsx +65 -0
- package/test/cartesian/XAxis/XAxis.state.spec.tsx +355 -0
- package/test/cartesian/XAxis/XAxis.tick.spec.tsx +493 -0
- package/test/cartesian/XAxis/XAxis.timescale.spec.tsx +233 -0
- package/test/cartesian/XAxis/XAxis.type.spec.tsx +107 -0
- package/test/cartesian/XAxis/XAxis.typed.spec.tsx +102 -0
- package/test/cartesian/XAxis/XAxis.vertical.spec.tsx +265 -0
- package/test/cartesian/XAxis.tickFormatter.spec.tsx +54 -0
- package/test/cartesian/YAxis/YAxis.7362.derivedDomain.spec.tsx +230 -0
- package/test/cartesian/YAxis/YAxis.7362.spec.tsx +104 -0
- package/test/cartesian/YAxis/YAxis.interval-zero.spec.tsx +88 -0
- package/test/cartesian/YAxis/YAxis.label.spec.tsx +219 -0
- package/test/cartesian/YAxis/YAxis.spec.tsx +1595 -0
- package/test/cartesian/YAxis/YAxis.tick.spec.tsx +428 -0
- package/test/cartesian/YAxis/YAxis.tickFormatter.spec.tsx +54 -0
- package/test/cartesian/YAxis/YAxis.ticks.spec.tsx +263 -0
- package/test/cartesian/YAxis/YAxis.type.spec.tsx +107 -0
- package/test/cartesian/YAxis/YAxis.typed.spec.tsx +102 -0
- package/test/cartesian/ZAxis.spec.tsx +300 -0
- package/test/cartesian/ZAxis.typed.spec.tsx +33 -0
- package/test/cartesian/__snapshots__/Brush.spec.tsx.snap +5 -0
- package/test/cartesian/axisLineAndStroke.spec.tsx +72 -0
- package/test/cartesian/getCartesianPosition.spec.ts +907 -0
- package/test/cartesian/getEquidistantTicks.spec.ts +88 -0
- package/test/cartesian/getTicks.spec.ts +378 -0
- package/test/cartesian/miscFeatureGaps.spec.tsx +89 -0
- package/test/cartesian/useAnimatedLineLength.spec.ts +168 -0
- package/test/chart/AccessibilityLayer.spec.tsx +569 -0
- package/test/chart/AccessibilityScans.spec.tsx +286 -0
- package/test/chart/AreaChart.spec.tsx +409 -0
- package/test/chart/AreaChart.stacked.spec.tsx +1407 -0
- package/test/chart/AreaChart.typed.spec.tsx +39 -0
- package/test/chart/BarChart.spec.tsx +3719 -0
- package/test/chart/BarChart.typed.spec.tsx +60 -0
- package/test/chart/CategoricalChart.spec.tsx +255 -0
- package/test/chart/ComposedChart.spec.tsx +199 -0
- package/test/chart/ComposedChart.typed.spec.tsx +39 -0
- package/test/chart/FunnelChart.spec.tsx +215 -0
- package/test/chart/FunnelChart.typed.spec.tsx +39 -0
- package/test/chart/LineChart.multiseries.spec.tsx +50 -0
- package/test/chart/LineChart.smoke.spec.tsx +50 -0
- package/test/chart/LineChart.spec.tsx +930 -0
- package/test/chart/LineChart.typed.spec.tsx +39 -0
- package/test/chart/NicheChartTooltip.spec.tsx +81 -0
- package/test/chart/PieChart.spec.tsx +793 -0
- package/test/chart/PieChart.typed.spec.tsx +39 -0
- package/test/chart/RadarChart.spec.tsx +530 -0
- package/test/chart/RadarChart.typed.spec.tsx +39 -0
- package/test/chart/RadialBarChart.5966.spec.tsx +48 -0
- package/test/chart/RadialBarChart.spec.tsx +679 -0
- package/test/chart/RadialBarChart.typed.spec.tsx +39 -0
- package/test/chart/RechartsWrapper.spec.tsx +83 -0
- package/test/chart/Sankey.content.spec.tsx +46 -0
- package/test/chart/Sankey.spec.tsx +952 -0
- package/test/chart/Sankey.typed.spec.tsx +29 -0
- package/test/chart/ScatterChart.spec.tsx +2613 -0
- package/test/chart/ScatterChart.typed.spec.tsx +39 -0
- package/test/chart/SunburstChart.spec.tsx +146 -0
- package/test/chart/Treemap.animation.spec.tsx +52 -0
- package/test/chart/Treemap.spec.tsx +1003 -0
- package/test/chart/Treemap.typed.spec.tsx +26 -0
- package/test/chart/chartEvents.spec.tsx +127 -0
- package/test/chart/responsive.spec.tsx +620 -0
- package/test/component/Cell.render.spec.tsx +155 -0
- package/test/component/Cell.spec.tsx +12 -0
- package/test/component/Cursor.spec.tsx +186 -0
- package/test/component/DefaultTooltipContent.spec.tsx +102 -0
- package/test/component/Label.render.spec.tsx +63 -0
- package/test/component/Label.spec.tsx +686 -0
- package/test/component/Label.typed.spec.tsx +46 -0
- package/test/component/LabelList.spec.tsx +188 -0
- package/test/component/Legend.itemSorter.spec.tsx +704 -0
- package/test/component/Legend.render.spec.tsx +92 -0
- package/test/component/Legend.spec.tsx +2213 -0
- package/test/component/Legend.typed.spec.tsx +22 -0
- package/test/component/ResponsiveContainer.spec.tsx +523 -0
- package/test/component/ResponsiveContainerDataTest.spec.tsx +51 -0
- package/test/component/Text.spec.tsx +415 -0
- package/test/component/Text.typed.spec.tsx +46 -0
- package/test/component/Tooltip/ActiveDot.spec.tsx +370 -0
- package/test/component/Tooltip/Tooltip.animation.spec.tsx +209 -0
- package/test/component/Tooltip/Tooltip.content.spec.tsx +128 -0
- package/test/component/Tooltip/Tooltip.formatter.spec.tsx +152 -0
- package/test/component/Tooltip/Tooltip.includeHidden.spec.tsx +79 -0
- package/test/component/Tooltip/Tooltip.multipleDataArrays.spec.tsx +165 -0
- package/test/component/Tooltip/Tooltip.offset.spec.tsx +113 -0
- package/test/component/Tooltip/Tooltip.state.spec.tsx +74 -0
- package/test/component/Tooltip/Tooltip.sync.spec.tsx +639 -0
- package/test/component/Tooltip/defaultIndex.spec.tsx +227 -0
- package/test/component/Tooltip/graphicalItem.formatter.spec.tsx +138 -0
- package/test/component/Tooltip/itemSorter.spec.tsx +2815 -0
- package/test/component/Tooltip/tooltipEventType.spec.tsx +344 -0
- package/test/component/Tooltip/tooltipMouseHoverSelectors.ts +41 -0
- package/test/component/Tooltip/tooltipTestHelpers.tsx +162 -0
- package/test/component/Tooltip.defaultIndex.spec.tsx +48 -0
- package/test/component/Tooltip.hover.spec.tsx +61 -0
- package/test/component/Tooltip.item.spec.tsx +54 -0
- package/test/component/Tooltip.keyboard.spec.tsx +51 -0
- package/test/component/Tooltip.payload.spec.tsx +1716 -0
- package/test/component/Tooltip.touch.spec.tsx +39 -0
- package/test/component/Tooltip.visibility.spec.tsx +1889 -0
- package/test/component/TooltipBoundingBox.spec.tsx +89 -0
- package/test/component/responsiveContainerUtils.spec.ts +205 -0
- package/test/container/ClipPath.spec.tsx +602 -0
- package/test/container/chartDimensions.spec.tsx +368 -0
- package/test/context/chartLayoutContext.spec.tsx +378 -0
- package/test/helper/ExpectAxisDomain.tsx +27 -0
- package/test/helper/assertNotNull.ts +6 -0
- package/test/helper/assertZIndexLayerOrder.ts +19 -0
- package/test/helper/createSelectorTestCase.tsx +176 -0
- package/test/helper/expectAnimatedPieAngles.ts +100 -0
- package/test/helper/expectAnimatedPiePaths.ts +78 -0
- package/test/helper/expectAreaCurve.ts +15 -0
- package/test/helper/expectAxisTicks.ts +48 -0
- package/test/helper/expectBars.ts +54 -0
- package/test/helper/expectFunctionReturning.ts +58 -0
- package/test/helper/expectLabel.ts +32 -0
- package/test/helper/expectLastCalledWith.ts +48 -0
- package/test/helper/expectLine.ts +20 -0
- package/test/helper/expectPieSectors.ts +80 -0
- package/test/helper/expectScale.ts +37 -0
- package/test/helper/expectScatterPoints.ts +52 -0
- package/test/helper/expectStackGroups.ts +144 -0
- package/test/helper/mockAxes.ts +22 -0
- package/test/helper/mockGetBoundingClientRect.ts +66 -0
- package/test/helper/mockHTMLElementProperty.ts +19 -0
- package/test/helper/mockTouchingElement.ts +27 -0
- package/test/helper/offsetHelpers.ts +19 -0
- package/test/helper/parameterizedTestCases.tsx +99 -0
- package/test/helper/produceState.ts +32 -0
- package/test/helper/render.ts +7 -0
- package/test/helper/selectorTestHelpers.tsx +63 -0
- package/test/helper/trim.spec.ts +35 -0
- package/test/helper/trim.ts +11 -0
- package/test/hooks/useActiveTooltipDataPoints.spec.tsx +358 -0
- package/test/hooks/useAxisDomain.spec.tsx +361 -0
- package/test/hooks/useAxisScale.spec.tsx +283 -0
- package/test/hooks/useAxisTicks.spec.tsx +130 -0
- package/test/hooks/useOffset.spec.tsx +248 -0
- package/test/hooks/useTooltipStateHooks.spec.tsx +109 -0
- package/test/polar/Pie/Pie-TwoLevelPieChart.spec.tsx +135 -0
- package/test/polar/Pie/Pie.spec.tsx +784 -0
- package/test/polar/Pie/Pie.typed.spec.tsx +78 -0
- package/test/polar/Pie.animation.spec.tsx +529 -0
- package/test/polar/PieWithLegend.animation.spec.tsx +142 -0
- package/test/polar/PolarAngleAxis/PolarAngleAxis.events.spec.tsx +76 -0
- package/test/polar/PolarAngleAxis/PolarAngleAxis.spec.tsx +2079 -0
- package/test/polar/PolarAngleAxis/PolarAngleAxis.typed.spec.tsx +102 -0
- package/test/polar/PolarAngleAxis.render.spec.tsx +79 -0
- package/test/polar/PolarGrid.render.spec.tsx +75 -0
- package/test/polar/PolarGrid.spec.tsx +918 -0
- package/test/polar/PolarLegendPerRow.render.spec.tsx +85 -0
- package/test/polar/PolarRadiusAxis.events.spec.tsx +65 -0
- package/test/polar/PolarRadiusAxis.render.spec.tsx +52 -0
- package/test/polar/PolarRadiusAxis.spec.tsx +991 -0
- package/test/polar/PolarRadiusAxis.typed.spec.tsx +84 -0
- package/test/polar/PolarTooltipLegend.render.spec.tsx +80 -0
- package/test/polar/Radar.animation.spec.tsx +570 -0
- package/test/polar/Radar.render.spec.tsx +71 -0
- package/test/polar/Radar.spec.tsx +265 -0
- package/test/polar/Radar.typed.spec.tsx +119 -0
- package/test/polar/RadialBar/RadialBar.spec.tsx +1521 -0
- package/test/polar/RadialBar/RadialBar.typed.spec.tsx +132 -0
- package/test/polar/RadialBar.animation.spec.tsx +375 -0
- package/test/polar/RadialBar.render.spec.tsx +66 -0
- package/test/polar/RadialBar.stacked.spec.tsx +57 -0
- package/test/setup.ts +84 -0
- package/test/shape/ActiveShape.spec.tsx +181 -0
- package/test/shape/Cross.spec.tsx +60 -0
- package/test/shape/Cross.typed.spec.tsx +26 -0
- package/test/shape/Curve.spec.tsx +368 -0
- package/test/shape/Curve.typed.spec.tsx +69 -0
- package/test/shape/Dot.spec.tsx +73 -0
- package/test/shape/Dot.typed.spec.tsx +30 -0
- package/test/shape/Polygon.spec.tsx +357 -0
- package/test/shape/Polygon.typed.spec.tsx +28 -0
- package/test/shape/Rectangle.animation.spec.tsx +451 -0
- package/test/shape/Rectangle.spec.tsx +68 -0
- package/test/shape/Rectangle.typed.spec.tsx +24 -0
- package/test/shape/Sector.spec.tsx +76 -0
- package/test/shape/Sector.typed.spec.tsx +24 -0
- package/test/shape/Symbols.spec.tsx +43 -0
- package/test/shape/Symbols.typed.spec.tsx +24 -0
- package/test/shape/Trapezoid.spec.tsx +50 -0
- package/test/shape/Trapezoid.typed.spec.tsx +24 -0
- package/test/shape/__snapshots__/Cross.spec.tsx.snap +62 -0
- package/test/shape/__snapshots__/Curve.spec.tsx.snap +460 -0
- package/test/shape/__snapshots__/Polygon.spec.tsx.snap +58 -0
- package/test/shape/__snapshots__/Rectangle.spec.tsx.snap +117 -0
- package/test/shape/__snapshots__/Sector.spec.tsx.snap +71 -0
- package/test/shape/__snapshots__/Trapezoid.spec.tsx.snap +64 -0
- package/test/state/chartDataSlice.spec.ts +53 -0
- package/test/state/externalEventsMiddleware.spec.ts +178 -0
- package/test/state/graphicalItemsSlice.spec.ts +92 -0
- package/test/state/hooks.spec.tsx +68 -0
- package/test/state/legendSlice.spec.ts +44 -0
- package/test/state/mouseEventsMiddleware.spec.ts +75 -0
- package/test/state/optionsSlice.spec.ts +19 -0
- package/test/state/reduxDevtoolsJsonStringifyReplacer.spec.ts +25 -0
- package/test/state/referenceElementsSlice.spec.ts +84 -0
- package/test/state/selectors/areaSelectors.spec.tsx +77 -0
- package/test/state/selectors/axisSelectors.spec.tsx +1418 -0
- package/test/state/selectors/barStackSelectors.spec.tsx +752 -0
- package/test/state/selectors/brushSelectors.spec.tsx +30 -0
- package/test/state/selectors/cartesianAxisSlice.spec.ts +96 -0
- package/test/state/selectors/combineNiceTicks.spec.ts +207 -0
- package/test/state/selectors/combiners/combineActiveTooltipIndex.spec.ts +61 -0
- package/test/state/selectors/combiners/combineAllBarPositions.spec.ts +39 -0
- package/test/state/selectors/combiners/combineConfiguredScale.spec.ts +56 -0
- package/test/state/selectors/combiners/combineDisplayedStackedData.spec.ts +123 -0
- package/test/state/selectors/combiners/combineRealScaleType.spec.ts +80 -0
- package/test/state/selectors/containerSelectors.spec.tsx +168 -0
- package/test/state/selectors/dataSelectors.spec.tsx +136 -0
- package/test/state/selectors/legendSelectors.spec.tsx +113 -0
- package/test/state/selectors/lineSelectors.spec.tsx +60 -0
- package/test/state/selectors/pieSelectors.spec.tsx +72 -0
- package/test/state/selectors/radarSelectors.spec.tsx +496 -0
- package/test/state/selectors/rootPropsSelectors.spec.tsx +169 -0
- package/test/state/selectors/scatterSelectors.spec.tsx +47 -0
- package/test/state/selectors/selectActiveTooltipIndex.spec.tsx +234 -0
- package/test/state/selectors/selectAllAxes.spec.tsx +18 -0
- package/test/state/selectors/selectAxisDomain.spec.tsx +21 -0
- package/test/state/selectors/selectAxisDomainIncludingNiceTicks.spec.tsx +19 -0
- package/test/state/selectors/selectAxisRangeWithReverse.spec.tsx +22 -0
- package/test/state/selectors/selectAxisScale.spec.tsx +91 -0
- package/test/state/selectors/selectBarRectangles.stackOffset.spec.tsx +503 -0
- package/test/state/selectors/selectBaseAxis.spec.tsx +56 -0
- package/test/state/selectors/selectCartesianItemsSettings.spec.tsx +57 -0
- package/test/state/selectors/selectChartOffset.spec.tsx +26 -0
- package/test/state/selectors/selectDisplayedData.spec.tsx +282 -0
- package/test/state/selectors/selectIsTooltipActive.spec.tsx +231 -0
- package/test/state/selectors/selectNumericalDomain.spec.tsx +21 -0
- package/test/state/selectors/selectRealScaleType.spec.tsx +19 -0
- package/test/state/selectors/selectStackGroups.spec.tsx +322 -0
- package/test/state/selectors/selectXAxisPosition.spec.tsx +22 -0
- package/test/state/selectors/selectYAxisPosition.spec.tsx +22 -0
- package/test/state/selectors/selectors.spec.tsx +1613 -0
- package/test/state/throttling.spec.ts +200 -0
- package/test/state/zIndexSlice.spec.ts +85 -0
- package/test/synchronisation/useChartSynchronisation.spec.tsx +225 -0
- package/test/util/BarUtils.spec.ts +39 -0
- package/test/util/CartesianUtils/CartesianUtils.spec.ts +261 -0
- package/test/util/CartesianUtils/rectWithPoints.spec.ts +48 -0
- package/test/util/ChartUtils/ChartUtils.spec.ts +491 -0
- package/test/util/ChartUtils/appendOffsetOfLegend.spec.ts +136 -0
- package/test/util/ChartUtils/appendOffsetOfLegend.spec.tsx +133 -0
- package/test/util/ChartUtils/getCateCoordinateOfLine.spec.ts +83 -0
- package/test/util/ChartUtils/getStackedData.spec.ts +416 -0
- package/test/util/ChartUtils/truncateByDomain.spec.ts +70 -0
- package/test/util/DataUtils.spec.ts +385 -0
- package/test/util/DomUtils.spec.tsx +117 -0
- package/test/util/FunnelUtils.spec.tsx +70 -0
- package/test/util/Global.spec.ts +11 -0
- package/test/util/LRUCache.spec.ts +81 -0
- package/test/util/LogUtils.spec.ts +45 -0
- package/test/util/PolarUtils.spec.ts +66 -0
- package/test/util/ReduceCssCalcPrototype.spec.ts +141 -0
- package/test/util/ShallowEqual.spec.ts +102 -0
- package/test/util/TickUtils.spec.ts +29 -0
- package/test/util/axisPropsAreEqual.spec.ts +93 -0
- package/test/util/createChartHelpers.spec.tsx +210 -0
- package/test/util/cursor/getCursorPoints.spec.ts +136 -0
- package/test/util/cursor/getCursorRectangle.spec.ts +50 -0
- package/test/util/cursor/getRadialCursorPoints.spec.ts +36 -0
- package/test/util/errorValue.spec.ts +69 -0
- package/test/util/getEveryNth.spec.ts +39 -0
- package/test/util/getRadiusAndStrokeWidthFromDot.spec.ts +51 -0
- package/test/util/getRelativeCoordinate.spec.ts +250 -0
- package/test/util/getSliced.spec.ts +45 -0
- package/test/util/isDomainSpecifiedByUser.spec.ts +207 -0
- package/test/util/isWellBehavedNumber.spec.ts +54 -0
- package/test/util/payload/getUniqPayload.spec.ts +56 -0
- package/test/util/propsAreEqual.spec.ts +75 -0
- package/test/util/round.spec.ts +112 -0
- package/test/util/scale/arithmetic.spec.ts +61 -0
- package/test/util/scale/createCategoricalInverse.spec.ts +84 -0
- package/test/util/scale/getNiceTickValues.spec.ts +421 -0
- package/test/util/scale/getTickValuesFixedDomain.spec.ts +155 -0
- package/test/util/svgPropertiesAndEvents.spec.tsx +206 -0
- package/test/util/svgPropertiesNoEvents.spec.tsx +228 -0
- package/test/util/tooltip/translate.spec.ts +396 -0
- package/test/util/useAnimationId.spec.tsx +59 -0
- package/test/util/useElementOffset.spec.tsx +173 -0
- package/test/util/usePrefersReducedMotion.spec.ts +54 -0
- package/test/util/useUniqueId.spec.ts +99 -0
- package/test/utils/diagnostics-allowlist.ts +18 -0
- package/test/utils/diagnostics.ts +58 -0
- package/test/zIndex/AllZIndexPortals.spec.tsx +83 -0
- package/test/zIndex/DefaultZIndexes.spec.ts +80 -0
- package/test/zIndex/DynamicZIndex.spec.tsx +102 -0
- package/test/zIndex/ZIndexLayer.portalOwner.spec.tsx +125 -0
- package/test/zIndex/componentZIndex.spec.tsx +255 -0
- package/test/zIndex/getZIndexFromUnknown.spec.ts +51 -0
- package/test/zIndex/multiChartZIndexIsolation.spec.tsx +90 -0
- package/test/zIndex/zIndexSelectors.spec.ts +172 -0
- package/tsconfig.json +11 -0
|
@@ -0,0 +1,742 @@
|
|
|
1
|
+
// Ported from recharts 3.9.0 src/cartesian/Line.tsx.
|
|
2
|
+
//
|
|
3
|
+
// FULLY WIRED: graphical-item registration, points selection, drawing (the
|
|
4
|
+
// default <LineDrawShape>), dots + activeDot, labels, legend/tooltip payload
|
|
5
|
+
// registration, ErrorBar context, clip paths, and animation on the v3.9 engine —
|
|
6
|
+
// the entrance stroke-dasharray draw-in (via useAnimatedLineLength + LineDrawShape)
|
|
7
|
+
// AND the data-change point morph (via <AnimatedItems> + defaultLineAnimateItems,
|
|
8
|
+
// replacing the legacy <JavascriptAnimate> + manual prevPoints tracking).
|
|
9
|
+
// zIndex relayering IS wired: the whole `.recharts-line` Layer is wrapped in
|
|
10
|
+
// <ZIndexLayer> (default DefaultZIndexes.line = 400), matching recharts.
|
|
11
|
+
//
|
|
12
|
+
// Deviations:
|
|
13
|
+
// - `resolveDefaultProps` → `merge` (default props).
|
|
14
|
+
// - `RegisterGraphicalItemId` + `SetCartesianGraphicalItem` (effect-dispatch
|
|
15
|
+
// components) → a single `createEffect` add/replace + `onCleanup` remove,
|
|
16
|
+
// matching the XAxis/YAxis registration idiom.
|
|
17
|
+
// - `ReactUtils.isClipDot` (React-divergent) is not ported; clip-dot handling is
|
|
18
|
+
// part of the deferred dot rendering.
|
|
19
|
+
// - `LinePointItem.value` is typed `unknown` (recharts types it `number` via
|
|
20
|
+
// `any`); the value comes from `getValueByDataKey`, which is genuinely
|
|
21
|
+
// untyped, and only x/y are needed to draw. It flows through `scale.map`
|
|
22
|
+
// (which accepts `unknown`) unchanged.
|
|
23
|
+
import { createEffect, createMemo, createSignal, merge, Show, untrack } from "solid-js";
|
|
24
|
+
import { useActiveTooltipDataPoints } from "../hooks";
|
|
25
|
+
import { selectActiveTooltipIndex } from "../state/selectors/tooltipSelectors";
|
|
26
|
+
import type { JSX } from "@solidjs/web";
|
|
27
|
+
import { useAppSelector, useAppStore } from "../state/hooks";
|
|
28
|
+
import { AnimatedItems, type AnimationInterpolateFn } from "../animation/AnimatedItems";
|
|
29
|
+
import { matchByIndex, type AnimationItem, type AnimationMatchByProp } from "../animation/matchBy";
|
|
30
|
+
import type { MutableRef } from "../animation/useAnimationStartSnapshot";
|
|
31
|
+
import { LineDrawShape, type LineDrawShapeProps } from "./LineDrawShape";
|
|
32
|
+
import { useAnimatedLineLength } from "./useAnimatedLineLength";
|
|
33
|
+
import type { EasingInput } from "../animation/easing";
|
|
34
|
+
import { SetTooltipEntrySettings } from "../state/SetTooltipEntrySettings";
|
|
35
|
+
import { TooltipPayloadConfiguration } from "../state/tooltipSlice";
|
|
36
|
+
import { SetLegendPayload } from "../state/SetLegendPayload";
|
|
37
|
+
import { LegendPayload } from "../component/DefaultLegendContent";
|
|
38
|
+
import type { Formatter } from "../component/DefaultTooltipContent";
|
|
39
|
+
import { useIsPanorama } from "../context/PanoramaContext";
|
|
40
|
+
import { useCartesianChartLayout } from "../context/chartLayoutContext";
|
|
41
|
+
import { useUniqueId } from "../util/useUniqueId";
|
|
42
|
+
import { Layer } from "../container/Layer";
|
|
43
|
+
import type { CurveType, CurveProps } from "../shape/Curve";
|
|
44
|
+
import { Dots, isClipDot } from "../component/Dots";
|
|
45
|
+
import {
|
|
46
|
+
type CartesianLabelListEntry,
|
|
47
|
+
CartesianLabelListContextProvider,
|
|
48
|
+
type ImplicitLabelListType,
|
|
49
|
+
LabelListFromLabelProp,
|
|
50
|
+
} from "../component/LabelList";
|
|
51
|
+
import type { TrapezoidViewBox } from "../util/types";
|
|
52
|
+
import { getRadiusAndStrokeWidthFromDot } from "../util/getRadiusAndStrokeWidthFromDot";
|
|
53
|
+
import { pickEventHandlers } from "../util/adaptEventHandlers";
|
|
54
|
+
import { usePlotArea } from "../hooks";
|
|
55
|
+
import { RegisterGraphicalItemId } from "../context/RegisterGraphicalItemId";
|
|
56
|
+
import { SetErrorBarContext } from "../context/ErrorBarContext";
|
|
57
|
+
import type { ErrorBarDataItem, ErrorBarDataPointFormatter } from "./ErrorBar";
|
|
58
|
+
import { selectLinePoints } from "../state/selectors/lineSelectors";
|
|
59
|
+
import { LineSettings } from "../state/types/LineSettings";
|
|
60
|
+
import { AxisId } from "../state/cartesianAxisSlice";
|
|
61
|
+
import { ChartData } from "../state/chartDataSlice";
|
|
62
|
+
import {
|
|
63
|
+
ActiveDotType,
|
|
64
|
+
ActiveShape,
|
|
65
|
+
AnimationDuration,
|
|
66
|
+
CartesianLayout,
|
|
67
|
+
DataKey,
|
|
68
|
+
DotType,
|
|
69
|
+
LegendType,
|
|
70
|
+
TickItem,
|
|
71
|
+
TooltipType,
|
|
72
|
+
} from "../util/types";
|
|
73
|
+
import {
|
|
74
|
+
computeActivePointState,
|
|
75
|
+
renderActivePointsLayerFromState,
|
|
76
|
+
} from "../component/ActivePoints";
|
|
77
|
+
import { getCateCoordinateOfLine, getTooltipNameProp, getValueByDataKey } from "../util/ChartUtils";
|
|
78
|
+
import { interpolate, isNotNil, isNullish, noop } from "../util/DataUtils";
|
|
79
|
+
import { BaseAxisWithScale } from "../state/selectors/axisSelectors";
|
|
80
|
+
import { GraphicalItemClipPath, useNeedsClip } from "./GraphicalItemClipPath";
|
|
81
|
+
import { DefaultZIndexes } from "../zIndex/DefaultZIndexes";
|
|
82
|
+
import { ZIndexLayer } from "../zIndex/ZIndexLayer";
|
|
83
|
+
import { unregisterOnCleanup } from "../state/unregisterOnCleanup";
|
|
84
|
+
|
|
85
|
+
export interface LinePointItem {
|
|
86
|
+
readonly value: unknown;
|
|
87
|
+
readonly payload?: unknown;
|
|
88
|
+
/**
|
|
89
|
+
* Line coordinates can have gaps (the `connectNulls` prop bridges them), so a
|
|
90
|
+
* point may have `null` x or y.
|
|
91
|
+
*/
|
|
92
|
+
x: number | null;
|
|
93
|
+
y: number | null;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export function computeLinePoints({
|
|
97
|
+
layout,
|
|
98
|
+
xAxis,
|
|
99
|
+
yAxis,
|
|
100
|
+
xAxisTicks,
|
|
101
|
+
yAxisTicks,
|
|
102
|
+
dataKey,
|
|
103
|
+
bandSize,
|
|
104
|
+
displayedData,
|
|
105
|
+
}: {
|
|
106
|
+
layout: CartesianLayout;
|
|
107
|
+
xAxis: BaseAxisWithScale;
|
|
108
|
+
yAxis: BaseAxisWithScale;
|
|
109
|
+
xAxisTicks: TickItem[];
|
|
110
|
+
yAxisTicks: TickItem[];
|
|
111
|
+
dataKey: DataKey<unknown> | undefined;
|
|
112
|
+
bandSize: number;
|
|
113
|
+
displayedData: ChartData;
|
|
114
|
+
}): ReadonlyArray<LinePointItem> {
|
|
115
|
+
return displayedData
|
|
116
|
+
.map((entry, index): LinePointItem | null => {
|
|
117
|
+
const value = getValueByDataKey(entry, dataKey);
|
|
118
|
+
|
|
119
|
+
if (layout === "horizontal") {
|
|
120
|
+
const x = getCateCoordinateOfLine({
|
|
121
|
+
axis: xAxis,
|
|
122
|
+
ticks: xAxisTicks,
|
|
123
|
+
bandSize,
|
|
124
|
+
entry,
|
|
125
|
+
index,
|
|
126
|
+
});
|
|
127
|
+
const y = isNullish(value) ? null : yAxis.scale.map(value);
|
|
128
|
+
return {
|
|
129
|
+
x,
|
|
130
|
+
y: y ?? null,
|
|
131
|
+
value,
|
|
132
|
+
payload: entry,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const x = isNullish(value) ? null : xAxis.scale.map(value);
|
|
137
|
+
const y = getCateCoordinateOfLine({ axis: yAxis, ticks: yAxisTicks, bandSize, entry, index });
|
|
138
|
+
if (x == null || y == null) {
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
return {
|
|
142
|
+
x,
|
|
143
|
+
y,
|
|
144
|
+
value,
|
|
145
|
+
payload: entry,
|
|
146
|
+
};
|
|
147
|
+
})
|
|
148
|
+
.filter(isNotNil);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// SVG props (including event handlers) that Line forwards onto its <Curve>, minus
|
|
152
|
+
// the ones Line computes itself or redeclares below with a narrower type. Mirrors
|
|
153
|
+
// recharts `LineSvgProps = Omit<CurveProps, ...>` so `<Line onClick={...} />` and
|
|
154
|
+
// other path attributes/events type-check on the public surface.
|
|
155
|
+
type LineSvgProps = Omit<
|
|
156
|
+
CurveProps,
|
|
157
|
+
| "points"
|
|
158
|
+
| "pathRef"
|
|
159
|
+
| "ref"
|
|
160
|
+
| "layout"
|
|
161
|
+
| "baseLine"
|
|
162
|
+
| "type"
|
|
163
|
+
| "connectNulls"
|
|
164
|
+
| "path"
|
|
165
|
+
| "class"
|
|
166
|
+
| "id"
|
|
167
|
+
| "stroke"
|
|
168
|
+
| "strokeWidth"
|
|
169
|
+
| "strokeDasharray"
|
|
170
|
+
| "fill"
|
|
171
|
+
| "children"
|
|
172
|
+
>;
|
|
173
|
+
|
|
174
|
+
export interface LineProps extends LineSvgProps {
|
|
175
|
+
xAxisId?: AxisId;
|
|
176
|
+
yAxisId?: AxisId;
|
|
177
|
+
dataKey?: DataKey<unknown>;
|
|
178
|
+
data?: ChartData;
|
|
179
|
+
/** Tooltip/legend display name; falls back to the dataKey. */
|
|
180
|
+
name?: string | number;
|
|
181
|
+
/** Unit appended in the tooltip (recharts `unit` prop). */
|
|
182
|
+
unit?: string | number | null;
|
|
183
|
+
/** `'none'` hides this series from the tooltip payload. */
|
|
184
|
+
tooltipType?: TooltipType;
|
|
185
|
+
/** Formats this Line's tooltip value; takes precedence over the Tooltip-level `formatter`. */
|
|
186
|
+
formatter?: Formatter;
|
|
187
|
+
type?: CurveType;
|
|
188
|
+
stroke?: string;
|
|
189
|
+
strokeWidth?: number;
|
|
190
|
+
strokeDasharray?: string | number;
|
|
191
|
+
fill?: string;
|
|
192
|
+
connectNulls?: boolean;
|
|
193
|
+
hide?: boolean;
|
|
194
|
+
dot?: DotType;
|
|
195
|
+
activeDot?: ActiveDotType;
|
|
196
|
+
animateNewValues?: boolean;
|
|
197
|
+
isAnimationActive?: boolean | "auto";
|
|
198
|
+
animationBegin?: number;
|
|
199
|
+
animationDuration?: AnimationDuration;
|
|
200
|
+
animationEasing?: EasingInput;
|
|
201
|
+
onAnimationStart?: () => void;
|
|
202
|
+
onAnimationEnd?: () => void;
|
|
203
|
+
/** Custom per-frame interpolation for the line points (v3.9). */
|
|
204
|
+
animationInterpolateFn?: AnimationInterpolateFn<LinePointItem, CartesianLayout>;
|
|
205
|
+
/** How prev/next points are matched across data updates (v3.9). @defaultValue matchByIndex */
|
|
206
|
+
animationMatchBy?: AnimationMatchByProp<LinePointItem>;
|
|
207
|
+
label?: ImplicitLabelListType;
|
|
208
|
+
legendType?: LegendType;
|
|
209
|
+
/** Custom line shape (function render-prop or props object). @defaultValue LineDrawShape */
|
|
210
|
+
shape?: ActiveShape<LineDrawShapeProps, SVGPathElement>;
|
|
211
|
+
zIndex?: number;
|
|
212
|
+
id?: string;
|
|
213
|
+
class?: string;
|
|
214
|
+
/** Children (e.g. <ErrorBar>, <LabelList>) rendered within the item's contexts. */
|
|
215
|
+
children?: JSX.Element;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Compute the average x-shift between matched pairs (prev → next): the overall
|
|
219
|
+
// direction and magnitude of the data movement, used to extrapolate the entry/exit
|
|
220
|
+
// position of added/removed points (recharts `averageShift`).
|
|
221
|
+
function averageShift(items: ReadonlyArray<AnimationItem<LinePointItem>>): number {
|
|
222
|
+
let total = 0;
|
|
223
|
+
let count = 0;
|
|
224
|
+
for (const item of items) {
|
|
225
|
+
if (item.status === "matched" && item.prev.x != null && item.next.x != null) {
|
|
226
|
+
total += item.next.x - item.prev.x;
|
|
227
|
+
count++;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return count > 0 ? total / count : 0;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Default per-frame interpolation for Line points (the `animationInterpolateFn`
|
|
234
|
+
// the new AnimatedItems engine drives). Mirrors recharts 3.9 `defaultLineAnimateItems`:
|
|
235
|
+
// matched points tween prev→next; added points enter from where they "would have
|
|
236
|
+
// been" (extrapolated by the average shift); removed points exit by the same shift.
|
|
237
|
+
// On first render returns [] — the entrance is driven by stroke-dasharray reveal.
|
|
238
|
+
const defaultLineAnimateItems: AnimationInterpolateFn<LinePointItem, CartesianLayout> = (
|
|
239
|
+
items,
|
|
240
|
+
animationElapsedTime,
|
|
241
|
+
) => {
|
|
242
|
+
if (items == null) {
|
|
243
|
+
return [];
|
|
244
|
+
}
|
|
245
|
+
if (animationElapsedTime === 1) {
|
|
246
|
+
return items.flatMap((item) => (item.status === "removed" ? [] : [item.next]));
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
const shift = averageShift(items);
|
|
250
|
+
const result: LinePointItem[] = [];
|
|
251
|
+
|
|
252
|
+
for (const item of items) {
|
|
253
|
+
if (item.status === "matched") {
|
|
254
|
+
result.push({
|
|
255
|
+
...item.next,
|
|
256
|
+
x: interpolate(item.prev.x, item.next.x, animationElapsedTime),
|
|
257
|
+
y: interpolate(item.prev.y, item.next.y, animationElapsedTime),
|
|
258
|
+
});
|
|
259
|
+
} else if (item.status === "added") {
|
|
260
|
+
if (item.next.x != null) {
|
|
261
|
+
const entryX = item.next.x - shift;
|
|
262
|
+
result.push({
|
|
263
|
+
...item.next,
|
|
264
|
+
x: interpolate(entryX, item.next.x, animationElapsedTime),
|
|
265
|
+
y: item.next.y,
|
|
266
|
+
});
|
|
267
|
+
} else {
|
|
268
|
+
result.push(item.next);
|
|
269
|
+
}
|
|
270
|
+
} else if (item.status === "removed") {
|
|
271
|
+
if (item.prev.x != null) {
|
|
272
|
+
const exitX = item.prev.x + shift;
|
|
273
|
+
result.push({
|
|
274
|
+
...item.prev,
|
|
275
|
+
x: interpolate(item.prev.x, exitX, animationElapsedTime),
|
|
276
|
+
y: item.prev.y,
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
// else: removed items are simply dropped
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
return result;
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
const coerceErrorVal = (value: unknown): number[] | number | undefined => {
|
|
287
|
+
if (typeof value === "number") {
|
|
288
|
+
return value;
|
|
289
|
+
}
|
|
290
|
+
if (value != null && Array.isArray(value)) {
|
|
291
|
+
const nums = value.filter((v): v is number => typeof v === "number");
|
|
292
|
+
return nums.length === value.length ? nums : undefined;
|
|
293
|
+
}
|
|
294
|
+
return undefined;
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
// Maps a LinePointItem (erased to `unknown` by the ErrorBar context) to the
|
|
298
|
+
// {x, y, value, errorVal} an ErrorBar needs.
|
|
299
|
+
const lineErrorBarFormatter: ErrorBarDataPointFormatter = (entry, dataKey): ErrorBarDataItem => {
|
|
300
|
+
// `entry` is a LinePointItem erased to `unknown` by the context; read its fields
|
|
301
|
+
// via getValueByDataKey (accepts unknown) to stay cast-free.
|
|
302
|
+
const x = getValueByDataKey(entry, "x");
|
|
303
|
+
const y = getValueByDataKey(entry, "y");
|
|
304
|
+
const value = getValueByDataKey(entry, "value");
|
|
305
|
+
const payload = getValueByDataKey(entry, "payload");
|
|
306
|
+
return {
|
|
307
|
+
x: typeof x === "number" ? x : undefined,
|
|
308
|
+
y: typeof y === "number" ? y : undefined,
|
|
309
|
+
value: typeof value === "number" ? value : 0,
|
|
310
|
+
errorVal: coerceErrorVal(getValueByDataKey(payload, dataKey)),
|
|
311
|
+
};
|
|
312
|
+
};
|
|
313
|
+
|
|
314
|
+
export const lineDefaultProps = {
|
|
315
|
+
activeDot: true,
|
|
316
|
+
animateNewValues: true,
|
|
317
|
+
connectNulls: false,
|
|
318
|
+
dot: true,
|
|
319
|
+
fill: "#fff",
|
|
320
|
+
hide: false,
|
|
321
|
+
stroke: "#3182bd",
|
|
322
|
+
strokeWidth: 1,
|
|
323
|
+
xAxisId: 0,
|
|
324
|
+
yAxisId: 0,
|
|
325
|
+
type: "linear",
|
|
326
|
+
isAnimationActive: "auto",
|
|
327
|
+
animationBegin: 0,
|
|
328
|
+
animationDuration: 1500,
|
|
329
|
+
animationEasing: "ease",
|
|
330
|
+
animationInterpolateFn: defaultLineAnimateItems,
|
|
331
|
+
animationMatchBy: matchByIndex,
|
|
332
|
+
label: false,
|
|
333
|
+
legendType: "line",
|
|
334
|
+
shape: LineDrawShape,
|
|
335
|
+
zIndex: DefaultZIndexes.line,
|
|
336
|
+
} as const;
|
|
337
|
+
|
|
338
|
+
export const Line = (props: LineProps): JSX.Element => {
|
|
339
|
+
const store = useAppStore();
|
|
340
|
+
const merged = merge(lineDefaultProps, props);
|
|
341
|
+
const isPanorama = useIsPanorama();
|
|
342
|
+
const layout = useCartesianChartLayout();
|
|
343
|
+
const id = useUniqueId("recharts-line", props.id);
|
|
344
|
+
|
|
345
|
+
let prev: LineSettings | null = null;
|
|
346
|
+
|
|
347
|
+
createEffect(
|
|
348
|
+
(): LineSettings => ({
|
|
349
|
+
id,
|
|
350
|
+
type: "line",
|
|
351
|
+
isPanorama,
|
|
352
|
+
data: merged.data,
|
|
353
|
+
dataKey: merged.dataKey,
|
|
354
|
+
xAxisId: merged.xAxisId,
|
|
355
|
+
yAxisId: merged.yAxisId,
|
|
356
|
+
zAxisId: 0,
|
|
357
|
+
hide: merged.hide,
|
|
358
|
+
}),
|
|
359
|
+
(settings) => {
|
|
360
|
+
if (store == null) {
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
if (prev === null) {
|
|
364
|
+
store.actions.graphicalItems.addCartesianGraphicalItem(settings);
|
|
365
|
+
} else if (prev !== settings) {
|
|
366
|
+
store.actions.graphicalItems.replaceCartesianGraphicalItem({ prev, next: settings });
|
|
367
|
+
}
|
|
368
|
+
prev = settings;
|
|
369
|
+
},
|
|
370
|
+
);
|
|
371
|
+
|
|
372
|
+
unregisterOnCleanup(() => {
|
|
373
|
+
if (prev && store != null) {
|
|
374
|
+
store.actions.graphicalItems.removeCartesianGraphicalItem(prev);
|
|
375
|
+
prev = null;
|
|
376
|
+
}
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
const points = useAppSelector((state) =>
|
|
380
|
+
selectLinePoints(state, merged.xAxisId, merged.yAxisId, isPanorama, id),
|
|
381
|
+
);
|
|
382
|
+
|
|
383
|
+
const tooltipConfig = createMemo<TooltipPayloadConfiguration>(() => ({
|
|
384
|
+
dataDefinedOnItem: merged.data,
|
|
385
|
+
getPosition: noop,
|
|
386
|
+
settings: {
|
|
387
|
+
stroke: merged.stroke,
|
|
388
|
+
strokeWidth: merged.strokeWidth,
|
|
389
|
+
fill: merged.fill,
|
|
390
|
+
dataKey: merged.dataKey,
|
|
391
|
+
nameKey: undefined,
|
|
392
|
+
name: getTooltipNameProp(merged.name, merged.dataKey),
|
|
393
|
+
hide: merged.hide,
|
|
394
|
+
type: merged.tooltipType,
|
|
395
|
+
color: merged.stroke,
|
|
396
|
+
unit: merged.unit,
|
|
397
|
+
formatter: merged.formatter,
|
|
398
|
+
graphicalItemId: id,
|
|
399
|
+
},
|
|
400
|
+
}));
|
|
401
|
+
|
|
402
|
+
// Legend payload entry for this line.
|
|
403
|
+
const legendPayload = createMemo<ReadonlyArray<LegendPayload>>(() => [
|
|
404
|
+
{
|
|
405
|
+
inactive: merged.hide,
|
|
406
|
+
dataKey: merged.dataKey,
|
|
407
|
+
type: merged.legendType,
|
|
408
|
+
color: merged.stroke,
|
|
409
|
+
value: getTooltipNameProp(merged.name, merged.dataKey),
|
|
410
|
+
payload: {
|
|
411
|
+
activeDot: merged.activeDot,
|
|
412
|
+
animateNewValues: merged.animateNewValues,
|
|
413
|
+
animationBegin: merged.animationBegin,
|
|
414
|
+
animationDuration: merged.animationDuration,
|
|
415
|
+
animationEasing: merged.animationEasing,
|
|
416
|
+
connectNulls: merged.connectNulls,
|
|
417
|
+
dataKey: merged.dataKey,
|
|
418
|
+
dot: merged.dot,
|
|
419
|
+
fill: merged.fill,
|
|
420
|
+
hide: merged.hide,
|
|
421
|
+
id: merged.id,
|
|
422
|
+
isAnimationActive: merged.isAnimationActive,
|
|
423
|
+
label: merged.label,
|
|
424
|
+
legendType: merged.legendType,
|
|
425
|
+
name: merged.name,
|
|
426
|
+
shape: merged.shape,
|
|
427
|
+
stroke: merged.stroke,
|
|
428
|
+
strokeWidth: merged.strokeWidth,
|
|
429
|
+
type: merged.type,
|
|
430
|
+
xAxisId: merged.xAxisId,
|
|
431
|
+
yAxisId: merged.yAxisId,
|
|
432
|
+
zIndex: merged.zIndex,
|
|
433
|
+
},
|
|
434
|
+
},
|
|
435
|
+
]);
|
|
436
|
+
|
|
437
|
+
// Entrance animation: the curve "draws" via stroke-dasharray (the `d` is morphed
|
|
438
|
+
// by AnimatedItems on a data change, but the entrance reveal itself is dash-only).
|
|
439
|
+
// The new v3.9 engine drives this through <AnimatedItems> + <LineDrawShape>:
|
|
440
|
+
// - `previousItemsRef` holds the last visible point frame so a re-animation
|
|
441
|
+
// (data change) tweens from where the line currently is (managed by
|
|
442
|
+
// useAnimationStartSnapshot inside AnimatedItems).
|
|
443
|
+
// - `useAnimatedLineLength` tracks the monotonically-growing visible length so a
|
|
444
|
+
// mid-animation data change continues the dash from the furthest length drawn
|
|
445
|
+
// (recharts' startingLengthRef / maxAnimatedLengthRef) and returns null once
|
|
446
|
+
// full (no entrance dasharray needed).
|
|
447
|
+
// - `totalLength` is measured off the rendered path (in an effect, NOT a ref —
|
|
448
|
+
// refs fire before the dynamic `d` lands, where getTotalLength() is 0).
|
|
449
|
+
const [totalLength, setTotalLength] = createSignal(0);
|
|
450
|
+
let curveEl: SVGPathElement | undefined;
|
|
451
|
+
const forwardPathRef = (el: SVGPathElement): void => {
|
|
452
|
+
curveEl = el;
|
|
453
|
+
};
|
|
454
|
+
const previousPointsRef: MutableRef<ReadonlyArray<LinePointItem> | null | undefined> = {
|
|
455
|
+
current: null,
|
|
456
|
+
};
|
|
457
|
+
const animatedLineLength = useAnimatedLineLength();
|
|
458
|
+
|
|
459
|
+
const activeTooltipIndex = useAppSelector(selectActiveTooltipIndex);
|
|
460
|
+
const activeDataPoints = useActiveTooltipDataPoints();
|
|
461
|
+
|
|
462
|
+
const { needClip } = useNeedsClip(merged.xAxisId, merged.yAxisId);
|
|
463
|
+
const plotArea = usePlotArea();
|
|
464
|
+
// Line is only ever horizontal | vertical (the render Show below cannot mount in
|
|
465
|
+
// any other layout); coerce for the AnimatedItems layout prop.
|
|
466
|
+
const cartesianLayout = (): CartesianLayout =>
|
|
467
|
+
layout() === "vertical" ? "vertical" : "horizontal";
|
|
468
|
+
|
|
469
|
+
// One LabelList entry per data point: a zero-size viewBox at the point's (x, y).
|
|
470
|
+
// recharts does not pass parentViewBox here (labels can escape) — mirrored.
|
|
471
|
+
const labelListEntries = createMemo<ReadonlyArray<CartesianLabelListEntry>>(() => {
|
|
472
|
+
const pts = points();
|
|
473
|
+
if (pts == null) {
|
|
474
|
+
return [];
|
|
475
|
+
}
|
|
476
|
+
return pts.map((point): CartesianLabelListEntry => {
|
|
477
|
+
const viewBox: TrapezoidViewBox = {
|
|
478
|
+
x: point.x ?? 0,
|
|
479
|
+
y: point.y ?? 0,
|
|
480
|
+
width: 0,
|
|
481
|
+
lowerWidth: 0,
|
|
482
|
+
upperWidth: 0,
|
|
483
|
+
height: 0,
|
|
484
|
+
};
|
|
485
|
+
return {
|
|
486
|
+
...viewBox,
|
|
487
|
+
value: point.value,
|
|
488
|
+
payload: point.payload,
|
|
489
|
+
viewBox,
|
|
490
|
+
parentViewBox: undefined,
|
|
491
|
+
fill: undefined,
|
|
492
|
+
};
|
|
493
|
+
});
|
|
494
|
+
});
|
|
495
|
+
// Labels are hidden while the entrance animation runs and shown once it ends
|
|
496
|
+
// (matching recharts: showLabels = !isAnimating).
|
|
497
|
+
// ownedWrite: handleAnimationEnd also fires from the animation effect cleanup
|
|
498
|
+
// when a mid-animation chart is disposed (route/soft navigation) — a legal
|
|
499
|
+
// teardown write, not a write-in-computation bug.
|
|
500
|
+
const [showLabels, setShowLabels] = createSignal(true, { ownedWrite: true });
|
|
501
|
+
const labelContextEntries = createMemo(() => (showLabels() ? labelListEntries() : undefined));
|
|
502
|
+
const handleAnimationStart = (): void => {
|
|
503
|
+
props.onAnimationStart?.();
|
|
504
|
+
setShowLabels(false);
|
|
505
|
+
};
|
|
506
|
+
const handleAnimationEnd = (): void => {
|
|
507
|
+
props.onAnimationEnd?.();
|
|
508
|
+
setShowLabels(true);
|
|
509
|
+
};
|
|
510
|
+
|
|
511
|
+
// Measure on data change AND on animation start/end (showLabels flips): a
|
|
512
|
+
// data-change morph alters the path geometry per frame, so the length taken
|
|
513
|
+
// at the morph's first frame is the OLD curve's; re-measuring once the final
|
|
514
|
+
// frame committed (effects run after render effects in the flush) gives the
|
|
515
|
+
// settled dasharray the new curve's true length — mirroring recharts, which
|
|
516
|
+
// recomputes totalLength on the post-animation re-render.
|
|
517
|
+
createEffect(
|
|
518
|
+
() => ({ points: points(), showLabels: showLabels() }),
|
|
519
|
+
() => {
|
|
520
|
+
if (curveEl?.getTotalLength == null) {
|
|
521
|
+
return;
|
|
522
|
+
}
|
|
523
|
+
let length = 0;
|
|
524
|
+
try {
|
|
525
|
+
length = curveEl.getTotalLength() || 0;
|
|
526
|
+
} catch {
|
|
527
|
+
return; // getTotalLength can throw on detached/empty paths — keep the last value.
|
|
528
|
+
}
|
|
529
|
+
setTotalLength(length);
|
|
530
|
+
},
|
|
531
|
+
);
|
|
532
|
+
|
|
533
|
+
// Raw user event handlers forwarded to the curve. recharts' StaticCurve spreads
|
|
534
|
+
// `svgPropertiesAndEvents(others)` onto the curve and Curve rewraps them props-first
|
|
535
|
+
// via `adaptEventHandlers`; we forward the raw handlers and let Curve do the wrap.
|
|
536
|
+
const eventHandlers = (): Record<string, unknown> => pickEventHandlers(props);
|
|
537
|
+
|
|
538
|
+
// When the dots are NOT clipped to the dot bounding box (clipDot false), recharts
|
|
539
|
+
// emits a wider `clipPath-dots-` rect (plot area expanded by the dot size) and the
|
|
540
|
+
// Dots wrapper references it; clipDot true reuses the graphical-item clip path.
|
|
541
|
+
const dotsClip = (): { clipDot: boolean; dotSize: number } => {
|
|
542
|
+
const { r, strokeWidth } = getRadiusAndStrokeWidthFromDot(merged.dot);
|
|
543
|
+
return { clipDot: isClipDot(merged.dot), dotSize: r * 2 + strokeWidth };
|
|
544
|
+
};
|
|
545
|
+
const tooltipActive = createMemo(() => ({
|
|
546
|
+
index: activeTooltipIndex(),
|
|
547
|
+
dataPoints: activeDataPoints(),
|
|
548
|
+
}));
|
|
549
|
+
const curveClipPath = createMemo(() => (needClip() ? `url(#clipPath-${id})` : undefined));
|
|
550
|
+
// recharts emits the plot-area width/height as raw DOM attributes on the curve
|
|
551
|
+
// path (the "Render 1 line" attr-set spec asserts them). SVG <path> has no typed
|
|
552
|
+
// width/height, so spread them as a plain object rather than typed JSX props.
|
|
553
|
+
const curveSizeAttrs = (): Record<string, number> => {
|
|
554
|
+
const area = plotArea();
|
|
555
|
+
if (area == null) {
|
|
556
|
+
return {};
|
|
557
|
+
}
|
|
558
|
+
return { width: area.width, height: area.height };
|
|
559
|
+
};
|
|
560
|
+
// Guard for shouldUpdatePreviousRef: don't commit the previous-points ref before
|
|
561
|
+
// the SVG path length has been measured (recharts gates on `t > 0 && totalLength
|
|
562
|
+
// > 0`). totalLength() is read untracked — this is called from the animation
|
|
563
|
+
// render-prop where reactive subscription would be a write-in-computation.
|
|
564
|
+
const shouldUpdatePreviousRef = (animationElapsedTime: number): boolean =>
|
|
565
|
+
animationElapsedTime > 0 && untrack(totalLength) > 0;
|
|
566
|
+
|
|
567
|
+
// Whether to apply the entrance/draw shape (skip when a custom shape is supplied,
|
|
568
|
+
// mirroring recharts: a custom shape opts out of the built-in dasharray reveal).
|
|
569
|
+
const hasCustomShape = (): boolean => merged.shape !== LineDrawShape;
|
|
570
|
+
|
|
571
|
+
return (
|
|
572
|
+
<>
|
|
573
|
+
<SetTooltipEntrySettings tooltipEntrySettings={tooltipConfig()} />
|
|
574
|
+
<SetLegendPayload id={id} legendPayload={legendPayload()} />
|
|
575
|
+
<Show when={!merged.hide && points()}>
|
|
576
|
+
{(pts) => (
|
|
577
|
+
// The line group carries "recharts-line" plus the user's `class`
|
|
578
|
+
// (recharts: clsx('recharts-line', className)). Wrapped in <ZIndexLayer>
|
|
579
|
+
// (default 400) so a `zIndex` prop relayers the whole line into its portal
|
|
580
|
+
// — recharts wraps the entire `.recharts-line` Layer in ZIndexLayer.
|
|
581
|
+
<ZIndexLayer zIndex={merged.zIndex}>
|
|
582
|
+
<Layer class={merged.class == null ? "recharts-line" : `recharts-line ${merged.class}`}>
|
|
583
|
+
<Show when={needClip()}>
|
|
584
|
+
<defs>
|
|
585
|
+
<GraphicalItemClipPath
|
|
586
|
+
clipPathId={id}
|
|
587
|
+
xAxisId={merged.xAxisId}
|
|
588
|
+
yAxisId={merged.yAxisId}
|
|
589
|
+
/>
|
|
590
|
+
<Show when={!dotsClip().clipDot && plotArea()}>
|
|
591
|
+
{(area) => (
|
|
592
|
+
<clipPath id={`clipPath-dots-${id}`}>
|
|
593
|
+
<rect
|
|
594
|
+
x={area().x - dotsClip().dotSize / 2}
|
|
595
|
+
y={area().y - dotsClip().dotSize / 2}
|
|
596
|
+
width={area().width + dotsClip().dotSize}
|
|
597
|
+
height={area().height + dotsClip().dotSize}
|
|
598
|
+
/>
|
|
599
|
+
</clipPath>
|
|
600
|
+
)}
|
|
601
|
+
</Show>
|
|
602
|
+
</defs>
|
|
603
|
+
</Show>
|
|
604
|
+
<CartesianLabelListContextProvider value={labelContextEntries}>
|
|
605
|
+
<AnimatedItems
|
|
606
|
+
animationInput={pts()}
|
|
607
|
+
animationIdPrefix="recharts-line-"
|
|
608
|
+
items={pts()}
|
|
609
|
+
previousItemsRef={previousPointsRef}
|
|
610
|
+
isAnimationActive={merged.isAnimationActive}
|
|
611
|
+
animationBegin={merged.animationBegin}
|
|
612
|
+
animationDuration={merged.animationDuration}
|
|
613
|
+
animationEasing={merged.animationEasing}
|
|
614
|
+
onAnimationStart={handleAnimationStart}
|
|
615
|
+
onAnimationEnd={handleAnimationEnd}
|
|
616
|
+
animationInterpolateFn={merged.animationInterpolateFn}
|
|
617
|
+
animationMatchBy={merged.animationMatchBy}
|
|
618
|
+
shouldUpdatePreviousRef={shouldUpdatePreviousRef}
|
|
619
|
+
layout={cartesianLayout()}
|
|
620
|
+
>
|
|
621
|
+
{(frame, animationElapsedTime, isEntrance) => {
|
|
622
|
+
// Detect a data change (ref-compare) before measuring the visible
|
|
623
|
+
// length, so a mid-animation data swap resumes the dash from the
|
|
624
|
+
// furthest length already drawn — recharts does this in render via
|
|
625
|
+
// useAnimatedLineLength's prevPointsRef compare.
|
|
626
|
+
animatedLineLength.markDataChange(untrack(pts));
|
|
627
|
+
// recharts: visibleLength is computed only while the animation is
|
|
628
|
+
// active; once settled it is null so no entrance dasharray remains.
|
|
629
|
+
const len = untrack(totalLength);
|
|
630
|
+
const animationActive =
|
|
631
|
+
untrack(showLabels) === false || animationElapsedTime < 1;
|
|
632
|
+
const visibleLength = animationActive
|
|
633
|
+
? animatedLineLength.getVisibleLength(animationElapsedTime, len)
|
|
634
|
+
: null;
|
|
635
|
+
// recharts only draws the curve path when there is more than one
|
|
636
|
+
// point (a single point is a lone dot, no line).
|
|
637
|
+
const shapeProps = (): LineDrawShapeProps => ({
|
|
638
|
+
class: "recharts-line-curve",
|
|
639
|
+
id,
|
|
640
|
+
points: frame,
|
|
641
|
+
type: merged.type,
|
|
642
|
+
layout: layout(),
|
|
643
|
+
connectNulls: merged.connectNulls,
|
|
644
|
+
fill: "none",
|
|
645
|
+
stroke: merged.stroke,
|
|
646
|
+
strokeWidth: merged.strokeWidth,
|
|
647
|
+
strokeDasharray: merged.strokeDasharray,
|
|
648
|
+
animationElapsedTime,
|
|
649
|
+
isAnimating: animationActive,
|
|
650
|
+
isEntrance: merged.animateNewValues ? isEntrance : false,
|
|
651
|
+
visibleLength,
|
|
652
|
+
forwardPathRef,
|
|
653
|
+
...eventHandlers(),
|
|
654
|
+
...curveSizeAttrs(),
|
|
655
|
+
...(curveClipPath() != null ? { clipPath: curveClipPath() } : {}),
|
|
656
|
+
});
|
|
657
|
+
const customShape = merged.shape;
|
|
658
|
+
return (
|
|
659
|
+
<>
|
|
660
|
+
<Show when={frame.length > 1}>
|
|
661
|
+
{hasCustomShape() && typeof customShape === "function" ? (
|
|
662
|
+
customShape(shapeProps())
|
|
663
|
+
) : (
|
|
664
|
+
<LineDrawShape {...shapeProps()} />
|
|
665
|
+
)}
|
|
666
|
+
</Show>
|
|
667
|
+
{/* Dots live inside the animation frame (recharts StaticCurve
|
|
668
|
+
renders them from stepData), so a data-change morph moves
|
|
669
|
+
the dots with the curve. */}
|
|
670
|
+
<Dots
|
|
671
|
+
points={frame}
|
|
672
|
+
dot={merged.dot}
|
|
673
|
+
class="recharts-line-dots"
|
|
674
|
+
dotClass="recharts-line-dot"
|
|
675
|
+
dataKey={merged.dataKey}
|
|
676
|
+
needClip={needClip()}
|
|
677
|
+
clipPathId={id}
|
|
678
|
+
baseProps={{
|
|
679
|
+
stroke: merged.stroke,
|
|
680
|
+
strokeWidth: merged.strokeWidth,
|
|
681
|
+
fill: merged.fill,
|
|
682
|
+
}}
|
|
683
|
+
/>
|
|
684
|
+
</>
|
|
685
|
+
);
|
|
686
|
+
}}
|
|
687
|
+
</AnimatedItems>
|
|
688
|
+
<LabelListFromLabelProp label={merged.label} />
|
|
689
|
+
</CartesianLabelListContextProvider>
|
|
690
|
+
</Layer>
|
|
691
|
+
</ZIndexLayer>
|
|
692
|
+
)}
|
|
693
|
+
</Show>
|
|
694
|
+
<>
|
|
695
|
+
{(() => {
|
|
696
|
+
const pts = points();
|
|
697
|
+
if (pts == null) {
|
|
698
|
+
return null;
|
|
699
|
+
}
|
|
700
|
+
const t = tooltipActive();
|
|
701
|
+
const state = computeActivePointState({
|
|
702
|
+
points: pts,
|
|
703
|
+
activeTooltipIndex: t.index,
|
|
704
|
+
activeDataPoints: t.dataPoints,
|
|
705
|
+
activeDot: merged.activeDot,
|
|
706
|
+
mainColor: merged.stroke,
|
|
707
|
+
itemDataKey: merged.dataKey,
|
|
708
|
+
clipPath: needClip() ? `url(#clipPath-${id})` : undefined,
|
|
709
|
+
});
|
|
710
|
+
if (state == null) {
|
|
711
|
+
return null;
|
|
712
|
+
}
|
|
713
|
+
return renderActivePointsLayerFromState(state, {
|
|
714
|
+
points: pts,
|
|
715
|
+
activeDot: merged.activeDot,
|
|
716
|
+
mainColor: merged.stroke,
|
|
717
|
+
itemDataKey: merged.dataKey,
|
|
718
|
+
clipPath: needClip() ? `url(#clipPath-${id})` : undefined,
|
|
719
|
+
});
|
|
720
|
+
})()}
|
|
721
|
+
</>
|
|
722
|
+
{/* Provide the item's id + data/axes to children (ErrorBar/LabelList).
|
|
723
|
+
Rendered unconditionally so ErrorBar registers and can extend the axis
|
|
724
|
+
domain even before/independent of the curve drawing. */}
|
|
725
|
+
<RegisterGraphicalItemId type="line" id={id}>
|
|
726
|
+
{() => (
|
|
727
|
+
<SetErrorBarContext
|
|
728
|
+
xAxisId={merged.xAxisId}
|
|
729
|
+
yAxisId={merged.yAxisId}
|
|
730
|
+
data={points() ?? []}
|
|
731
|
+
dataPointFormatter={lineErrorBarFormatter}
|
|
732
|
+
errorBarOffset={0}
|
|
733
|
+
>
|
|
734
|
+
<CartesianLabelListContextProvider value={labelContextEntries}>
|
|
735
|
+
{props.children}
|
|
736
|
+
</CartesianLabelListContextProvider>
|
|
737
|
+
</SetErrorBarContext>
|
|
738
|
+
)}
|
|
739
|
+
</RegisterGraphicalItemId>
|
|
740
|
+
</>
|
|
741
|
+
);
|
|
742
|
+
};
|