@solidports/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/LICENSE +22 -0
- package/NOTICE +19 -0
- package/README.md +102 -0
- package/dist/dev.js +28564 -0
- package/dist/index.d.ts +7859 -0
- package/dist/index.js +28546 -0
- package/package.json +98 -0
- package/src/animation/AnimatedItems.tsx +183 -0
- package/src/animation/AnimationController.ts +33 -0
- package/src/animation/AnimationControllerImpl.ts +36 -0
- package/src/animation/AnimationHandle.ts +307 -0
- package/src/animation/CSSTransitionAnimate.tsx +170 -0
- package/src/animation/JavascriptAnimate.tsx +119 -0
- package/src/animation/easing.ts +221 -0
- package/src/animation/matchBy.ts +164 -0
- package/src/animation/timeoutController.ts +70 -0
- package/src/animation/useAnimationController.tsx +34 -0
- package/src/animation/useAnimationStartSnapshot.ts +118 -0
- package/src/animation/util.ts +41 -0
- package/src/cartesian/Area.tsx +915 -0
- package/src/cartesian/AreaRevealShape.tsx +190 -0
- package/src/cartesian/Bar.tsx +1369 -0
- package/src/cartesian/BarStack.tsx +152 -0
- package/src/cartesian/Brush.tsx +951 -0
- package/src/cartesian/CartesianAxis.tsx +722 -0
- package/src/cartesian/CartesianGrid.tsx +711 -0
- package/src/cartesian/ErrorBar.tsx +361 -0
- package/src/cartesian/Funnel.tsx +803 -0
- package/src/cartesian/GraphicalItemClipPath.tsx +67 -0
- package/src/cartesian/Line.tsx +863 -0
- package/src/cartesian/LineDrawShape.tsx +89 -0
- package/src/cartesian/ReferenceArea.tsx +331 -0
- package/src/cartesian/ReferenceDot.tsx +304 -0
- package/src/cartesian/ReferenceLine.tsx +474 -0
- package/src/cartesian/Scatter.tsx +888 -0
- package/src/cartesian/XAxis.tsx +433 -0
- package/src/cartesian/YAxis.tsx +443 -0
- package/src/cartesian/ZAxis.tsx +155 -0
- package/src/cartesian/cartesianPositionToCSSTranslate.tsx +29 -0
- package/src/cartesian/cartesianViewBoxToTrapezoid.tsx +21 -0
- package/src/cartesian/getCartesianPosition.tsx +267 -0
- package/src/cartesian/getEquidistantTicks.ts +144 -0
- package/src/cartesian/getTicks.ts +225 -0
- package/src/cartesian/isOutsidePosition.ts +15 -0
- package/src/cartesian/useAnimatedLineLength.ts +54 -0
- package/src/chart/AreaChart.tsx +29 -0
- package/src/chart/BarChart.tsx +29 -0
- package/src/chart/CartesianChart.tsx +131 -0
- package/src/chart/CategoricalChart.tsx +94 -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 +50 -0
- package/src/chart/PolarChart.tsx +164 -0
- package/src/chart/RadarChart.tsx +70 -0
- package/src/chart/RadialBarChart.tsx +46 -0
- package/src/chart/RechartsWrapper.tsx +551 -0
- package/src/chart/Sankey.tsx +1534 -0
- package/src/chart/ScatterChart.tsx +29 -0
- package/src/chart/SunburstChart.tsx +504 -0
- package/src/chart/Treemap.tsx +1223 -0
- package/src/chart/createInitialRootProps.ts +24 -0
- package/src/chart/types.ts +53 -0
- package/src/component/ActivePoints.tsx +144 -0
- package/src/component/Cell.tsx +37 -0
- package/src/component/Cursor.tsx +185 -0
- package/src/component/Customized.tsx +50 -0
- package/src/component/DefaultLegendContent.tsx +348 -0
- package/src/component/DefaultTooltipContent.tsx +224 -0
- package/src/component/Dots.tsx +157 -0
- package/src/component/Label.tsx +636 -0
- package/src/component/LabelList.tsx +375 -0
- package/src/component/Legend.tsx +512 -0
- package/src/component/ResponsiveContainer.tsx +348 -0
- package/src/component/Text.tsx +541 -0
- package/src/component/Tooltip.tsx +470 -0
- package/src/component/TooltipBoundingBox.tsx +146 -0
- package/src/component/responsiveContainerUtils.ts +134 -0
- package/src/container/ClipPathProvider.tsx +51 -0
- package/src/container/Layer.tsx +38 -0
- package/src/container/RootSurface.tsx +120 -0
- package/src/container/Surface.tsx +61 -0
- package/src/context/CellsContext.tsx +54 -0
- package/src/context/ErrorBarContext.tsx +146 -0
- package/src/context/GraphicalItemChildrenScope.tsx +18 -0
- package/src/context/PanoramaContext.tsx +9 -0
- package/src/context/RegisterGraphicalItemId.tsx +30 -0
- package/src/context/accessibilityContext.tsx +6 -0
- package/src/context/brushUpdateContext.tsx +9 -0
- package/src/context/chartDataContext.tsx +97 -0
- package/src/context/chartLayoutContext.tsx +201 -0
- package/src/context/legendPayloadContext.tsx +20 -0
- package/src/context/legendPortalContext.tsx +12 -0
- package/src/context/tooltipContext.tsx +89 -0
- package/src/context/tooltipPortalContext.tsx +12 -0
- package/src/context/useTooltipAxis.ts +22 -0
- package/src/hooks.ts +476 -0
- package/src/index.ts +280 -0
- package/src/polar/Pie.tsx +1360 -0
- package/src/polar/PolarAngleAxis.tsx +616 -0
- package/src/polar/PolarGrid.tsx +312 -0
- package/src/polar/PolarRadiusAxis.tsx +547 -0
- package/src/polar/Radar.tsx +734 -0
- package/src/polar/RadialBar.tsx +917 -0
- package/src/polar/defaultPolarAngleAxisProps.tsx +27 -0
- package/src/polar/defaultPolarRadiusAxisProps.tsx +25 -0
- package/src/shape/Cross.tsx +89 -0
- package/src/shape/Curve.tsx +343 -0
- package/src/shape/Dot.tsx +70 -0
- package/src/shape/Polygon.tsx +195 -0
- package/src/shape/Rectangle.tsx +470 -0
- package/src/shape/Sector.tsx +347 -0
- package/src/shape/Symbols.tsx +139 -0
- package/src/shape/Trapezoid.tsx +280 -0
- package/src/state/RechartsStateContext.tsx +12 -0
- package/src/state/RechartsStateProvider.tsx +87 -0
- package/src/state/RechartsStoreContext.tsx +25 -0
- package/src/state/RechartsStoreProvider.tsx +35 -0
- package/src/state/ReportChartProps.tsx +40 -0
- package/src/state/ReportEventSettings.tsx +30 -0
- package/src/state/ReportMainChartProps.tsx +61 -0
- package/src/state/ReportPolarOptions.tsx +35 -0
- package/src/state/SetGraphicalItem.ts +79 -0
- package/src/state/SetLegendPayload.ts +134 -0
- package/src/state/SetTooltipEntrySettings.tsx +72 -0
- package/src/state/actions.ts +464 -0
- package/src/state/brushSlice.ts +13 -0
- package/src/state/cartesianAxisSlice.ts +141 -0
- package/src/state/chartDataSlice.ts +50 -0
- package/src/state/chartState.ts +297 -0
- package/src/state/errorBarSlice.ts +29 -0
- package/src/state/eventSettingsSlice.ts +8 -0
- package/src/state/events.ts +76 -0
- package/src/state/externalEventsMiddleware.ts +255 -0
- package/src/state/graphicalItemsSlice.ts +74 -0
- package/src/state/hooks/useChartSelectors.tsx +45 -0
- package/src/state/keyboardEventsMiddleware.ts +228 -0
- package/src/state/layoutSlice.ts +21 -0
- package/src/state/legendSlice.ts +57 -0
- package/src/state/mouseEventsMiddleware.ts +185 -0
- package/src/state/optionsSlice.ts +47 -0
- package/src/state/polarAxisSlice.ts +10 -0
- package/src/state/polarOptionsSlice.ts +12 -0
- package/src/state/rawData.ts +26 -0
- package/src/state/referenceElementsSlice.ts +40 -0
- package/src/state/renderedTicksSlice.ts +15 -0
- package/src/state/rootPropsSlice.ts +47 -0
- package/src/state/selectors/areaSelectors.ts +240 -0
- package/src/state/selectors/arrayEqualityCheck.ts +29 -0
- package/src/state/selectors/axisSelectors.ts +2157 -0
- package/src/state/selectors/barSelectors.ts +310 -0
- package/src/state/selectors/barStackSelectors.ts +77 -0
- package/src/state/selectors/brushSelectors.ts +33 -0
- package/src/state/selectors/chartSelector.ts +185 -0
- package/src/state/selectors/combiners/combineActiveLabel.ts +16 -0
- package/src/state/selectors/combiners/combineActiveTooltipIndex.ts +95 -0
- package/src/state/selectors/combiners/combineAllBarPositions.ts +122 -0
- package/src/state/selectors/combiners/combineAxisRangeWithReverse.ts +16 -0
- package/src/state/selectors/combiners/combineBarPosition.ts +23 -0
- package/src/state/selectors/combiners/combineBarSizeList.ts +80 -0
- package/src/state/selectors/combiners/combineCheckedDomain.ts +48 -0
- package/src/state/selectors/combiners/combineConfiguredScale.ts +111 -0
- package/src/state/selectors/combiners/combineCoordinateForDefaultIndex.ts +45 -0
- package/src/state/selectors/combiners/combineDisplayedStackedData.ts +50 -0
- package/src/state/selectors/combiners/combineInverseScaleFunction.ts +16 -0
- package/src/state/selectors/combiners/combineRealScaleType.ts +44 -0
- package/src/state/selectors/combiners/combineStackedData.ts +27 -0
- package/src/state/selectors/combiners/combineTooltipInteractionState.ts +86 -0
- package/src/state/selectors/combiners/combineTooltipPayload.ts +205 -0
- package/src/state/selectors/combiners/combineTooltipPayloadConfigurations.ts +58 -0
- package/src/state/selectors/containerSelectors.ts +12 -0
- package/src/state/selectors/dataSelectors.ts +88 -0
- package/src/state/selectors/funnelSelectors.ts +75 -0
- package/src/state/selectors/graphicalItemSelectors.ts +30 -0
- package/src/state/selectors/legendSelectors.ts +29 -0
- package/src/state/selectors/lineSelectors.ts +134 -0
- package/src/state/selectors/numberDomainEqualityCheck.ts +14 -0
- package/src/state/selectors/pickAxisId.ts +5 -0
- package/src/state/selectors/pickAxisType.ts +3 -0
- package/src/state/selectors/pieSelectors.ts +97 -0
- package/src/state/selectors/polarAxisSelectors.ts +201 -0
- package/src/state/selectors/polarGridSelectors.ts +28 -0
- package/src/state/selectors/polarScaleSelectors.ts +133 -0
- package/src/state/selectors/polarSelectors.ts +219 -0
- package/src/state/selectors/radarSelectors.ts +191 -0
- package/src/state/selectors/radialBarSelectors.ts +435 -0
- package/src/state/selectors/rootPropsSelectors.ts +25 -0
- package/src/state/selectors/scatterSelectors.ts +96 -0
- package/src/state/selectors/selectActivePropsFromChartPointer.ts +26 -0
- package/src/state/selectors/selectAllAxes.ts +17 -0
- package/src/state/selectors/selectChartOffset.ts +16 -0
- package/src/state/selectors/selectChartOffsetInternal.ts +136 -0
- package/src/state/selectors/selectLegendArea.ts +20 -0
- package/src/state/selectors/selectPlotArea.ts +22 -0
- package/src/state/selectors/selectTooltipAxisId.ts +7 -0
- package/src/state/selectors/selectTooltipAxisType.ts +32 -0
- package/src/state/selectors/selectTooltipEventType.ts +48 -0
- package/src/state/selectors/selectTooltipPayloadSearcher.ts +6 -0
- package/src/state/selectors/selectTooltipSettings.ts +39 -0
- package/src/state/selectors/selectTooltipState.ts +8 -0
- package/src/state/selectors/selectors.ts +271 -0
- package/src/state/selectors/tooltipSelectors.ts +578 -0
- package/src/state/selectors/touchSelectors.ts +31 -0
- package/src/state/store.ts +29 -0
- package/src/state/storeIdentity.ts +9 -0
- package/src/state/teardownWrite.ts +10 -0
- package/src/state/tooltipInteraction.ts +23 -0
- package/src/state/tooltipSlice.ts +334 -0
- package/src/state/touchEventsMiddleware.ts +214 -0
- package/src/state/types/AnimationSettings.ts +20 -0
- package/src/state/types/AreaSettings.ts +14 -0
- package/src/state/types/BarSettings.ts +15 -0
- package/src/state/types/LineSettings.ts +9 -0
- package/src/state/types/PieSettings.ts +34 -0
- package/src/state/types/RadarSettings.ts +5 -0
- package/src/state/types/RadialBarSettings.ts +10 -0
- package/src/state/types/ScatterSettings.ts +12 -0
- package/src/state/types/StackedGraphicalItem.ts +34 -0
- package/src/state/useChartState.ts +17 -0
- package/src/state/zIndexSlice.ts +39 -0
- package/src/synchronisation/syncSelectors.ts +7 -0
- package/src/synchronisation/types.ts +44 -0
- package/src/synchronisation/useChartSynchronisation.tsx +404 -0
- package/src/theme/RechartsTheme.ts +16 -0
- package/src/theme/RechartsThemeContext.ts +19 -0
- package/src/theme/darkTheme.ts +13 -0
- package/src/theme/graphicalItemIdentity.ts +70 -0
- package/src/theme/legacyTheme.ts +17 -0
- package/src/theme/lightTheme.ts +13 -0
- package/src/types.ts +54 -0
- package/src/util/ActiveShapeUtils.tsx +162 -0
- package/src/util/BarUtils.tsx +62 -0
- package/src/util/BarePortal.tsx +50 -0
- package/src/util/CamelCaseSVGAttrs.ts +34 -0
- package/src/util/CartesianUtils.ts +48 -0
- package/src/util/ChartUtils.ts +802 -0
- package/src/util/Constants.ts +42 -0
- package/src/util/CssPrefixUtils.ts +20 -0
- package/src/util/DOMUtils.ts +129 -0
- package/src/util/DataUtils.ts +216 -0
- package/src/util/Events.ts +16 -0
- package/src/util/FunnelUtils.tsx +15 -0
- package/src/util/Global.ts +12 -0
- package/src/util/IfOverflow.ts +15 -0
- package/src/util/LRUCache.ts +41 -0
- package/src/util/LogUtils.ts +22 -0
- package/src/util/PolarUtils.ts +132 -0
- package/src/util/RadialBarUtils.tsx +24 -0
- package/src/util/ReactUtils.ts +95 -0
- package/src/util/ReduceCSSCalc.ts +187 -0
- package/src/util/ScatterUtils.tsx +52 -0
- package/src/util/ShapeElementProps.tsx +87 -0
- package/src/util/TickUtils.ts +60 -0
- package/src/util/XAxisUtils.ts +48 -0
- package/src/util/YAxisUtils.ts +48 -0
- package/src/util/axisPropsAreEqual.ts +48 -0
- package/src/util/createCartesianCharts.tsx +150 -0
- package/src/util/createEventProxy.ts +20 -0
- package/src/util/createPolarCharts.tsx +112 -0
- package/src/util/cursor/getCursorPoints.ts +46 -0
- package/src/util/cursor/getCursorRectangle.ts +28 -0
- package/src/util/cursor/getRadialCursorPoints.ts +32 -0
- package/src/util/excludeEventProps.ts +171 -0
- package/src/util/getActiveCoordinate.ts +213 -0
- package/src/util/getAxisTypeBasedOnLayout.ts +21 -0
- package/src/util/getClassNameFromUnknown.ts +6 -0
- package/src/util/getEveryNth.ts +27 -0
- package/src/util/getRadiusAndStrokeWidthFromDot.ts +35 -0
- package/src/util/getRelativeCoordinate.ts +80 -0
- package/src/util/getSliced.ts +13 -0
- package/src/util/hoverDedupe.ts +41 -0
- package/src/util/isDomainSpecifiedByUser.ts +219 -0
- package/src/util/isWellBehavedNumber.ts +7 -0
- package/src/util/pathTotalLength.ts +25 -0
- package/src/util/payload/getUniqPayload.ts +28 -0
- package/src/util/propsAreEqual.ts +121 -0
- package/src/util/resolveDefaultProps.ts +161 -0
- package/src/util/round.ts +32 -0
- package/src/util/scale/CartesianScaleHelper.ts +72 -0
- package/src/util/scale/CustomScaleDefinition.ts +81 -0
- package/src/util/scale/RechartsScale.ts +130 -0
- package/src/util/scale/createCategoricalInverse.ts +72 -0
- package/src/util/scale/getNiceTickValues.ts +311 -0
- package/src/util/scale/index.ts +2 -0
- package/src/util/scale/util/arithmetic.ts +54 -0
- package/src/util/solid-1-compat.ts +310 -0
- package/src/util/solidJsxCamelAugment.d.ts +84 -0
- package/src/util/stacks/getStackSeriesIdentifier.ts +21 -0
- package/src/util/stacks/stackTypes.ts +60 -0
- package/src/util/structurallyEqual.ts +31 -0
- package/src/util/svgPropertiesAndEvents.ts +53 -0
- package/src/util/svgPropertiesNoEvents.ts +571 -0
- package/src/util/tooltip/translate.ts +171 -0
- package/src/util/typedDataKey.ts +48 -0
- package/src/util/types.ts +1560 -0
- package/src/util/useAnimationId.ts +31 -0
- package/src/util/useElementOffset.ts +110 -0
- package/src/util/useId.ts +8 -0
- package/src/util/usePrefersReducedMotion.ts +48 -0
- package/src/util/useReportScale.ts +24 -0
- package/src/util/useUniqueId.ts +30 -0
- package/src/zIndex/DefaultZIndexes.ts +84 -0
- package/src/zIndex/ZIndexLayer.tsx +121 -0
- package/src/zIndex/ZIndexPortal.tsx +79 -0
- package/src/zIndex/getZIndexFromUnknown.ts +14 -0
- package/src/zIndex/zIndexSelectors.ts +48 -0
|
@@ -0,0 +1,915 @@
|
|
|
1
|
+
/* eslint-disable import/no-cycle, sort-keys */
|
|
2
|
+
import type { Formatter } from "../component/DefaultTooltipContent"
|
|
3
|
+
import { createMemo, Show, createEffect } from 'solid-js';
|
|
4
|
+
import type { JSX } from '@solidjs/web';
|
|
5
|
+
import { clsx } from "clsx"
|
|
6
|
+
import type { BaseLineType, CurveType, Props as CurveProps } from "../shape/Curve"
|
|
7
|
+
import { Layer } from "../container/Layer"
|
|
8
|
+
import {
|
|
9
|
+
LabelListContextBridge,
|
|
10
|
+
CartesianLabelListContextProvider,
|
|
11
|
+
type CartesianLabelListEntry,
|
|
12
|
+
type ImplicitLabelListType,
|
|
13
|
+
LabelListFromLabelProp,
|
|
14
|
+
} from "../component/LabelList"
|
|
15
|
+
import type { DotsDotProps } from "../component/Dots"
|
|
16
|
+
import { Dots } from "../component/Dots"
|
|
17
|
+
import { interpolate, isNan, isNullish, isNumber, noop } from "../util/DataUtils"
|
|
18
|
+
import {
|
|
19
|
+
getCateCoordinateOfLine,
|
|
20
|
+
getNormalizedStackId,
|
|
21
|
+
getTooltipNameProp,
|
|
22
|
+
getValueByDataKey,
|
|
23
|
+
type StackId,
|
|
24
|
+
} from "../util/ChartUtils"
|
|
25
|
+
import type {
|
|
26
|
+
ActiveDotType,
|
|
27
|
+
ActiveShape,
|
|
28
|
+
AnimationDuration,
|
|
29
|
+
AnimationTiming,
|
|
30
|
+
CartesianLayout,
|
|
31
|
+
DataConsumer,
|
|
32
|
+
DataKey,
|
|
33
|
+
DataProvider,
|
|
34
|
+
DotType,
|
|
35
|
+
LegendType,
|
|
36
|
+
NullableCoordinate,
|
|
37
|
+
TickItem,
|
|
38
|
+
TooltipType,
|
|
39
|
+
TrapezoidViewBox,
|
|
40
|
+
} from "../util/types"
|
|
41
|
+
import { Shape } from "../util/ActiveShapeUtils"
|
|
42
|
+
import type { AnimationInterpolateFn } from "../state/types/AnimationSettings"
|
|
43
|
+
import { matchAnimationItems, matchByIndex } from "../animation/matchBy"
|
|
44
|
+
import type { AnimationItem, AnimationMatchByProp } from "../animation/matchBy"
|
|
45
|
+
import { isClipDot } from "../util/ReactUtils"
|
|
46
|
+
import type { LegendPayload } from "../component/DefaultLegendContent"
|
|
47
|
+
import { ActivePoints } from "../component/ActivePoints"
|
|
48
|
+
import type { TooltipPayloadConfiguration } from "../state/tooltipSlice"
|
|
49
|
+
import { SetTooltipEntrySettings } from "../state/SetTooltipEntrySettings"
|
|
50
|
+
import { GraphicalItemClipPath, useNeedsClip } from "./GraphicalItemClipPath"
|
|
51
|
+
import type { BaseAxisWithScale } from "../state/selectors/axisSelectors"
|
|
52
|
+
import type { ChartData } from "../state/chartDataSlice"
|
|
53
|
+
import type { AreaPointItem, ComputedArea } from "../state/selectors/areaSelectors"
|
|
54
|
+
import { selectArea } from "../state/selectors/areaSelectors"
|
|
55
|
+
import { useIsPanorama } from "../context/PanoramaContext"
|
|
56
|
+
import { useCartesianChartLayout, useChartLayout } from "../context/chartLayoutContext"
|
|
57
|
+
import { useChartName } from "../state/selectors/selectors"
|
|
58
|
+
import { SetLegendPayload } from "../state/SetLegendPayload"
|
|
59
|
+
import { useChartStore } from "../state/RechartsStoreContext"
|
|
60
|
+
import { useAnimationId } from "../util/useAnimationId"
|
|
61
|
+
import { resolveDefaultProps } from "../util/resolveDefaultProps"
|
|
62
|
+
import { usePlotArea } from "../hooks"
|
|
63
|
+
import type { WithIdRequired, WithoutId } from "../util/useUniqueId"
|
|
64
|
+
import { RegisterGraphicalItemId } from "../context/RegisterGraphicalItemId"
|
|
65
|
+
import type { AreaSettings } from "../state/types/AreaSettings"
|
|
66
|
+
import { SetCartesianGraphicalItem } from "../state/SetGraphicalItem"
|
|
67
|
+
import { svgPropertiesNoEvents } from "../util/svgPropertiesNoEvents"
|
|
68
|
+
import { AnimatedItems, useAnimationCallbacks } from "../animation/AnimatedItems"
|
|
69
|
+
import { useAnimationStartSnapshot } from "../animation/useAnimationStartSnapshot"
|
|
70
|
+
import { AreaRevealShape } from "./AreaRevealShape"
|
|
71
|
+
import type { AreaRevealShapeProps } from "./AreaRevealShape"
|
|
72
|
+
import { getRadiusAndStrokeWidthFromDot } from "../util/getRadiusAndStrokeWidthFromDot"
|
|
73
|
+
import { svgPropertiesAndEvents } from "../util/svgPropertiesAndEvents"
|
|
74
|
+
import type { ZIndexable } from "../zIndex/ZIndexLayer"
|
|
75
|
+
import { ZIndexLayer } from "../zIndex/ZIndexLayer"
|
|
76
|
+
import { DefaultZIndexes } from "../zIndex/DefaultZIndexes"
|
|
77
|
+
import type { AxisId } from "../state/cartesianAxisSlice"
|
|
78
|
+
import type { StackDataPoint } from "../util/stacks/stackTypes"
|
|
79
|
+
|
|
80
|
+
import { splitProps } from '../util/solid-1-compat';
|
|
81
|
+
/** @inline */
|
|
82
|
+
export type BaseValue = number | "dataMin" | "dataMax"
|
|
83
|
+
|
|
84
|
+
type BaseValueCoordinate<DataPointType = unknown> = NullableCoordinate & {
|
|
85
|
+
payload: DataPointType | undefined
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
interface InternalAreaProps extends ZIndexable {
|
|
89
|
+
activeDot: ActiveDotType
|
|
90
|
+
animationBegin: number
|
|
91
|
+
animationDuration: AnimationDuration
|
|
92
|
+
animationEasing: AnimationTiming
|
|
93
|
+
baseLine: BaseLineType | undefined
|
|
94
|
+
|
|
95
|
+
baseValue?: BaseValue
|
|
96
|
+
className?: string
|
|
97
|
+
connectNulls: boolean
|
|
98
|
+
data?: ChartData
|
|
99
|
+
dataKey: DataKey<unknown>
|
|
100
|
+
dot: DotType
|
|
101
|
+
height: number
|
|
102
|
+
hide: boolean
|
|
103
|
+
id: string
|
|
104
|
+
isAnimationActive: boolean | "auto"
|
|
105
|
+
isRange?: boolean
|
|
106
|
+
label?: ImplicitLabelListType
|
|
107
|
+
layout: CartesianLayout
|
|
108
|
+
left: number
|
|
109
|
+
legendType: LegendType
|
|
110
|
+
name?: string | number
|
|
111
|
+
needClip: boolean
|
|
112
|
+
onAnimationEnd?: () => void
|
|
113
|
+
onAnimationStart?: () => void
|
|
114
|
+
points: ReadonlyArray<AreaPointItem>
|
|
115
|
+
shape: ActiveShape<AreaRevealShapeProps, SVGPathElement>
|
|
116
|
+
animationInterpolateFn: AnimationInterpolateFn<AreaPointItem, CartesianLayout>
|
|
117
|
+
animationMatchBy: AnimationMatchByProp<AreaPointItem>
|
|
118
|
+
stackId?: StackId
|
|
119
|
+
tooltipType?: TooltipType
|
|
120
|
+
formatter?: Formatter
|
|
121
|
+
top: number
|
|
122
|
+
type?: CurveType
|
|
123
|
+
unit?: string | number
|
|
124
|
+
width: number
|
|
125
|
+
xAxisId: string | number
|
|
126
|
+
yAxisId: string | number
|
|
127
|
+
children?: JSX.Element
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
interface AreaProps<DataPointType = unknown, DataValueType = unknown>
|
|
131
|
+
extends
|
|
132
|
+
DataProvider<DataPointType>,
|
|
133
|
+
Required<DataConsumer<DataPointType, DataValueType>>,
|
|
134
|
+
ZIndexable {
|
|
135
|
+
activeDot?: ActiveDotType
|
|
136
|
+
animationBegin?: number
|
|
137
|
+
animationDuration?: AnimationDuration
|
|
138
|
+
animationEasing?: AnimationTiming
|
|
139
|
+
baseLine?: BaseLineType
|
|
140
|
+
baseValue?: BaseValue
|
|
141
|
+
className?: string
|
|
142
|
+
connectNulls?: boolean
|
|
143
|
+
dot?: DotType
|
|
144
|
+
hide?: boolean
|
|
145
|
+
id?: string
|
|
146
|
+
isAnimationActive?: boolean | "auto"
|
|
147
|
+
isRange?: boolean
|
|
148
|
+
label?: ImplicitLabelListType
|
|
149
|
+
legendType?: LegendType
|
|
150
|
+
name?: string | number
|
|
151
|
+
onAnimationEnd?: () => void
|
|
152
|
+
onAnimationStart?: () => void
|
|
153
|
+
/**
|
|
154
|
+
* The shape of the area. Defaults to `AreaRevealShape`, which reveals the area with a
|
|
155
|
+
* clip-path during the entrance animation.
|
|
156
|
+
* During animations, a function shape also receives `animationElapsedTime`, `isAnimating`, and `isEntrance`.
|
|
157
|
+
*/
|
|
158
|
+
shape?: ActiveShape<AreaRevealShapeProps, SVGPathElement>
|
|
159
|
+
/**
|
|
160
|
+
* Custom animation function for interpolating data items.
|
|
161
|
+
* When provided, this replaces the default animation interpolation.
|
|
162
|
+
*
|
|
163
|
+
* @since 3.9
|
|
164
|
+
* @see {@link https://recharts.github.io/en-US/guide/animations/ Animations guide}
|
|
165
|
+
*/
|
|
166
|
+
animationInterpolateFn?: AnimationInterpolateFn<AreaPointItem, CartesianLayout>
|
|
167
|
+
/**
|
|
168
|
+
* Strategy for matching previous items to next items during animation.
|
|
169
|
+
*
|
|
170
|
+
* - `matchByIndex` (default): match by array position with proportional stretching
|
|
171
|
+
* - `matchAppend`: match sequentially by index and treat newly appended items as new
|
|
172
|
+
* - `matchByDataKey('someKey')`: match by a data key from the payload
|
|
173
|
+
* - Custom function `(item, index) => key`: match by the returned key
|
|
174
|
+
*
|
|
175
|
+
* @defaultValue index
|
|
176
|
+
*/
|
|
177
|
+
animationMatchBy?: AnimationMatchByProp<AreaPointItem>
|
|
178
|
+
stackId?: StackId
|
|
179
|
+
stroke?: string
|
|
180
|
+
strokeWidth?: string | number
|
|
181
|
+
tooltipType?: TooltipType
|
|
182
|
+
/**
|
|
183
|
+
* Formats the value displayed in the tooltip for this Area.
|
|
184
|
+
* When set, takes precedence over the `formatter` prop on the Tooltip component.
|
|
185
|
+
*/
|
|
186
|
+
formatter?: Formatter
|
|
187
|
+
type?: CurveType
|
|
188
|
+
unit?: string | number
|
|
189
|
+
xAxisId?: AxisId
|
|
190
|
+
yAxisId?: AxisId
|
|
191
|
+
zIndex?: number
|
|
192
|
+
children?: JSX.Element
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
type AreaSvgProps = Omit<
|
|
196
|
+
CurveProps,
|
|
197
|
+
"points" | "ref" | "layout" | "path" | "pathRef" | "baseLine" | "dangerouslySetInnerHTML"
|
|
198
|
+
>
|
|
199
|
+
|
|
200
|
+
type InternalProps = AreaSvgProps & InternalAreaProps
|
|
201
|
+
|
|
202
|
+
/* eslint-disable-next-line typescript-eslint/no-explicit-any -- upstream contract: untyped items accept any data */
|
|
203
|
+
export type Props<DataPointType = any, DataValueType = any> = AreaSvgProps & AreaProps<DataPointType, DataValueType>
|
|
204
|
+
|
|
205
|
+
function getLegendItemColor(
|
|
206
|
+
stroke: string | undefined,
|
|
207
|
+
fill: string | undefined,
|
|
208
|
+
): string | undefined {
|
|
209
|
+
return stroke && stroke !== "none" ? stroke : fill
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/* eslint-disable solid/reactivity -- plain utility fn; areaProps is not a Solid reactive proxy at this call site */
|
|
213
|
+
const computeLegendPayloadFromAreaData = (areaProps: Props): ReadonlyArray<LegendPayload> => {
|
|
214
|
+
return [
|
|
215
|
+
{
|
|
216
|
+
color: getLegendItemColor(areaProps.stroke, areaProps.fill),
|
|
217
|
+
dataKey: areaProps.dataKey,
|
|
218
|
+
inactive: areaProps.hide,
|
|
219
|
+
payload: areaProps,
|
|
220
|
+
type: areaProps.legendType,
|
|
221
|
+
value: getTooltipNameProp(areaProps.name, areaProps.dataKey),
|
|
222
|
+
},
|
|
223
|
+
]
|
|
224
|
+
}
|
|
225
|
+
/* eslint-enable solid/reactivity */
|
|
226
|
+
|
|
227
|
+
function SetAreaTooltipEntrySettings(
|
|
228
|
+
props: Pick<
|
|
229
|
+
WithIdRequired<Props>,
|
|
230
|
+
| "dataKey"
|
|
231
|
+
| "data"
|
|
232
|
+
| "stroke"
|
|
233
|
+
| "strokeWidth"
|
|
234
|
+
| "fill"
|
|
235
|
+
| "name"
|
|
236
|
+
| "hide"
|
|
237
|
+
| "unit"
|
|
238
|
+
| "tooltipType"
|
|
239
|
+
| "formatter"
|
|
240
|
+
| "id"
|
|
241
|
+
>,
|
|
242
|
+
) {
|
|
243
|
+
/* GOTCHA-005: createMemo so reactive props flow into the settings object. */
|
|
244
|
+
const tooltipEntrySettings = createMemo<TooltipPayloadConfiguration>(() => ({
|
|
245
|
+
dataDefinedOnItem: props.data,
|
|
246
|
+
getPosition: noop,
|
|
247
|
+
settings: {
|
|
248
|
+
color: getLegendItemColor(props.stroke, props.fill),
|
|
249
|
+
dataKey: props.dataKey,
|
|
250
|
+
fill: props.fill,
|
|
251
|
+
formatter: props.formatter,
|
|
252
|
+
graphicalItemId: props.id,
|
|
253
|
+
hide: props.hide,
|
|
254
|
+
name: getTooltipNameProp(props.name, props.dataKey),
|
|
255
|
+
nameKey: undefined,
|
|
256
|
+
stroke: props.stroke,
|
|
257
|
+
strokeWidth: props.strokeWidth,
|
|
258
|
+
type: props.tooltipType,
|
|
259
|
+
unit: props.unit,
|
|
260
|
+
},
|
|
261
|
+
}))
|
|
262
|
+
return <SetTooltipEntrySettings tooltipEntrySettings={tooltipEntrySettings()} />
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
function AreaDotsWrapper(props: {
|
|
266
|
+
clipPathId: string
|
|
267
|
+
points: ReadonlyArray<AreaPointItem>
|
|
268
|
+
allProps: WithoutId<InternalProps>
|
|
269
|
+
}) {
|
|
270
|
+
const areaProps = (): DotsDotProps => svgPropertiesNoEvents(props.allProps)
|
|
271
|
+
|
|
272
|
+
return (
|
|
273
|
+
<Dots
|
|
274
|
+
points={props.points}
|
|
275
|
+
dot={props.allProps.dot}
|
|
276
|
+
className="recharts-area-dots"
|
|
277
|
+
dotClassName="recharts-area-dot"
|
|
278
|
+
dataKey={props.allProps.dataKey}
|
|
279
|
+
baseProps={areaProps()}
|
|
280
|
+
needClip={props.allProps.needClip}
|
|
281
|
+
clipPathId={props.clipPathId}
|
|
282
|
+
/>
|
|
283
|
+
)
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
function AreaLabelListProvider(props: {
|
|
287
|
+
showLabels: boolean
|
|
288
|
+
children: JSX.Element
|
|
289
|
+
points: ReadonlyArray<AreaPointItem>
|
|
290
|
+
}) {
|
|
291
|
+
const labelListEntries = createMemo((): ReadonlyArray<CartesianLabelListEntry> => {
|
|
292
|
+
return props.points.map((point): CartesianLabelListEntry => {
|
|
293
|
+
const viewBox: TrapezoidViewBox = {
|
|
294
|
+
height: 0,
|
|
295
|
+
lowerWidth: 0,
|
|
296
|
+
upperWidth: 0,
|
|
297
|
+
width: 0,
|
|
298
|
+
x: point.x ?? 0,
|
|
299
|
+
y: point.y ?? 0,
|
|
300
|
+
}
|
|
301
|
+
return {
|
|
302
|
+
...viewBox,
|
|
303
|
+
fill: undefined,
|
|
304
|
+
parentViewBox: undefined,
|
|
305
|
+
payload: point.payload,
|
|
306
|
+
value: point.value,
|
|
307
|
+
viewBox,
|
|
308
|
+
}
|
|
309
|
+
})
|
|
310
|
+
})
|
|
311
|
+
|
|
312
|
+
/* eslint-disable solid/reactivity -- showLabels and labelListEntries() in JSX; linter can't trace through Context.Provider value prop */
|
|
313
|
+
return (
|
|
314
|
+
<CartesianLabelListContextProvider value={props.showLabels ? labelListEntries() : undefined}>
|
|
315
|
+
{props.children}
|
|
316
|
+
</CartesianLabelListContextProvider>
|
|
317
|
+
)
|
|
318
|
+
/* eslint-enable solid/reactivity */
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
function StaticArea(props: {
|
|
322
|
+
points: ReadonlyArray<AreaPointItem>
|
|
323
|
+
baseLine: BaseLineType | undefined
|
|
324
|
+
needClip: boolean
|
|
325
|
+
clipPathId: string
|
|
326
|
+
allProps: InternalProps
|
|
327
|
+
animationElapsedTime: number
|
|
328
|
+
isAnimating: boolean
|
|
329
|
+
isEntrance: boolean
|
|
330
|
+
}) {
|
|
331
|
+
/* eslint-disable-next-line solid/reactivity -- splitProps keeps lazy getters; reads happen in the memo below */
|
|
332
|
+
const [, propsWithoutId] = splitProps(props.allProps, ["id"])
|
|
333
|
+
const propsWithEvents = createMemo(() => svgPropertiesAndEvents(propsWithoutId))
|
|
334
|
+
|
|
335
|
+
return (
|
|
336
|
+
<>
|
|
337
|
+
<Show when={props.points?.length > 1}>
|
|
338
|
+
<Layer clip-path={props.needClip ? `url(#clipPath-${props.clipPathId})` : undefined}>
|
|
339
|
+
<Shape
|
|
340
|
+
{...propsWithEvents()}
|
|
341
|
+
shapeType="curve"
|
|
342
|
+
option={props.allProps.shape}
|
|
343
|
+
DefaultShape={AreaRevealShape}
|
|
344
|
+
id={props.allProps.id}
|
|
345
|
+
points={props.points}
|
|
346
|
+
connectNulls={props.allProps.connectNulls}
|
|
347
|
+
type={props.allProps.type}
|
|
348
|
+
baseLine={props.baseLine}
|
|
349
|
+
layout={props.allProps.layout}
|
|
350
|
+
stroke={props.allProps.stroke}
|
|
351
|
+
isRange={props.allProps.isRange}
|
|
352
|
+
animationElapsedTime={props.animationElapsedTime}
|
|
353
|
+
isAnimating={props.isAnimating}
|
|
354
|
+
isEntrance={props.isEntrance}
|
|
355
|
+
/>
|
|
356
|
+
</Layer>
|
|
357
|
+
</Show>
|
|
358
|
+
<AreaDotsWrapper
|
|
359
|
+
points={props.points}
|
|
360
|
+
allProps={propsWithoutId as WithoutId<InternalProps>}
|
|
361
|
+
clipPathId={props.clipPathId}
|
|
362
|
+
/>
|
|
363
|
+
</>
|
|
364
|
+
)
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
function interpolateScalarBaseLine(
|
|
368
|
+
baseLine: BaseLineType | undefined,
|
|
369
|
+
prevBaseLine: BaseLineType | undefined,
|
|
370
|
+
animationElapsedTime: number,
|
|
371
|
+
): BaseLineType {
|
|
372
|
+
if (isNumber(baseLine)) {
|
|
373
|
+
const previousNumberBaseLine = isNumber(prevBaseLine) ? prevBaseLine : undefined
|
|
374
|
+
return interpolate(previousNumberBaseLine, baseLine, animationElapsedTime)
|
|
375
|
+
}
|
|
376
|
+
if (isNullish(baseLine) || isNan(baseLine)) {
|
|
377
|
+
const previousNumberBaseLine = isNumber(prevBaseLine) ? prevBaseLine : undefined
|
|
378
|
+
return interpolate(previousNumberBaseLine, 0, animationElapsedTime)
|
|
379
|
+
}
|
|
380
|
+
return baseLine
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
const defaultAreaAnimateItems: AnimationInterpolateFn<AreaPointItem, CartesianLayout> = (
|
|
384
|
+
items,
|
|
385
|
+
animationElapsedTime,
|
|
386
|
+
) => {
|
|
387
|
+
if (items == null) {
|
|
388
|
+
// First render: return items as-is, clip-path animation handles the reveal
|
|
389
|
+
return []
|
|
390
|
+
}
|
|
391
|
+
if (animationElapsedTime === 1) {
|
|
392
|
+
return items.flatMap((item) => (item.status === "removed" ? [] : [item.next]))
|
|
393
|
+
}
|
|
394
|
+
return items.flatMap((item) => {
|
|
395
|
+
if (item.status === "matched") {
|
|
396
|
+
return [
|
|
397
|
+
{
|
|
398
|
+
...item.next,
|
|
399
|
+
x: interpolate(item.prev.x, item.next.x, animationElapsedTime),
|
|
400
|
+
y: interpolate(item.prev.y, item.next.y, animationElapsedTime),
|
|
401
|
+
},
|
|
402
|
+
]
|
|
403
|
+
}
|
|
404
|
+
if (item.status === "added") {
|
|
405
|
+
/*
|
|
406
|
+
* Here we just return the final position without interpolating
|
|
407
|
+
* so that we can allow the default initial animation that is done by clipPath in AreaRevealShape.
|
|
408
|
+
* If you want your own custom animations then you may want to interpolate this one as well.
|
|
409
|
+
*/
|
|
410
|
+
return [item.next]
|
|
411
|
+
}
|
|
412
|
+
// removed: drop
|
|
413
|
+
return []
|
|
414
|
+
})
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
function AreaWithAnimation(props: {
|
|
418
|
+
needClip: boolean
|
|
419
|
+
clipPathId: string
|
|
420
|
+
allProps: InternalProps
|
|
421
|
+
previousPointsRef: { current: ReadonlyArray<AreaPointItem> | null }
|
|
422
|
+
previousBaselineRef: { current: BaseLineType | undefined }
|
|
423
|
+
}) {
|
|
424
|
+
const animationInput = createMemo(() => ({
|
|
425
|
+
baseLine: props.allProps.baseLine,
|
|
426
|
+
points: props.allProps.points,
|
|
427
|
+
}))
|
|
428
|
+
/* Same content-compared identity AnimatedItems derives from `animationInput`. */
|
|
429
|
+
const baseLineAnimationId = useAnimationId(animationInput, "recharts-area-baseline-")
|
|
430
|
+
const baseLineAnimationState = useAnimationStartSnapshot(
|
|
431
|
+
baseLineAnimationId,
|
|
432
|
+
/* eslint-disable-next-line solid/reactivity -- the ref box is a stable mutable container */
|
|
433
|
+
props.previousBaselineRef,
|
|
434
|
+
)
|
|
435
|
+
const layout = createMemo(() => useCartesianChartLayout())
|
|
436
|
+
|
|
437
|
+
const { isAnimating, handleAnimationStart, handleAnimationEnd } = useAnimationCallbacks(
|
|
438
|
+
() => props.allProps.onAnimationStart,
|
|
439
|
+
() => props.allProps.onAnimationEnd,
|
|
440
|
+
)
|
|
441
|
+
|
|
442
|
+
const baseLineAnimationItems = createMemo((): ReadonlyArray<AnimationItem<NullableCoordinate>> | null => {
|
|
443
|
+
const baseLine = props.allProps.baseLine
|
|
444
|
+
const prevBaseLine = baseLineAnimationState.frozenStartValue()
|
|
445
|
+
if (Array.isArray(baseLine) && Array.isArray(prevBaseLine)) {
|
|
446
|
+
return matchAnimationItems<NullableCoordinate>(prevBaseLine, baseLine, props.allProps.animationMatchBy as AnimationMatchByProp<NullableCoordinate>)
|
|
447
|
+
}
|
|
448
|
+
if (Array.isArray(baseLine)) {
|
|
449
|
+
return matchAnimationItems<NullableCoordinate>(null, baseLine, props.allProps.animationMatchBy as AnimationMatchByProp<NullableCoordinate>)
|
|
450
|
+
}
|
|
451
|
+
return null
|
|
452
|
+
})
|
|
453
|
+
|
|
454
|
+
return (
|
|
455
|
+
<Show when={layout()}>
|
|
456
|
+
{(cartesianLayout) => (
|
|
457
|
+
<AreaLabelListProvider showLabels={!isAnimating()} points={props.allProps.points}>
|
|
458
|
+
{props.allProps.children}
|
|
459
|
+
<AnimatedItems
|
|
460
|
+
animationInput={animationInput()}
|
|
461
|
+
animationIdPrefix="recharts-area-"
|
|
462
|
+
items={props.allProps.points}
|
|
463
|
+
previousItemsRef={props.previousPointsRef}
|
|
464
|
+
isAnimationActive={props.allProps.isAnimationActive}
|
|
465
|
+
animationBegin={props.allProps.animationBegin}
|
|
466
|
+
animationDuration={props.allProps.animationDuration}
|
|
467
|
+
animationEasing={props.allProps.animationEasing}
|
|
468
|
+
onAnimationStart={handleAnimationStart}
|
|
469
|
+
onAnimationEnd={handleAnimationEnd}
|
|
470
|
+
animationInterpolateFn={props.allProps.animationInterpolateFn}
|
|
471
|
+
animationMatchBy={props.allProps.animationMatchBy}
|
|
472
|
+
layout={cartesianLayout()}
|
|
473
|
+
>
|
|
474
|
+
{(stepPoints, animationElapsedTime, isEntrance) => {
|
|
475
|
+
const stepBaseLine = createMemo((): BaseLineType | undefined => {
|
|
476
|
+
const t = animationElapsedTime()
|
|
477
|
+
const baseLine = props.allProps.baseLine
|
|
478
|
+
if (t === 1) {
|
|
479
|
+
return baseLine
|
|
480
|
+
}
|
|
481
|
+
if (Array.isArray(baseLine)) {
|
|
482
|
+
return (
|
|
483
|
+
props.allProps.animationInterpolateFn as unknown as AnimationInterpolateFn<
|
|
484
|
+
NullableCoordinate,
|
|
485
|
+
CartesianLayout
|
|
486
|
+
>
|
|
487
|
+
)(baseLineAnimationItems(), t, cartesianLayout())
|
|
488
|
+
}
|
|
489
|
+
return isEntrance()
|
|
490
|
+
? baseLine
|
|
491
|
+
: interpolateScalarBaseLine(baseLine, baseLineAnimationState.frozenStartValue(), t)
|
|
492
|
+
})
|
|
493
|
+
createEffect(
|
|
494
|
+
() => ({ step: stepBaseLine(), t: animationElapsedTime() }),
|
|
495
|
+
({ step, t }) => {
|
|
496
|
+
baseLineAnimationState.syncStepValue(step, t)
|
|
497
|
+
},
|
|
498
|
+
)
|
|
499
|
+
return (
|
|
500
|
+
<StaticArea
|
|
501
|
+
points={stepPoints()}
|
|
502
|
+
baseLine={stepBaseLine()}
|
|
503
|
+
needClip={props.needClip}
|
|
504
|
+
clipPathId={props.clipPathId}
|
|
505
|
+
allProps={props.allProps}
|
|
506
|
+
animationElapsedTime={animationElapsedTime()}
|
|
507
|
+
isAnimating={isAnimating() || animationElapsedTime() < 1}
|
|
508
|
+
isEntrance={isEntrance()}
|
|
509
|
+
/>
|
|
510
|
+
)
|
|
511
|
+
}}
|
|
512
|
+
</AnimatedItems>
|
|
513
|
+
<LabelListFromLabelProp label={props.allProps.label} />
|
|
514
|
+
</AreaLabelListProvider>
|
|
515
|
+
)}
|
|
516
|
+
</Show>
|
|
517
|
+
)
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
function RenderArea(props: { needClip: boolean; clipPathId: string; allProps: InternalProps }) {
|
|
521
|
+
const previousPointsRef: { current: ReadonlyArray<AreaPointItem> | null } = { current: null }
|
|
522
|
+
const previousBaselineRef: { current: BaseLineType | undefined } = { current: undefined }
|
|
523
|
+
return (
|
|
524
|
+
<AreaWithAnimation
|
|
525
|
+
needClip={props.needClip}
|
|
526
|
+
clipPathId={props.clipPathId}
|
|
527
|
+
allProps={props.allProps}
|
|
528
|
+
previousPointsRef={previousPointsRef}
|
|
529
|
+
previousBaselineRef={previousBaselineRef}
|
|
530
|
+
/>
|
|
531
|
+
)
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
function AreaWithState(props: InternalProps) {
|
|
535
|
+
return (
|
|
536
|
+
<Show when={!props.hide}>
|
|
537
|
+
{(() => {
|
|
538
|
+
const layerClass = () => clsx("recharts-area", props.className)
|
|
539
|
+
const clipPathId = () => props.id
|
|
540
|
+
const dotMeta = () => getRadiusAndStrokeWidthFromDot(props.dot)
|
|
541
|
+
const clipDot = () => isClipDot(props.dot)
|
|
542
|
+
const dotSize = () => dotMeta().r * 2 + dotMeta().strokeWidth
|
|
543
|
+
const activePointsClipPath = () =>
|
|
544
|
+
props.needClip ? `url(#clipPath-${clipDot() ? "" : "dots-"}${clipPathId()})` : undefined
|
|
545
|
+
|
|
546
|
+
return (
|
|
547
|
+
<ZIndexLayer zIndex={props.zIndex}>
|
|
548
|
+
<Layer class={layerClass()}>
|
|
549
|
+
<Show when={props.needClip}>
|
|
550
|
+
<defs>
|
|
551
|
+
<GraphicalItemClipPath
|
|
552
|
+
clipPathId={clipPathId()}
|
|
553
|
+
xAxisId={props.xAxisId}
|
|
554
|
+
yAxisId={props.yAxisId}
|
|
555
|
+
/>
|
|
556
|
+
<Show when={!clipDot()}>
|
|
557
|
+
<clipPath id={`clipPath-dots-${clipPathId()}`}>
|
|
558
|
+
<rect
|
|
559
|
+
x={props.left - dotSize() / 2}
|
|
560
|
+
y={props.top - dotSize() / 2}
|
|
561
|
+
width={props.width + dotSize()}
|
|
562
|
+
height={props.height + dotSize()}
|
|
563
|
+
/>
|
|
564
|
+
</clipPath>
|
|
565
|
+
</Show>
|
|
566
|
+
</defs>
|
|
567
|
+
</Show>
|
|
568
|
+
<RenderArea
|
|
569
|
+
needClip={props.needClip}
|
|
570
|
+
clipPathId={clipPathId()}
|
|
571
|
+
allProps={props}
|
|
572
|
+
/>
|
|
573
|
+
</Layer>
|
|
574
|
+
<ActivePoints
|
|
575
|
+
points={props.points}
|
|
576
|
+
mainColor={getLegendItemColor(props.stroke, props.fill)}
|
|
577
|
+
itemDataKey={props.dataKey}
|
|
578
|
+
activeDot={props.activeDot}
|
|
579
|
+
clipPath={activePointsClipPath()}
|
|
580
|
+
/>
|
|
581
|
+
<Show when={props.isRange && Array.isArray(props.baseLine)}>
|
|
582
|
+
<ActivePoints
|
|
583
|
+
points={props.baseLine as ReadonlyArray<AreaPointItem>}
|
|
584
|
+
mainColor={getLegendItemColor(props.stroke, props.fill)}
|
|
585
|
+
itemDataKey={props.dataKey}
|
|
586
|
+
activeDot={props.activeDot}
|
|
587
|
+
clipPath={activePointsClipPath()}
|
|
588
|
+
/>
|
|
589
|
+
</Show>
|
|
590
|
+
</ZIndexLayer>
|
|
591
|
+
)
|
|
592
|
+
})()}
|
|
593
|
+
</Show>
|
|
594
|
+
)
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
export const defaultAreaProps = {
|
|
598
|
+
activeDot: true,
|
|
599
|
+
animationBegin: 0,
|
|
600
|
+
animationDuration: 1500,
|
|
601
|
+
animationEasing: "ease",
|
|
602
|
+
animationInterpolateFn: defaultAreaAnimateItems,
|
|
603
|
+
animationMatchBy: matchByIndex,
|
|
604
|
+
connectNulls: false,
|
|
605
|
+
dot: false,
|
|
606
|
+
fill: "#3182bd",
|
|
607
|
+
fillOpacity: 0.6,
|
|
608
|
+
hide: false,
|
|
609
|
+
isAnimationActive: "auto",
|
|
610
|
+
label: false,
|
|
611
|
+
legendType: "line",
|
|
612
|
+
shape: AreaRevealShape,
|
|
613
|
+
stroke: "#3182bd",
|
|
614
|
+
strokeWidth: 1,
|
|
615
|
+
type: "linear",
|
|
616
|
+
xAxisId: 0,
|
|
617
|
+
yAxisId: 0,
|
|
618
|
+
zIndex: DefaultZIndexes.area,
|
|
619
|
+
} as const satisfies Partial<Props>
|
|
620
|
+
|
|
621
|
+
function AreaImpl(props: WithIdRequired<Props>) {
|
|
622
|
+
const resolved = resolveDefaultProps(props, defaultAreaProps)
|
|
623
|
+
const ctx = useChartStore()
|
|
624
|
+
const layout = createMemo(() => useChartLayout())
|
|
625
|
+
const chartName = createMemo(() => (ctx ? useChartName(ctx.store) : undefined))
|
|
626
|
+
const needClipResult = createMemo(() => useNeedsClip(resolved.xAxisId, resolved.yAxisId))
|
|
627
|
+
const isPanorama = useIsPanorama()
|
|
628
|
+
|
|
629
|
+
/* perf: cache selector result; without memo every consumer read triggers full chain.
|
|
630
|
+
Axis reactivity: selectArea reads ctx.store.cartesianAxes (Solid proxy) without
|
|
631
|
+
untrack — this memo tracks those signals.
|
|
632
|
+
Item reactivity: explicit graphicalItems[id] read tracks item settings mutations. */
|
|
633
|
+
/* Per-chart chartSelector memo keyed by ids; settings are resolved from the store. */
|
|
634
|
+
const areaData = createMemo(() => (ctx ? selectArea(ctx.store, props.id, isPanorama) : undefined))
|
|
635
|
+
const plotArea = createMemo(() => usePlotArea())
|
|
636
|
+
const visibleArea = createMemo(() => {
|
|
637
|
+
if (
|
|
638
|
+
(layout() === "horizontal" || layout() === "vertical") &&
|
|
639
|
+
plotArea() != null &&
|
|
640
|
+
(chartName() === "AreaChart" || chartName() === "ComposedChart") &&
|
|
641
|
+
areaData()?.points?.length
|
|
642
|
+
) {
|
|
643
|
+
return areaData()
|
|
644
|
+
}
|
|
645
|
+
return undefined
|
|
646
|
+
})
|
|
647
|
+
|
|
648
|
+
return (
|
|
649
|
+
<Show when={visibleArea() != null}>
|
|
650
|
+
<AreaWithState
|
|
651
|
+
{...resolved}
|
|
652
|
+
activeDot={resolved.activeDot}
|
|
653
|
+
animationBegin={resolved.animationBegin}
|
|
654
|
+
animationDuration={resolved.animationDuration}
|
|
655
|
+
animationEasing={resolved.animationEasing}
|
|
656
|
+
baseLine={visibleArea()?.baseLine}
|
|
657
|
+
connectNulls={resolved.connectNulls}
|
|
658
|
+
dot={resolved.dot}
|
|
659
|
+
fill={resolved.fill}
|
|
660
|
+
fillOpacity={resolved.fillOpacity}
|
|
661
|
+
height={plotArea()?.height ?? 0}
|
|
662
|
+
hide={resolved.hide}
|
|
663
|
+
layout={layout() as CartesianLayout}
|
|
664
|
+
isAnimationActive={resolved.isAnimationActive}
|
|
665
|
+
isRange={visibleArea()?.isRange}
|
|
666
|
+
legendType={resolved.legendType}
|
|
667
|
+
needClip={needClipResult()?.needClip() ?? false}
|
|
668
|
+
points={visibleArea()?.points ?? []}
|
|
669
|
+
stroke={resolved.stroke}
|
|
670
|
+
width={plotArea()?.width ?? 0}
|
|
671
|
+
left={plotArea()?.x ?? 0}
|
|
672
|
+
top={plotArea()?.y ?? 0}
|
|
673
|
+
xAxisId={resolved.xAxisId}
|
|
674
|
+
yAxisId={resolved.yAxisId}
|
|
675
|
+
/>
|
|
676
|
+
</Show>
|
|
677
|
+
)
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
export const getBaseValue = (
|
|
681
|
+
layout: "horizontal" | "vertical",
|
|
682
|
+
chartBaseValue: BaseValue | undefined,
|
|
683
|
+
itemBaseValue: BaseValue | undefined,
|
|
684
|
+
xAxis: BaseAxisWithScale,
|
|
685
|
+
yAxis: BaseAxisWithScale,
|
|
686
|
+
): number => {
|
|
687
|
+
const baseValue: BaseValue | undefined = itemBaseValue ?? chartBaseValue
|
|
688
|
+
|
|
689
|
+
if (isNumber(baseValue)) {
|
|
690
|
+
return baseValue as number
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
const numericAxis = layout === "horizontal" ? yAxis : xAxis
|
|
694
|
+
const rawDomain = numericAxis.scale.domain()
|
|
695
|
+
const domain: [number, number] = [Number(rawDomain[0] ?? 0), Number(rawDomain[1] ?? 0)]
|
|
696
|
+
|
|
697
|
+
if (numericAxis.type === "number") {
|
|
698
|
+
const domainMax = Math.max(domain[0], domain[1])
|
|
699
|
+
const domainMin = Math.min(domain[0], domain[1])
|
|
700
|
+
|
|
701
|
+
if (baseValue === "dataMin") {
|
|
702
|
+
return domainMin
|
|
703
|
+
}
|
|
704
|
+
if (baseValue === "dataMax") {
|
|
705
|
+
return domainMax
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
return domainMax < 0 ? domainMax : Math.max(Math.min(domain[0], domain[1]), 0)
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
if (baseValue === "dataMin") {
|
|
712
|
+
return domain[0]
|
|
713
|
+
}
|
|
714
|
+
if (baseValue === "dataMax") {
|
|
715
|
+
return domain[1]
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
return domain[0]
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
export function computeArea({
|
|
722
|
+
areaSettings: { connectNulls, baseValue: itemBaseValue, dataKey },
|
|
723
|
+
stackedData,
|
|
724
|
+
layout,
|
|
725
|
+
chartBaseValue,
|
|
726
|
+
xAxis,
|
|
727
|
+
yAxis,
|
|
728
|
+
displayedData,
|
|
729
|
+
dataStartIndex,
|
|
730
|
+
xAxisTicks,
|
|
731
|
+
yAxisTicks,
|
|
732
|
+
bandSize,
|
|
733
|
+
stackDataKeys,
|
|
734
|
+
}: {
|
|
735
|
+
areaSettings: AreaSettings
|
|
736
|
+
stackedData: ReadonlyArray<StackDataPoint> | undefined
|
|
737
|
+
layout: "horizontal" | "vertical"
|
|
738
|
+
chartBaseValue: BaseValue | undefined
|
|
739
|
+
xAxis: BaseAxisWithScale
|
|
740
|
+
yAxis: BaseAxisWithScale
|
|
741
|
+
displayedData: ChartData
|
|
742
|
+
dataStartIndex: number
|
|
743
|
+
xAxisTicks: TickItem[]
|
|
744
|
+
yAxisTicks: TickItem[]
|
|
745
|
+
bandSize: number
|
|
746
|
+
stackDataKeys?: ReadonlyArray<DataKey<unknown>>
|
|
747
|
+
}): ComputedArea {
|
|
748
|
+
const hasStack = stackedData && stackedData.length
|
|
749
|
+
const baseValue = getBaseValue(layout, chartBaseValue, itemBaseValue, xAxis, yAxis)
|
|
750
|
+
const isHorizontalLayout = layout === "horizontal"
|
|
751
|
+
let isRange = false
|
|
752
|
+
|
|
753
|
+
const points: ReadonlyArray<AreaPointItem> = displayedData.map((entry, index): AreaPointItem => {
|
|
754
|
+
const entryRecord =
|
|
755
|
+
entry != null && typeof entry === "object"
|
|
756
|
+
? (entry as Record<string, unknown>)
|
|
757
|
+
: ({} as Record<string, unknown>)
|
|
758
|
+
let valueAsArray: ReadonlyArray<unknown> | undefined
|
|
759
|
+
|
|
760
|
+
if (hasStack) {
|
|
761
|
+
valueAsArray = stackedData[dataStartIndex + index]
|
|
762
|
+
} else {
|
|
763
|
+
const rawValue = getValueByDataKey(entry, dataKey)
|
|
764
|
+
|
|
765
|
+
if (!Array.isArray(rawValue)) {
|
|
766
|
+
valueAsArray = [baseValue, rawValue]
|
|
767
|
+
} else {
|
|
768
|
+
valueAsArray = rawValue
|
|
769
|
+
isRange = true
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
const value1 = valueAsArray?.[1] ?? null
|
|
774
|
+
|
|
775
|
+
const rawValue = getValueByDataKey(entry, dataKey)
|
|
776
|
+
const wholeStackIsNull =
|
|
777
|
+
Boolean(hasStack) &&
|
|
778
|
+
rawValue == null &&
|
|
779
|
+
stackDataKeys != null &&
|
|
780
|
+
stackDataKeys.length > 0 &&
|
|
781
|
+
stackDataKeys.every((key) => getValueByDataKey(entry, key) == null)
|
|
782
|
+
const isBreakPoint =
|
|
783
|
+
value1 == null ||
|
|
784
|
+
(Boolean(hasStack) && !connectNulls && rawValue == null) ||
|
|
785
|
+
wholeStackIsNull
|
|
786
|
+
|
|
787
|
+
if (isHorizontalLayout) {
|
|
788
|
+
return {
|
|
789
|
+
payload: entry,
|
|
790
|
+
value: valueAsArray,
|
|
791
|
+
x: getCateCoordinateOfLine({
|
|
792
|
+
axis: xAxis,
|
|
793
|
+
bandSize,
|
|
794
|
+
entry: entryRecord,
|
|
795
|
+
index,
|
|
796
|
+
ticks: xAxisTicks,
|
|
797
|
+
}),
|
|
798
|
+
y: isBreakPoint ? null : (yAxis.scale.map(value1) ?? null),
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
return {
|
|
803
|
+
payload: entry,
|
|
804
|
+
value: valueAsArray,
|
|
805
|
+
x: isBreakPoint ? null : (xAxis.scale.map(value1) ?? null),
|
|
806
|
+
y: getCateCoordinateOfLine({
|
|
807
|
+
axis: yAxis,
|
|
808
|
+
bandSize,
|
|
809
|
+
entry: entryRecord,
|
|
810
|
+
index,
|
|
811
|
+
ticks: yAxisTicks,
|
|
812
|
+
}),
|
|
813
|
+
}
|
|
814
|
+
})
|
|
815
|
+
|
|
816
|
+
let baseLine: number | NullableCoordinate[] | undefined
|
|
817
|
+
if (hasStack || isRange) {
|
|
818
|
+
baseLine = points.map((entry: AreaPointItem): BaseValueCoordinate => {
|
|
819
|
+
const x = Array.isArray(entry.value) ? entry.value[0] : null
|
|
820
|
+
if (isHorizontalLayout) {
|
|
821
|
+
return {
|
|
822
|
+
payload: entry.payload,
|
|
823
|
+
x: entry.x,
|
|
824
|
+
y: x != null && entry.y != null ? (yAxis.scale.map(x) ?? null) : null,
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
return {
|
|
828
|
+
payload: entry.payload,
|
|
829
|
+
x: x != null ? (xAxis.scale.map(x) ?? null) : null,
|
|
830
|
+
y: entry.y,
|
|
831
|
+
}
|
|
832
|
+
})
|
|
833
|
+
} else {
|
|
834
|
+
baseLine = isHorizontalLayout ? yAxis.scale.map(baseValue) : xAxis.scale.map(baseValue)
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
return {
|
|
838
|
+
baseLine: baseLine ?? 0,
|
|
839
|
+
isRange,
|
|
840
|
+
points,
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
/**
|
|
845
|
+
* @provides LabelListContext
|
|
846
|
+
* @consumes CartesianChartContext
|
|
847
|
+
*/
|
|
848
|
+
function AreaFn(outsideProps: Props): JSX.Element {
|
|
849
|
+
/* GOTCHA-013: split children before resolveDefaultProps. The spread inside
|
|
850
|
+
resolveDefaultProps reads the `children` getter and eagerly invokes user JSX
|
|
851
|
+
(ErrorBar/etc.) before RegisterGraphicalItemId installs its Provider.
|
|
852
|
+
Memoize once: the `get children()` getter on user JSX re-creates components on
|
|
853
|
+
every read; without resolveChildren, downstream JSX holes re-mint ErrorBar each
|
|
854
|
+
time → infinite dispatch loop on `state.errorBars[id]`. */
|
|
855
|
+
const [childrenProps, restProps] = splitProps(outsideProps, ["children"])
|
|
856
|
+
const props = resolveDefaultProps(restProps, defaultAreaProps)
|
|
857
|
+
const isPanorama = useIsPanorama()
|
|
858
|
+
return (
|
|
859
|
+
<RegisterGraphicalItemId id={props.id} type="area">
|
|
860
|
+
{(id) => (
|
|
861
|
+
<LabelListContextBridge>
|
|
862
|
+
{(() => {
|
|
863
|
+
/* Memoize children inside Provider scope (GOTCHA-013). */
|
|
864
|
+
const memoizedChildren = createMemo(() => childrenProps.children)
|
|
865
|
+
return (
|
|
866
|
+
<>
|
|
867
|
+
<SetLegendPayload legendPayload={computeLegendPayloadFromAreaData(props)} />
|
|
868
|
+
<SetAreaTooltipEntrySettings
|
|
869
|
+
dataKey={props.dataKey}
|
|
870
|
+
data={props.data}
|
|
871
|
+
stroke={props.stroke}
|
|
872
|
+
strokeWidth={props.strokeWidth}
|
|
873
|
+
fill={props.fill}
|
|
874
|
+
name={props.name}
|
|
875
|
+
hide={props.hide}
|
|
876
|
+
unit={props.unit}
|
|
877
|
+
tooltipType={props.tooltipType}
|
|
878
|
+
formatter={props.formatter}
|
|
879
|
+
id={id}
|
|
880
|
+
/>
|
|
881
|
+
<SetCartesianGraphicalItem
|
|
882
|
+
type="area"
|
|
883
|
+
id={id}
|
|
884
|
+
data={props.data}
|
|
885
|
+
dataKey={props.dataKey}
|
|
886
|
+
xAxisId={props.xAxisId}
|
|
887
|
+
yAxisId={props.yAxisId}
|
|
888
|
+
zAxisId={0}
|
|
889
|
+
stackId={getNormalizedStackId(props.stackId)}
|
|
890
|
+
hide={props.hide}
|
|
891
|
+
barSize={undefined}
|
|
892
|
+
baseValue={props.baseValue}
|
|
893
|
+
isPanorama={isPanorama}
|
|
894
|
+
connectNulls={props.connectNulls}
|
|
895
|
+
/>
|
|
896
|
+
<AreaImpl {...props} id={id}>
|
|
897
|
+
{memoizedChildren()}
|
|
898
|
+
</AreaImpl>
|
|
899
|
+
</>
|
|
900
|
+
)
|
|
901
|
+
})()}
|
|
902
|
+
</LabelListContextBridge>
|
|
903
|
+
)}
|
|
904
|
+
</RegisterGraphicalItemId>
|
|
905
|
+
)
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
/**
|
|
909
|
+
* Typed entry point: the generics constrain props at the call site, like upstream.
|
|
910
|
+
*/
|
|
911
|
+
/* eslint-disable-next-line typescript-eslint/no-explicit-any -- upstream contract: untyped usage accepts any data */
|
|
912
|
+
export const Area = AreaFn as (<DataPointType = any, DataValueType = any>(
|
|
913
|
+
props: Props<DataPointType, DataValueType>,
|
|
914
|
+
) => JSX.Element) & { displayName?: string }
|
|
915
|
+
Area.displayName = "Area"
|