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,128 @@
|
|
|
1
|
+
// Ported from recharts 3.8.1 src/state/zIndexSlice.ts (commit 7a23854).
|
|
2
|
+
// FULL SOLID-NATIVE REWRITE (no Redux/immer). Registry of z-index -> element refs
|
|
3
|
+
// used to portal components at each z-index. Z-index layering is wired into the
|
|
4
|
+
// store so chart items can render through ZIndexLayer.
|
|
5
|
+
import { createStore } from "solid-js";
|
|
6
|
+
import { DefaultZIndexes } from "../zIndex/DefaultZIndexes";
|
|
7
|
+
|
|
8
|
+
type ZIndexEntry = {
|
|
9
|
+
/**
|
|
10
|
+
* DOM element backing this z-index (used to portal components here). `undefined`
|
|
11
|
+
* means registration is in progress -- wait for the next render cycle.
|
|
12
|
+
*/
|
|
13
|
+
element: Element | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* Panorama items render in a different SVG element, so they need a separate
|
|
16
|
+
* element reference from normal items at the same z-index.
|
|
17
|
+
*/
|
|
18
|
+
panoramaElement: Element | undefined;
|
|
19
|
+
consumers: number;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export type ZIndexState = {
|
|
23
|
+
zIndexMap: Record<number, ZIndexEntry>;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
function buildInitialMap(): Record<number, ZIndexEntry> {
|
|
27
|
+
const map: Record<number, ZIndexEntry> = {};
|
|
28
|
+
for (const z of Object.values(DefaultZIndexes)) {
|
|
29
|
+
map[z] = { element: undefined, panoramaElement: undefined, consumers: 0 };
|
|
30
|
+
}
|
|
31
|
+
return map;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export const initialZIndexState: ZIndexState = {
|
|
35
|
+
zIndexMap: buildInitialMap(),
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const defaultZIndexSet = new Set<number>(Object.values(DefaultZIndexes));
|
|
39
|
+
function isDefaultZIndex(zIndex: number): boolean {
|
|
40
|
+
return defaultZIndexSet.has(zIndex);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface ZIndexActions {
|
|
44
|
+
registerZIndexPortal(payload: { zIndex: number }): void;
|
|
45
|
+
unregisterZIndexPortal(payload: { zIndex: number }): void;
|
|
46
|
+
registerZIndexPortalElement(payload: {
|
|
47
|
+
zIndex: number;
|
|
48
|
+
element: Element;
|
|
49
|
+
isPanorama: boolean;
|
|
50
|
+
}): void;
|
|
51
|
+
unregisterZIndexPortalElement(payload: { zIndex: number; isPanorama: boolean }): void;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export interface ZIndexSlice {
|
|
55
|
+
readonly state: ZIndexState;
|
|
56
|
+
readonly actions: ZIndexActions;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function createZIndexSlice(initialState: ZIndexState = initialZIndexState): ZIndexSlice {
|
|
60
|
+
// Deep-copy the entries: a shallow `{ ...initialState.zIndexMap }` would make
|
|
61
|
+
// every chart's store wrap the SAME module-level ZIndexEntry objects from
|
|
62
|
+
// `initialZIndexState`, so one chart registering its portal <g> would
|
|
63
|
+
// overwrite every other chart's portal element (graphical items then portal
|
|
64
|
+
// into a different chart's svg).
|
|
65
|
+
const [state, setState] = createStore<ZIndexState>({
|
|
66
|
+
zIndexMap: Object.fromEntries(
|
|
67
|
+
Object.entries(initialState.zIndexMap).map(([z, entry]) => [z, { ...entry }]),
|
|
68
|
+
),
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
const actions: ZIndexActions = {
|
|
72
|
+
registerZIndexPortal({ zIndex }) {
|
|
73
|
+
setState((s) => {
|
|
74
|
+
const entry = s.zIndexMap[zIndex];
|
|
75
|
+
if (entry) {
|
|
76
|
+
entry.consumers += 1;
|
|
77
|
+
} else {
|
|
78
|
+
s.zIndexMap[zIndex] = { consumers: 1, element: undefined, panoramaElement: undefined };
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
},
|
|
82
|
+
unregisterZIndexPortal({ zIndex }) {
|
|
83
|
+
setState((s) => {
|
|
84
|
+
const entry = s.zIndexMap[zIndex];
|
|
85
|
+
if (entry) {
|
|
86
|
+
entry.consumers -= 1;
|
|
87
|
+
// Garbage-collect unused entries, except default z-indexes (always
|
|
88
|
+
// rendered, so their portal provider stays mounted and won't re-register).
|
|
89
|
+
if (entry.consumers <= 0 && !isDefaultZIndex(zIndex)) {
|
|
90
|
+
delete s.zIndexMap[zIndex];
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
},
|
|
95
|
+
registerZIndexPortalElement({ zIndex, element, isPanorama }) {
|
|
96
|
+
setState((s) => {
|
|
97
|
+
const entry = s.zIndexMap[zIndex];
|
|
98
|
+
if (entry) {
|
|
99
|
+
if (isPanorama) {
|
|
100
|
+
entry.panoramaElement = element;
|
|
101
|
+
} else {
|
|
102
|
+
entry.element = element;
|
|
103
|
+
}
|
|
104
|
+
} else {
|
|
105
|
+
s.zIndexMap[zIndex] = {
|
|
106
|
+
consumers: 0,
|
|
107
|
+
element: isPanorama ? undefined : element,
|
|
108
|
+
panoramaElement: isPanorama ? element : undefined,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
},
|
|
113
|
+
unregisterZIndexPortalElement({ zIndex, isPanorama }) {
|
|
114
|
+
setState((s) => {
|
|
115
|
+
const entry = s.zIndexMap[zIndex];
|
|
116
|
+
if (entry) {
|
|
117
|
+
if (isPanorama) {
|
|
118
|
+
entry.panoramaElement = undefined;
|
|
119
|
+
} else {
|
|
120
|
+
entry.element = undefined;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
},
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
return { state, actions };
|
|
128
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
// Solid-native cross-chart synchronisation registry.
|
|
2
|
+
//
|
|
3
|
+
// recharts 3.8.1 synchronises charts through a global mitt `eventCenter`
|
|
4
|
+
// (`src/util/Events.ts`): on every tooltip/brush interaction a chart emits a
|
|
5
|
+
// `TOOLTIP_SYNC_EVENT`/`BRUSH_SYNC_EVENT` carrying `(syncId, action, emitter)`,
|
|
6
|
+
// and every chart subscribes to the same bus and filters by `syncId`/`emitter`.
|
|
7
|
+
// The Solid-native rewrite has NO Redux and intentionally NO mitt — but a module
|
|
8
|
+
// -level pub/sub registry is still the right shape for many-to-many cross-chart
|
|
9
|
+
// communication (each chart's store is an island; there is no shared reactive
|
|
10
|
+
// owner). This is a tiny synchronous emitter keyed by event name, deliberately
|
|
11
|
+
// mirroring the recharts `eventCenter` API surface (`on`/`off`/`emit`) so the
|
|
12
|
+
// behaviour — "send one event, every other subscriber receives it synchronously"
|
|
13
|
+
// — is identical, and so the vendored synchronisation specs port faithfully.
|
|
14
|
+
//
|
|
15
|
+
// Deviations from recharts:
|
|
16
|
+
// - The payload is the *plain* `TooltipSyncState` object (recharts wraps it in a
|
|
17
|
+
// Redux `PayloadAction` via `setSyncInteraction(payload)`; here
|
|
18
|
+
// `setSyncInteraction` is a void store mutator, so the registry carries the
|
|
19
|
+
// payload directly and receivers call `store.actions.tooltip.setSyncInteraction`).
|
|
20
|
+
// - Emission happens from component effects (not a Redux middleware). Writes into
|
|
21
|
+
// a receiver's store therefore go through the store's batched setter; the
|
|
22
|
+
// registry itself holds no reactive state, so subscribing/emitting never reads
|
|
23
|
+
// or writes a tracked scope (no STRICT_READ / SIGNAL_WRITE_IN_OWNED_SCOPE).
|
|
24
|
+
import { BrushStartEndIndex } from "../context/brushUpdateContext";
|
|
25
|
+
import { TooltipSyncState } from "../state/tooltipSlice";
|
|
26
|
+
|
|
27
|
+
export const TOOLTIP_SYNC_EVENT = "recharts.syncEvent.tooltip";
|
|
28
|
+
export const BRUSH_SYNC_EVENT = "recharts.syncEvent.brush";
|
|
29
|
+
|
|
30
|
+
export type SyncId = number | string;
|
|
31
|
+
|
|
32
|
+
export type TooltipSyncListener = (
|
|
33
|
+
syncId: SyncId,
|
|
34
|
+
payload: TooltipSyncState,
|
|
35
|
+
emitter: symbol,
|
|
36
|
+
) => void;
|
|
37
|
+
|
|
38
|
+
export type BrushSyncListener = (
|
|
39
|
+
syncId: SyncId,
|
|
40
|
+
payload: BrushStartEndIndex,
|
|
41
|
+
emitter: symbol,
|
|
42
|
+
) => void;
|
|
43
|
+
|
|
44
|
+
// Two separately-typed listener sets — one per event. The public methods below
|
|
45
|
+
// are typed via overloads (faithful to recharts' eventCenter signature); their
|
|
46
|
+
// shared implementation narrows on `eventName`, but TypeScript can't co-narrow
|
|
47
|
+
// the listener/payload param from that runtime check, so each branch keeps one
|
|
48
|
+
// localized assertion (the repo's convention for unavoidable narrowing).
|
|
49
|
+
const tooltipListeners = new Set<TooltipSyncListener>();
|
|
50
|
+
const brushListeners = new Set<BrushSyncListener>();
|
|
51
|
+
|
|
52
|
+
type AnyListener = TooltipSyncListener | BrushSyncListener;
|
|
53
|
+
type AnyPayload = TooltipSyncState | BrushStartEndIndex;
|
|
54
|
+
|
|
55
|
+
// Copy first so a listener that unsubscribes during dispatch doesn't mutate the
|
|
56
|
+
// set we're iterating (matches mitt's array-snapshot semantics).
|
|
57
|
+
function snapshot<L>(set: Set<L>): ReadonlyArray<L> {
|
|
58
|
+
return Array.from(set);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Overloaded surface of the bus. Interface declarations may carry method
|
|
63
|
+
* overloads (object-literal methods may not — the toolchain's formatter rejects
|
|
64
|
+
* them), so the typed `on`/`off`/`emit` overloads live here and the concrete
|
|
65
|
+
* object below is annotated with this type.
|
|
66
|
+
*/
|
|
67
|
+
interface SyncEventCenter {
|
|
68
|
+
on(eventName: typeof TOOLTIP_SYNC_EVENT, listener: TooltipSyncListener): void;
|
|
69
|
+
on(eventName: typeof BRUSH_SYNC_EVENT, listener: BrushSyncListener): void;
|
|
70
|
+
off(eventName: typeof TOOLTIP_SYNC_EVENT, listener: TooltipSyncListener): void;
|
|
71
|
+
off(eventName: typeof BRUSH_SYNC_EVENT, listener: BrushSyncListener): void;
|
|
72
|
+
emit(
|
|
73
|
+
eventName: typeof TOOLTIP_SYNC_EVENT,
|
|
74
|
+
syncId: SyncId,
|
|
75
|
+
payload: TooltipSyncState,
|
|
76
|
+
emitter: symbol,
|
|
77
|
+
): void;
|
|
78
|
+
emit(
|
|
79
|
+
eventName: typeof BRUSH_SYNC_EVENT,
|
|
80
|
+
syncId: SyncId,
|
|
81
|
+
payload: BrushStartEndIndex,
|
|
82
|
+
emitter: symbol,
|
|
83
|
+
): void;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
type SyncEventName = typeof TOOLTIP_SYNC_EVENT | typeof BRUSH_SYNC_EVENT;
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* The cross-chart synchronisation bus. Mirrors the `on`/`off`/`emit` surface of
|
|
90
|
+
* recharts' mitt `eventCenter` so synchronisation logic and tests read 1:1, but
|
|
91
|
+
* is a plain synchronous emitter with no reactive graph of its own.
|
|
92
|
+
*
|
|
93
|
+
* The event-name argument comes first (`on(TOOLTIP_SYNC_EVENT, …)`) for 1:1
|
|
94
|
+
* parity with recharts' eventCenter call sites and the vendored specs. The
|
|
95
|
+
* shared implementations narrow on `eventName`; TypeScript can't co-narrow the
|
|
96
|
+
* listener/payload param from that runtime check, so each branch keeps one
|
|
97
|
+
* localized assertion (the repo's convention for unavoidable narrowing).
|
|
98
|
+
*/
|
|
99
|
+
export const syncEventCenter: SyncEventCenter = {
|
|
100
|
+
on(eventName: SyncEventName, listener: AnyListener): void {
|
|
101
|
+
if (eventName === TOOLTIP_SYNC_EVENT) {
|
|
102
|
+
// eslint-disable-next-line typescript/consistent-type-assertions -- narrowed by eventName
|
|
103
|
+
tooltipListeners.add(listener as TooltipSyncListener);
|
|
104
|
+
} else {
|
|
105
|
+
// eslint-disable-next-line typescript/consistent-type-assertions -- narrowed by eventName
|
|
106
|
+
brushListeners.add(listener as BrushSyncListener);
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
off(eventName: SyncEventName, listener: AnyListener): void {
|
|
110
|
+
if (eventName === TOOLTIP_SYNC_EVENT) {
|
|
111
|
+
// eslint-disable-next-line typescript/consistent-type-assertions -- narrowed by eventName
|
|
112
|
+
tooltipListeners.delete(listener as TooltipSyncListener);
|
|
113
|
+
} else {
|
|
114
|
+
// eslint-disable-next-line typescript/consistent-type-assertions -- narrowed by eventName
|
|
115
|
+
brushListeners.delete(listener as BrushSyncListener);
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
emit(eventName: SyncEventName, syncId: SyncId, payload: AnyPayload, emitter: symbol): void {
|
|
119
|
+
if (eventName === TOOLTIP_SYNC_EVENT) {
|
|
120
|
+
for (const listener of snapshot(tooltipListeners)) {
|
|
121
|
+
// eslint-disable-next-line typescript/consistent-type-assertions -- narrowed by eventName
|
|
122
|
+
listener(syncId, payload as TooltipSyncState, emitter);
|
|
123
|
+
}
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
for (const listener of snapshot(brushListeners)) {
|
|
127
|
+
// eslint-disable-next-line typescript/consistent-type-assertions -- narrowed by eventName
|
|
128
|
+
listener(syncId, payload as BrushStartEndIndex, emitter);
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Ported from recharts 3.8.1 src/synchronisation/syncSelectors.ts (commit 7a23854).
|
|
2
|
+
import { RechartsRootState } from "../state/store";
|
|
3
|
+
import { TooltipSyncState } from "../state/tooltipSlice";
|
|
4
|
+
|
|
5
|
+
export function selectSynchronisedTooltipState(state: RechartsRootState): TooltipSyncState {
|
|
6
|
+
return state.tooltip.syncInteraction;
|
|
7
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// Ported from recharts 3.8.1 src/synchronisation/types.ts (commit 7a23854).
|
|
2
|
+
// Canonical home for SyncMethod (util/types re-exports it; the earlier seed there
|
|
3
|
+
// is now re-homed here). Deviation: `DataKey<any>` → `DataKey<unknown>` (no any).
|
|
4
|
+
import { Coordinate, DataKey, TickItem } from "../util/types";
|
|
5
|
+
import { TooltipIndex } from "../state/tooltipSlice";
|
|
6
|
+
|
|
7
|
+
export type ActiveLabel = string | number | undefined;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Despite the name, this type is used for all event types, not just mouse events.
|
|
11
|
+
*/
|
|
12
|
+
export type MouseHandlerDataParam = {
|
|
13
|
+
/**
|
|
14
|
+
* Index of the active tick in the current chart. Only works with number-indexed
|
|
15
|
+
* one-dimensional data charts (Line, Area, Bar, Pie, …), not two-dimensional
|
|
16
|
+
* ones (Treemap, Sankey) — though one day it will, hence the TooltipIndex type.
|
|
17
|
+
*/
|
|
18
|
+
activeTooltipIndex: number | TooltipIndex | undefined;
|
|
19
|
+
isTooltipActive: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Exactly the same as activeTooltipIndex — duplicated in recharts@2 too, kept
|
|
22
|
+
* for backwards compatibility.
|
|
23
|
+
*/
|
|
24
|
+
activeIndex: number | TooltipIndex | undefined;
|
|
25
|
+
/** The category or domain value of the active tooltip entry. */
|
|
26
|
+
activeLabel: ActiveLabel;
|
|
27
|
+
activeDataKey: DataKey<unknown> | undefined;
|
|
28
|
+
activeCoordinate: Coordinate | undefined;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Customises how charts synchronize tooltips and brushes. Default: `index`.
|
|
33
|
+
*
|
|
34
|
+
* - `index`: other charts reuse the current datum's index within the data array.
|
|
35
|
+
* - `value`: try to match other charts' values.
|
|
36
|
+
* - custom function: receives the current chart's ticks and the other chart's
|
|
37
|
+
* active tooltip state, and returns the active tick index in the current chart.
|
|
38
|
+
*/
|
|
39
|
+
export type SyncMethod =
|
|
40
|
+
| "index"
|
|
41
|
+
| "value"
|
|
42
|
+
| ((ticks: ReadonlyArray<TickItem>, data: MouseHandlerDataParam) => number);
|
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
// Ported from recharts 3.8.1 src/synchronisation/useChartSynchronisation.tsx
|
|
2
|
+
// (commit 7a23854) to Solid 2.0.
|
|
3
|
+
//
|
|
4
|
+
// recharts wires three React `useEffect`s onto the mitt `eventCenter`:
|
|
5
|
+
// - emit a TOOLTIP_SYNC_EVENT whenever the local active tooltip changes,
|
|
6
|
+
// - listen for TOOLTIP_SYNC_EVENTs from OTHER charts and project them onto this
|
|
7
|
+
// chart's axes per `syncMethod`,
|
|
8
|
+
// - the same pair for brush start/end indexes.
|
|
9
|
+
// The Solid port keeps the exact same semantics but over `syncEventCenter`
|
|
10
|
+
// (`syncRegistry.ts`, a plain synchronous bus) and Solid `createEffect`s.
|
|
11
|
+
//
|
|
12
|
+
// Reactivity notes (diagnostics-clean):
|
|
13
|
+
// - Each effect uses the two-arg `createEffect(deps, effect)` form: the first
|
|
14
|
+
// function tracks the reactive inputs and returns them as a tuple, the second
|
|
15
|
+
// runs the side effect (subscribe/emit). Reads inside the side-effect callback
|
|
16
|
+
// are therefore not tracked, and we never write a *local* signal there — emits
|
|
17
|
+
// only call OTHER charts' batched store setters via the registry, which is the
|
|
18
|
+
// sanctioned cross-store write path (no SIGNAL_WRITE_IN_OWNED_SCOPE).
|
|
19
|
+
// - The listener calls `store.actions.tooltip.setSyncInteraction(...)` +
|
|
20
|
+
// `flush()` on the RECEIVING chart's store; that store is a different owner, so
|
|
21
|
+
// the write is not "in an owned computation" of the emitting effect.
|
|
22
|
+
import { createEffect, flush, untrack } from "solid-js";
|
|
23
|
+
import { useAppStore } from "../state/hooks";
|
|
24
|
+
import {
|
|
25
|
+
selectEventEmitter,
|
|
26
|
+
selectSyncId,
|
|
27
|
+
selectSyncMethod,
|
|
28
|
+
} from "../state/selectors/rootPropsSelectors";
|
|
29
|
+
import {
|
|
30
|
+
selectActiveTooltipGraphicalItemId,
|
|
31
|
+
selectTooltipAxisTicks,
|
|
32
|
+
selectTooltipDataKey,
|
|
33
|
+
} from "../state/selectors/tooltipSelectors";
|
|
34
|
+
import { selectChartLayout, useViewBox } from "../context/chartLayoutContext";
|
|
35
|
+
import { Coordinate, TickItem, TooltipEventType } from "../util/types";
|
|
36
|
+
import { TooltipTrigger } from "../chart/types";
|
|
37
|
+
import { TooltipIndex, TooltipSyncState } from "../state/tooltipSlice";
|
|
38
|
+
import { ActiveLabel, MouseHandlerDataParam } from "./types";
|
|
39
|
+
import { BrushStartEndIndex } from "../context/brushUpdateContext";
|
|
40
|
+
import { BRUSH_SYNC_EVENT, SyncId, TOOLTIP_SYNC_EVENT, syncEventCenter } from "./syncRegistry";
|
|
41
|
+
import type { RechartsStore } from "../state/store";
|
|
42
|
+
|
|
43
|
+
const inactiveSyncState: TooltipSyncState = {
|
|
44
|
+
active: false,
|
|
45
|
+
coordinate: undefined,
|
|
46
|
+
dataKey: undefined,
|
|
47
|
+
index: null,
|
|
48
|
+
label: undefined,
|
|
49
|
+
sourceViewBox: undefined,
|
|
50
|
+
graphicalItemId: undefined,
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Listens for tooltip sync events from other charts and writes the appropriate
|
|
55
|
+
* sync interaction state based on this chart's `syncMethod`. Mirrors recharts'
|
|
56
|
+
* `useTooltipSyncEventsListener` 1:1.
|
|
57
|
+
*/
|
|
58
|
+
function useTooltipSyncEventsListener(store: RechartsStore): void {
|
|
59
|
+
const viewBox = useViewBox();
|
|
60
|
+
|
|
61
|
+
createEffect(
|
|
62
|
+
() => {
|
|
63
|
+
const mySyncId = selectSyncId(store.state);
|
|
64
|
+
const myEventEmitter = selectEventEmitter(store.state);
|
|
65
|
+
const syncMethod = selectSyncMethod(store.state);
|
|
66
|
+
const tooltipTicks = selectTooltipAxisTicks(store.state);
|
|
67
|
+
const layout = selectChartLayout(store.state);
|
|
68
|
+
const box = viewBox();
|
|
69
|
+
return { mySyncId, myEventEmitter, syncMethod, tooltipTicks, layout, box };
|
|
70
|
+
},
|
|
71
|
+
({ mySyncId, myEventEmitter, syncMethod, tooltipTicks, layout, box }) => {
|
|
72
|
+
if (mySyncId == null) {
|
|
73
|
+
// Not synchronised with any other chart — nothing to listen for.
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const listener = (
|
|
78
|
+
incomingSyncId: SyncId,
|
|
79
|
+
payload: TooltipSyncState,
|
|
80
|
+
emitter: symbol,
|
|
81
|
+
): void => {
|
|
82
|
+
if (myEventEmitter === emitter) {
|
|
83
|
+
// Don't react to our own emissions.
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
if (mySyncId !== incomingSyncId) {
|
|
87
|
+
// Not for this chart.
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Source deactivation (mouseLeave) clears state for ALL sync methods,
|
|
92
|
+
// including sourceViewBox so emission can resume.
|
|
93
|
+
if (payload.active === false) {
|
|
94
|
+
store.actions.tooltip.setSyncInteraction(inactiveSyncState);
|
|
95
|
+
flush();
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (syncMethod === "index") {
|
|
100
|
+
if (box && payload.coordinate && payload.sourceViewBox) {
|
|
101
|
+
const { coordinate } = payload;
|
|
102
|
+
const { x, y } = coordinate;
|
|
103
|
+
const {
|
|
104
|
+
x: sourceX,
|
|
105
|
+
y: sourceY,
|
|
106
|
+
width: sourceWidth,
|
|
107
|
+
height: sourceHeight,
|
|
108
|
+
} = payload.sourceViewBox;
|
|
109
|
+
const scaledCoordinate: Coordinate = {
|
|
110
|
+
...coordinate,
|
|
111
|
+
x: box.x + (sourceWidth ? (x - sourceX) / sourceWidth : 0) * box.width,
|
|
112
|
+
y: box.y + (sourceHeight ? (y - sourceY) / sourceHeight : 0) * box.height,
|
|
113
|
+
};
|
|
114
|
+
store.actions.tooltip.setSyncInteraction({
|
|
115
|
+
...payload,
|
|
116
|
+
coordinate: scaledCoordinate,
|
|
117
|
+
});
|
|
118
|
+
} else {
|
|
119
|
+
store.actions.tooltip.setSyncInteraction(payload);
|
|
120
|
+
}
|
|
121
|
+
flush();
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (tooltipTicks == null) {
|
|
126
|
+
// 'value'/function need ticks.
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
let activeTick: TickItem | undefined;
|
|
131
|
+
if (typeof syncMethod === "function") {
|
|
132
|
+
const syncMethodParam: MouseHandlerDataParam = {
|
|
133
|
+
activeTooltipIndex: payload.index == null ? undefined : Number(payload.index),
|
|
134
|
+
isTooltipActive: payload.active,
|
|
135
|
+
activeIndex: payload.index == null ? undefined : Number(payload.index),
|
|
136
|
+
activeLabel: payload.label,
|
|
137
|
+
activeDataKey: payload.dataKey,
|
|
138
|
+
activeCoordinate: payload.coordinate,
|
|
139
|
+
};
|
|
140
|
+
const activeTooltipIndex = syncMethod(tooltipTicks, syncMethodParam);
|
|
141
|
+
activeTick = tooltipTicks[activeTooltipIndex];
|
|
142
|
+
} else if (syncMethod === "value") {
|
|
143
|
+
activeTick = tooltipTicks.find((tick) => String(tick.value) === payload.label);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const { coordinate } = payload;
|
|
147
|
+
if (coordinate == null || box == null) {
|
|
148
|
+
store.actions.tooltip.setSyncInteraction(inactiveSyncState);
|
|
149
|
+
flush();
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (activeTick == null) {
|
|
154
|
+
// No matching tick (sparse data): hide locally but KEEP sourceViewBox so
|
|
155
|
+
// the emission guard still sees us as "receiving" (no counter-cascade).
|
|
156
|
+
store.actions.tooltip.setSyncInteraction({
|
|
157
|
+
...inactiveSyncState,
|
|
158
|
+
sourceViewBox: payload.sourceViewBox,
|
|
159
|
+
});
|
|
160
|
+
flush();
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const validateChartX = Math.min(coordinate.x, box.x + box.width);
|
|
165
|
+
const validateChartY = Math.min(coordinate.y, box.y + box.height);
|
|
166
|
+
const activeCoordinate: Coordinate = {
|
|
167
|
+
x: layout === "horizontal" ? activeTick.coordinate : validateChartX,
|
|
168
|
+
y: layout === "horizontal" ? validateChartY : activeTick.coordinate,
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
store.actions.tooltip.setSyncInteraction({
|
|
172
|
+
active: payload.active,
|
|
173
|
+
coordinate: activeCoordinate,
|
|
174
|
+
dataKey: payload.dataKey,
|
|
175
|
+
index: String(activeTick.index),
|
|
176
|
+
label: payload.label,
|
|
177
|
+
sourceViewBox: payload.sourceViewBox,
|
|
178
|
+
graphicalItemId: payload.graphicalItemId,
|
|
179
|
+
});
|
|
180
|
+
flush();
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
syncEventCenter.on(TOOLTIP_SYNC_EVENT, listener);
|
|
184
|
+
// The effect (apply) callback is a leaf scope — return cleanup, don't call
|
|
185
|
+
// onCleanup (which would warn NO_OWNER_CLEANUP). Runs before the next apply.
|
|
186
|
+
return () => {
|
|
187
|
+
syncEventCenter.off(TOOLTIP_SYNC_EVENT, listener);
|
|
188
|
+
};
|
|
189
|
+
},
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Listens for brush sync events from other charts and keeps this chart's data
|
|
195
|
+
* start/end indexes in step. Mirrors recharts' `useBrushSyncEventsListener`.
|
|
196
|
+
*/
|
|
197
|
+
function useBrushSyncEventsListener(store: RechartsStore): void {
|
|
198
|
+
createEffect(
|
|
199
|
+
() => {
|
|
200
|
+
const mySyncId = selectSyncId(store.state);
|
|
201
|
+
const myEventEmitter = selectEventEmitter(store.state);
|
|
202
|
+
return { mySyncId, myEventEmitter };
|
|
203
|
+
},
|
|
204
|
+
({ mySyncId, myEventEmitter }) => {
|
|
205
|
+
if (mySyncId == null) {
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
const listener = (
|
|
209
|
+
incomingSyncId: SyncId,
|
|
210
|
+
payload: BrushStartEndIndex,
|
|
211
|
+
emitter: symbol,
|
|
212
|
+
): void => {
|
|
213
|
+
if (myEventEmitter === emitter) {
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
if (mySyncId === incomingSyncId) {
|
|
217
|
+
store.actions.chartData.setDataStartEndIndexes(payload);
|
|
218
|
+
flush();
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
syncEventCenter.on(BRUSH_SYNC_EVENT, listener);
|
|
222
|
+
return () => {
|
|
223
|
+
syncEventCenter.off(BRUSH_SYNC_EVENT, listener);
|
|
224
|
+
};
|
|
225
|
+
},
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Wires this chart up to RECEIVE synchronisation events from other charts.
|
|
231
|
+
* Creates the chart's event-emitter symbol (used to ignore its own emissions)
|
|
232
|
+
* and registers the tooltip + brush listeners. No-op outside a chart.
|
|
233
|
+
*/
|
|
234
|
+
export function useSynchronisedEventsFromOtherCharts(): void {
|
|
235
|
+
const store = useAppStore();
|
|
236
|
+
if (store == null) {
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
// recharts dispatches `createEventEmitter` from a useEffect; do the same via the
|
|
240
|
+
// two-arg createEffect (the effect callback runs in the effect phase, NOT the
|
|
241
|
+
// owned component scope — a direct setup-time write trips SIGNAL_WRITE_IN_OWNED
|
|
242
|
+
// _SCOPE). Effects flush in creation order, so the symbol is set before the
|
|
243
|
+
// emit effect (created later, in the Tooltip) first runs.
|
|
244
|
+
createEffect(
|
|
245
|
+
() => undefined,
|
|
246
|
+
() => store.actions.options.createEventEmitter(),
|
|
247
|
+
);
|
|
248
|
+
useTooltipSyncEventsListener(store);
|
|
249
|
+
useBrushSyncEventsListener(store);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* EMITS tooltip sync events to other charts when this chart's active tooltip
|
|
254
|
+
* changes. Mirrors recharts' `useTooltipChartSynchronisation`.
|
|
255
|
+
*
|
|
256
|
+
* Emission is suppressed while `isReceivingSynchronisation` (a non-null
|
|
257
|
+
* `sourceViewBox` on the local sync state) to avoid feedback loops / cascading
|
|
258
|
+
* tooltip clears across charts with mismatched data.
|
|
259
|
+
*
|
|
260
|
+
* @param tooltipEventType resolved by the Tooltip
|
|
261
|
+
* @param trigger resolved by the Tooltip
|
|
262
|
+
* @param activeCoordinate from local interaction state
|
|
263
|
+
* @param activeLabel from local interaction state
|
|
264
|
+
* @param activeIndex from local interaction state
|
|
265
|
+
* @param isTooltipActive from local interaction state
|
|
266
|
+
*/
|
|
267
|
+
export function useTooltipChartSynchronisation(
|
|
268
|
+
tooltipEventType: () => TooltipEventType | undefined,
|
|
269
|
+
trigger: () => TooltipTrigger,
|
|
270
|
+
activeCoordinate: () => Coordinate | undefined,
|
|
271
|
+
activeLabel: () => ActiveLabel,
|
|
272
|
+
activeIndex: () => TooltipIndex | undefined,
|
|
273
|
+
isTooltipActive: () => boolean,
|
|
274
|
+
): void {
|
|
275
|
+
const store = useAppStore();
|
|
276
|
+
if (store == null) {
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
const viewBox = useViewBox();
|
|
280
|
+
|
|
281
|
+
// recharts dedupes via React's referential effect-dep comparison; its viewBox
|
|
282
|
+
// memo is reference-stable across renders. Here `selectChartViewBox` returns a
|
|
283
|
+
// fresh object each compute, so the effect can re-run with an unchanged payload
|
|
284
|
+
// — guard against emitting an identical sync state twice in a row.
|
|
285
|
+
let lastEmitted: string | undefined;
|
|
286
|
+
|
|
287
|
+
createEffect(
|
|
288
|
+
() => {
|
|
289
|
+
// Build the *plain* (snapshotted) payload in the COMPUTE phase, where store
|
|
290
|
+
// reads track and STRICT_READ_UNTRACKED doesn't apply. The apply phase then
|
|
291
|
+
// only emits — it never reads store proxies (which would warn).
|
|
292
|
+
const eventEmitterSymbol = selectEventEmitter(store.state);
|
|
293
|
+
const syncId = selectSyncId(store.state);
|
|
294
|
+
const tooltipState = store.state.tooltip.syncInteraction;
|
|
295
|
+
// sourceViewBox (not `active`) flags that we're currently RECEIVING sync.
|
|
296
|
+
const isReceivingSynchronisation = tooltipState.sourceViewBox != null;
|
|
297
|
+
|
|
298
|
+
const box = viewBox();
|
|
299
|
+
const rawCoordinate = activeCoordinate();
|
|
300
|
+
const rawLabel = activeLabel();
|
|
301
|
+
const payload: TooltipSyncState = {
|
|
302
|
+
active: isTooltipActive(),
|
|
303
|
+
coordinate: rawCoordinate == null ? undefined : { ...rawCoordinate },
|
|
304
|
+
dataKey: selectTooltipDataKey(store.state, tooltipEventType(), trigger()),
|
|
305
|
+
index: activeIndex() ?? null,
|
|
306
|
+
label: typeof rawLabel === "number" ? String(rawLabel) : rawLabel,
|
|
307
|
+
sourceViewBox: box == null ? undefined : { ...box },
|
|
308
|
+
graphicalItemId: selectActiveTooltipGraphicalItemId(store.state),
|
|
309
|
+
};
|
|
310
|
+
return { eventEmitterSymbol, syncId, isReceivingSynchronisation, payload };
|
|
311
|
+
},
|
|
312
|
+
({ eventEmitterSymbol, syncId, isReceivingSynchronisation, payload }) => {
|
|
313
|
+
if (isReceivingSynchronisation) {
|
|
314
|
+
// Receiving sync — don't echo events back out.
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
if (syncId == null) {
|
|
318
|
+
// Not synchronised.
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
if (eventEmitterSymbol == null) {
|
|
322
|
+
// Used outside a chart context — bail silently.
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
// Dedupe identical consecutive emissions (see lastEmitted note above). The
|
|
326
|
+
// payload is already a plain snapshot, so stringifying it here is safe.
|
|
327
|
+
const fingerprint = JSON.stringify(payload);
|
|
328
|
+
if (fingerprint === lastEmitted) {
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
lastEmitted = fingerprint;
|
|
332
|
+
syncEventCenter.emit(TOOLTIP_SYNC_EVENT, syncId, payload, eventEmitterSymbol);
|
|
333
|
+
},
|
|
334
|
+
);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* EMITS brush sync events to other charts when the brush start/end indexes
|
|
339
|
+
* change. Mirrors recharts' `useBrushChartSynchronisation`.
|
|
340
|
+
*/
|
|
341
|
+
export function useBrushChartSynchronisation(): void {
|
|
342
|
+
const store = useAppStore();
|
|
343
|
+
if (store == null) {
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
createEffect(
|
|
347
|
+
() => {
|
|
348
|
+
const syncId = selectSyncId(store.state);
|
|
349
|
+
const eventEmitterSymbol = selectEventEmitter(store.state);
|
|
350
|
+
const brushStartIndex = store.state.chartData.dataStartIndex;
|
|
351
|
+
const brushEndIndex = store.state.chartData.dataEndIndex;
|
|
352
|
+
return { syncId, eventEmitterSymbol, brushStartIndex, brushEndIndex };
|
|
353
|
+
},
|
|
354
|
+
({ syncId, eventEmitterSymbol, brushStartIndex, brushEndIndex }) => {
|
|
355
|
+
if (
|
|
356
|
+
syncId == null ||
|
|
357
|
+
brushStartIndex == null ||
|
|
358
|
+
brushEndIndex == null ||
|
|
359
|
+
eventEmitterSymbol == null
|
|
360
|
+
) {
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
const payload: BrushStartEndIndex = {
|
|
364
|
+
startIndex: brushStartIndex,
|
|
365
|
+
endIndex: brushEndIndex,
|
|
366
|
+
};
|
|
367
|
+
untrack(() => {
|
|
368
|
+
syncEventCenter.emit(BRUSH_SYNC_EVENT, syncId, payload, eventEmitterSymbol);
|
|
369
|
+
});
|
|
370
|
+
},
|
|
371
|
+
);
|
|
372
|
+
}
|