@solidports/recharts 0.1.0 → 0.1.1
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/dist/index.d.ts +40 -2
- package/dist/index.js +14238 -7174
- package/dist/{dev.js → index.jsx} +18367 -15900
- package/dist/server.js +48178 -0
- package/package.json +36 -19
- package/src/animation/AnimatedItems.tsx +0 -183
- package/src/animation/AnimationController.ts +0 -33
- package/src/animation/AnimationControllerImpl.ts +0 -36
- package/src/animation/AnimationHandle.ts +0 -307
- package/src/animation/CSSTransitionAnimate.tsx +0 -170
- package/src/animation/JavascriptAnimate.tsx +0 -119
- package/src/animation/easing.ts +0 -221
- package/src/animation/matchBy.ts +0 -164
- package/src/animation/timeoutController.ts +0 -70
- package/src/animation/useAnimationController.tsx +0 -34
- package/src/animation/useAnimationStartSnapshot.ts +0 -118
- package/src/animation/util.ts +0 -41
- package/src/cartesian/Area.tsx +0 -915
- package/src/cartesian/AreaRevealShape.tsx +0 -190
- package/src/cartesian/Bar.tsx +0 -1369
- package/src/cartesian/BarStack.tsx +0 -152
- package/src/cartesian/Brush.tsx +0 -951
- package/src/cartesian/CartesianAxis.tsx +0 -722
- package/src/cartesian/CartesianGrid.tsx +0 -711
- package/src/cartesian/ErrorBar.tsx +0 -361
- package/src/cartesian/Funnel.tsx +0 -803
- package/src/cartesian/GraphicalItemClipPath.tsx +0 -67
- package/src/cartesian/Line.tsx +0 -863
- package/src/cartesian/LineDrawShape.tsx +0 -89
- package/src/cartesian/ReferenceArea.tsx +0 -331
- package/src/cartesian/ReferenceDot.tsx +0 -304
- package/src/cartesian/ReferenceLine.tsx +0 -474
- package/src/cartesian/Scatter.tsx +0 -888
- package/src/cartesian/XAxis.tsx +0 -433
- package/src/cartesian/YAxis.tsx +0 -443
- package/src/cartesian/ZAxis.tsx +0 -155
- package/src/cartesian/cartesianPositionToCSSTranslate.tsx +0 -29
- package/src/cartesian/cartesianViewBoxToTrapezoid.tsx +0 -21
- package/src/cartesian/getCartesianPosition.tsx +0 -267
- package/src/cartesian/getEquidistantTicks.ts +0 -144
- package/src/cartesian/getTicks.ts +0 -225
- package/src/cartesian/isOutsidePosition.ts +0 -15
- package/src/cartesian/useAnimatedLineLength.ts +0 -54
- package/src/chart/AreaChart.tsx +0 -29
- package/src/chart/BarChart.tsx +0 -29
- package/src/chart/CartesianChart.tsx +0 -131
- package/src/chart/CategoricalChart.tsx +0 -94
- package/src/chart/ComposedChart.tsx +0 -29
- package/src/chart/FunnelChart.tsx +0 -29
- package/src/chart/LineChart.tsx +0 -29
- package/src/chart/PieChart.tsx +0 -50
- package/src/chart/PolarChart.tsx +0 -164
- package/src/chart/RadarChart.tsx +0 -70
- package/src/chart/RadialBarChart.tsx +0 -46
- package/src/chart/RechartsWrapper.tsx +0 -551
- package/src/chart/Sankey.tsx +0 -1534
- package/src/chart/ScatterChart.tsx +0 -29
- package/src/chart/SunburstChart.tsx +0 -504
- package/src/chart/Treemap.tsx +0 -1223
- package/src/chart/createInitialRootProps.ts +0 -24
- package/src/chart/types.ts +0 -53
- package/src/component/ActivePoints.tsx +0 -144
- package/src/component/Cell.tsx +0 -37
- package/src/component/Cursor.tsx +0 -185
- package/src/component/Customized.tsx +0 -50
- package/src/component/DefaultLegendContent.tsx +0 -348
- package/src/component/DefaultTooltipContent.tsx +0 -224
- package/src/component/Dots.tsx +0 -157
- package/src/component/Label.tsx +0 -636
- package/src/component/LabelList.tsx +0 -375
- package/src/component/Legend.tsx +0 -512
- package/src/component/ResponsiveContainer.tsx +0 -348
- package/src/component/Text.tsx +0 -541
- package/src/component/Tooltip.tsx +0 -470
- package/src/component/TooltipBoundingBox.tsx +0 -146
- package/src/component/responsiveContainerUtils.ts +0 -134
- package/src/container/ClipPathProvider.tsx +0 -51
- package/src/container/Layer.tsx +0 -38
- package/src/container/RootSurface.tsx +0 -120
- package/src/container/Surface.tsx +0 -61
- package/src/context/CellsContext.tsx +0 -54
- package/src/context/ErrorBarContext.tsx +0 -146
- package/src/context/GraphicalItemChildrenScope.tsx +0 -18
- package/src/context/PanoramaContext.tsx +0 -9
- package/src/context/RegisterGraphicalItemId.tsx +0 -30
- package/src/context/accessibilityContext.tsx +0 -6
- package/src/context/brushUpdateContext.tsx +0 -9
- package/src/context/chartDataContext.tsx +0 -97
- package/src/context/chartLayoutContext.tsx +0 -201
- package/src/context/legendPayloadContext.tsx +0 -20
- package/src/context/legendPortalContext.tsx +0 -12
- package/src/context/tooltipContext.tsx +0 -89
- package/src/context/tooltipPortalContext.tsx +0 -12
- package/src/context/useTooltipAxis.ts +0 -22
- package/src/hooks.ts +0 -476
- package/src/index.ts +0 -280
- package/src/polar/Pie.tsx +0 -1360
- package/src/polar/PolarAngleAxis.tsx +0 -616
- package/src/polar/PolarGrid.tsx +0 -312
- package/src/polar/PolarRadiusAxis.tsx +0 -547
- package/src/polar/Radar.tsx +0 -734
- package/src/polar/RadialBar.tsx +0 -917
- package/src/polar/defaultPolarAngleAxisProps.tsx +0 -27
- package/src/polar/defaultPolarRadiusAxisProps.tsx +0 -25
- package/src/shape/Cross.tsx +0 -89
- package/src/shape/Curve.tsx +0 -343
- package/src/shape/Dot.tsx +0 -70
- package/src/shape/Polygon.tsx +0 -195
- package/src/shape/Rectangle.tsx +0 -470
- package/src/shape/Sector.tsx +0 -347
- package/src/shape/Symbols.tsx +0 -139
- package/src/shape/Trapezoid.tsx +0 -280
- package/src/state/RechartsStateContext.tsx +0 -12
- package/src/state/RechartsStateProvider.tsx +0 -87
- package/src/state/RechartsStoreContext.tsx +0 -25
- package/src/state/RechartsStoreProvider.tsx +0 -35
- package/src/state/ReportChartProps.tsx +0 -40
- package/src/state/ReportEventSettings.tsx +0 -30
- package/src/state/ReportMainChartProps.tsx +0 -61
- package/src/state/ReportPolarOptions.tsx +0 -35
- package/src/state/SetGraphicalItem.ts +0 -79
- package/src/state/SetLegendPayload.ts +0 -134
- package/src/state/SetTooltipEntrySettings.tsx +0 -72
- package/src/state/actions.ts +0 -464
- package/src/state/brushSlice.ts +0 -13
- package/src/state/cartesianAxisSlice.ts +0 -141
- package/src/state/chartDataSlice.ts +0 -50
- package/src/state/chartState.ts +0 -297
- package/src/state/errorBarSlice.ts +0 -29
- package/src/state/eventSettingsSlice.ts +0 -8
- package/src/state/events.ts +0 -76
- package/src/state/externalEventsMiddleware.ts +0 -255
- package/src/state/graphicalItemsSlice.ts +0 -74
- package/src/state/hooks/useChartSelectors.tsx +0 -45
- package/src/state/keyboardEventsMiddleware.ts +0 -228
- package/src/state/layoutSlice.ts +0 -21
- package/src/state/legendSlice.ts +0 -57
- package/src/state/mouseEventsMiddleware.ts +0 -185
- package/src/state/optionsSlice.ts +0 -47
- package/src/state/polarAxisSlice.ts +0 -10
- package/src/state/polarOptionsSlice.ts +0 -12
- package/src/state/rawData.ts +0 -26
- package/src/state/referenceElementsSlice.ts +0 -40
- package/src/state/renderedTicksSlice.ts +0 -15
- package/src/state/rootPropsSlice.ts +0 -47
- package/src/state/selectors/areaSelectors.ts +0 -240
- package/src/state/selectors/arrayEqualityCheck.ts +0 -29
- package/src/state/selectors/axisSelectors.ts +0 -2157
- package/src/state/selectors/barSelectors.ts +0 -310
- package/src/state/selectors/barStackSelectors.ts +0 -77
- package/src/state/selectors/brushSelectors.ts +0 -33
- package/src/state/selectors/chartSelector.ts +0 -185
- package/src/state/selectors/combiners/combineActiveLabel.ts +0 -16
- package/src/state/selectors/combiners/combineActiveTooltipIndex.ts +0 -95
- package/src/state/selectors/combiners/combineAllBarPositions.ts +0 -122
- package/src/state/selectors/combiners/combineAxisRangeWithReverse.ts +0 -16
- package/src/state/selectors/combiners/combineBarPosition.ts +0 -23
- package/src/state/selectors/combiners/combineBarSizeList.ts +0 -80
- package/src/state/selectors/combiners/combineCheckedDomain.ts +0 -48
- package/src/state/selectors/combiners/combineConfiguredScale.ts +0 -111
- package/src/state/selectors/combiners/combineCoordinateForDefaultIndex.ts +0 -45
- package/src/state/selectors/combiners/combineDisplayedStackedData.ts +0 -50
- package/src/state/selectors/combiners/combineInverseScaleFunction.ts +0 -16
- package/src/state/selectors/combiners/combineRealScaleType.ts +0 -44
- package/src/state/selectors/combiners/combineStackedData.ts +0 -27
- package/src/state/selectors/combiners/combineTooltipInteractionState.ts +0 -86
- package/src/state/selectors/combiners/combineTooltipPayload.ts +0 -205
- package/src/state/selectors/combiners/combineTooltipPayloadConfigurations.ts +0 -58
- package/src/state/selectors/containerSelectors.ts +0 -12
- package/src/state/selectors/dataSelectors.ts +0 -88
- package/src/state/selectors/funnelSelectors.ts +0 -75
- package/src/state/selectors/graphicalItemSelectors.ts +0 -30
- package/src/state/selectors/legendSelectors.ts +0 -29
- package/src/state/selectors/lineSelectors.ts +0 -134
- package/src/state/selectors/numberDomainEqualityCheck.ts +0 -14
- package/src/state/selectors/pickAxisId.ts +0 -5
- package/src/state/selectors/pickAxisType.ts +0 -3
- package/src/state/selectors/pieSelectors.ts +0 -97
- package/src/state/selectors/polarAxisSelectors.ts +0 -201
- package/src/state/selectors/polarGridSelectors.ts +0 -28
- package/src/state/selectors/polarScaleSelectors.ts +0 -133
- package/src/state/selectors/polarSelectors.ts +0 -219
- package/src/state/selectors/radarSelectors.ts +0 -191
- package/src/state/selectors/radialBarSelectors.ts +0 -435
- package/src/state/selectors/rootPropsSelectors.ts +0 -25
- package/src/state/selectors/scatterSelectors.ts +0 -96
- package/src/state/selectors/selectActivePropsFromChartPointer.ts +0 -26
- package/src/state/selectors/selectAllAxes.ts +0 -17
- package/src/state/selectors/selectChartOffset.ts +0 -16
- package/src/state/selectors/selectChartOffsetInternal.ts +0 -136
- package/src/state/selectors/selectLegendArea.ts +0 -20
- package/src/state/selectors/selectPlotArea.ts +0 -22
- package/src/state/selectors/selectTooltipAxisId.ts +0 -7
- package/src/state/selectors/selectTooltipAxisType.ts +0 -32
- package/src/state/selectors/selectTooltipEventType.ts +0 -48
- package/src/state/selectors/selectTooltipPayloadSearcher.ts +0 -6
- package/src/state/selectors/selectTooltipSettings.ts +0 -39
- package/src/state/selectors/selectTooltipState.ts +0 -8
- package/src/state/selectors/selectors.ts +0 -271
- package/src/state/selectors/tooltipSelectors.ts +0 -578
- package/src/state/selectors/touchSelectors.ts +0 -31
- package/src/state/store.ts +0 -29
- package/src/state/storeIdentity.ts +0 -9
- package/src/state/teardownWrite.ts +0 -10
- package/src/state/tooltipInteraction.ts +0 -23
- package/src/state/tooltipSlice.ts +0 -334
- package/src/state/touchEventsMiddleware.ts +0 -214
- package/src/state/types/AnimationSettings.ts +0 -20
- package/src/state/types/AreaSettings.ts +0 -14
- package/src/state/types/BarSettings.ts +0 -15
- package/src/state/types/LineSettings.ts +0 -9
- package/src/state/types/PieSettings.ts +0 -34
- package/src/state/types/RadarSettings.ts +0 -5
- package/src/state/types/RadialBarSettings.ts +0 -10
- package/src/state/types/ScatterSettings.ts +0 -12
- package/src/state/types/StackedGraphicalItem.ts +0 -34
- package/src/state/useChartState.ts +0 -17
- package/src/state/zIndexSlice.ts +0 -39
- package/src/synchronisation/syncSelectors.ts +0 -7
- package/src/synchronisation/types.ts +0 -44
- package/src/synchronisation/useChartSynchronisation.tsx +0 -404
- package/src/theme/RechartsTheme.ts +0 -16
- package/src/theme/RechartsThemeContext.ts +0 -19
- package/src/theme/darkTheme.ts +0 -13
- package/src/theme/graphicalItemIdentity.ts +0 -70
- package/src/theme/legacyTheme.ts +0 -17
- package/src/theme/lightTheme.ts +0 -13
- package/src/types.ts +0 -54
- package/src/util/ActiveShapeUtils.tsx +0 -162
- package/src/util/BarUtils.tsx +0 -62
- package/src/util/BarePortal.tsx +0 -50
- package/src/util/CamelCaseSVGAttrs.ts +0 -34
- package/src/util/CartesianUtils.ts +0 -48
- package/src/util/ChartUtils.ts +0 -802
- package/src/util/Constants.ts +0 -42
- package/src/util/CssPrefixUtils.ts +0 -20
- package/src/util/DOMUtils.ts +0 -129
- package/src/util/DataUtils.ts +0 -216
- package/src/util/Events.ts +0 -16
- package/src/util/FunnelUtils.tsx +0 -15
- package/src/util/Global.ts +0 -12
- package/src/util/IfOverflow.ts +0 -15
- package/src/util/LRUCache.ts +0 -41
- package/src/util/LogUtils.ts +0 -22
- package/src/util/PolarUtils.ts +0 -132
- package/src/util/RadialBarUtils.tsx +0 -24
- package/src/util/ReactUtils.ts +0 -95
- package/src/util/ReduceCSSCalc.ts +0 -187
- package/src/util/ScatterUtils.tsx +0 -52
- package/src/util/ShapeElementProps.tsx +0 -87
- package/src/util/TickUtils.ts +0 -60
- package/src/util/XAxisUtils.ts +0 -48
- package/src/util/YAxisUtils.ts +0 -48
- package/src/util/axisPropsAreEqual.ts +0 -48
- package/src/util/createCartesianCharts.tsx +0 -150
- package/src/util/createEventProxy.ts +0 -20
- package/src/util/createPolarCharts.tsx +0 -112
- package/src/util/cursor/getCursorPoints.ts +0 -46
- package/src/util/cursor/getCursorRectangle.ts +0 -28
- package/src/util/cursor/getRadialCursorPoints.ts +0 -32
- package/src/util/excludeEventProps.ts +0 -171
- package/src/util/getActiveCoordinate.ts +0 -213
- package/src/util/getAxisTypeBasedOnLayout.ts +0 -21
- package/src/util/getClassNameFromUnknown.ts +0 -6
- package/src/util/getEveryNth.ts +0 -27
- package/src/util/getRadiusAndStrokeWidthFromDot.ts +0 -35
- package/src/util/getRelativeCoordinate.ts +0 -80
- package/src/util/getSliced.ts +0 -13
- package/src/util/hoverDedupe.ts +0 -41
- package/src/util/isDomainSpecifiedByUser.ts +0 -219
- package/src/util/isWellBehavedNumber.ts +0 -7
- package/src/util/pathTotalLength.ts +0 -25
- package/src/util/payload/getUniqPayload.ts +0 -28
- package/src/util/propsAreEqual.ts +0 -121
- package/src/util/resolveDefaultProps.ts +0 -161
- package/src/util/round.ts +0 -32
- package/src/util/scale/CartesianScaleHelper.ts +0 -72
- package/src/util/scale/CustomScaleDefinition.ts +0 -81
- package/src/util/scale/RechartsScale.ts +0 -130
- package/src/util/scale/createCategoricalInverse.ts +0 -72
- package/src/util/scale/getNiceTickValues.ts +0 -311
- package/src/util/scale/index.ts +0 -2
- package/src/util/scale/util/arithmetic.ts +0 -54
- package/src/util/solid-1-compat.ts +0 -310
- package/src/util/solidJsxCamelAugment.d.ts +0 -84
- package/src/util/stacks/getStackSeriesIdentifier.ts +0 -21
- package/src/util/stacks/stackTypes.ts +0 -60
- package/src/util/structurallyEqual.ts +0 -31
- package/src/util/svgPropertiesAndEvents.ts +0 -53
- package/src/util/svgPropertiesNoEvents.ts +0 -571
- package/src/util/tooltip/translate.ts +0 -171
- package/src/util/typedDataKey.ts +0 -48
- package/src/util/types.ts +0 -1560
- package/src/util/useAnimationId.ts +0 -31
- package/src/util/useElementOffset.ts +0 -110
- package/src/util/useId.ts +0 -8
- package/src/util/usePrefersReducedMotion.ts +0 -48
- package/src/util/useReportScale.ts +0 -24
- package/src/util/useUniqueId.ts +0 -30
- package/src/zIndex/DefaultZIndexes.ts +0 -84
- package/src/zIndex/ZIndexLayer.tsx +0 -121
- package/src/zIndex/ZIndexPortal.tsx +0 -79
- package/src/zIndex/getZIndexFromUnknown.ts +0 -14
- package/src/zIndex/zIndexSelectors.ts +0 -48
package/src/polar/Pie.tsx
DELETED
|
@@ -1,1360 +0,0 @@
|
|
|
1
|
-
/* eslint-disable import/no-cycle, sort-keys */
|
|
2
|
-
import type { JSX } from '@solidjs/web';
|
|
3
|
-
import { createHoverDedupe } from "../util/hoverDedupe"
|
|
4
|
-
import { createMemo, For, Show, untrack, useContext } from 'solid-js';
|
|
5
|
-
import get from "es-toolkit/compat/get"
|
|
6
|
-
|
|
7
|
-
import { clsx } from "clsx"
|
|
8
|
-
import { selectPieLegend, selectPieSectors } from "../state/selectors/pieSelectors"
|
|
9
|
-
import { useChartStore } from "../state/RechartsStoreContext"
|
|
10
|
-
import { CellsContextProvider, createCellsRegistry } from "../context/CellsContext"
|
|
11
|
-
import { Layer } from "../container/Layer"
|
|
12
|
-
import { Curve, Props as CurveProps } from "../shape/Curve"
|
|
13
|
-
import { Text } from "../component/Text"
|
|
14
|
-
import { getMaxRadius, polarToCartesian } from "../util/PolarUtils"
|
|
15
|
-
import { getPercentValue, interpolate, isNumber, mathSign } from "../util/DataUtils"
|
|
16
|
-
import { getTooltipNameProp, getValueByDataKey } from "../util/ChartUtils"
|
|
17
|
-
import {
|
|
18
|
-
ActiveShape,
|
|
19
|
-
adaptEventsOfChild,
|
|
20
|
-
AnimationDuration,
|
|
21
|
-
AnimationTiming,
|
|
22
|
-
ChartOffsetInternal,
|
|
23
|
-
Coordinate,
|
|
24
|
-
DataConsumer,
|
|
25
|
-
DataKey,
|
|
26
|
-
DataProvider,
|
|
27
|
-
GeometrySector,
|
|
28
|
-
LegendType,
|
|
29
|
-
PresentationAttributesAdaptChildEvent,
|
|
30
|
-
TooltipType,
|
|
31
|
-
} from "../util/types"
|
|
32
|
-
import { Shape } from "../util/ActiveShapeUtils"
|
|
33
|
-
import {
|
|
34
|
-
TooltipTriggerInfo,
|
|
35
|
-
useMouseClickItemDispatch,
|
|
36
|
-
useMouseEnterItemDispatch,
|
|
37
|
-
useMouseLeaveItemDispatch,
|
|
38
|
-
} from "../context/tooltipContext"
|
|
39
|
-
import { TooltipPayload, TooltipPayloadConfiguration } from "../state/tooltipSlice"
|
|
40
|
-
import { SetTooltipEntrySettings } from "../state/SetTooltipEntrySettings"
|
|
41
|
-
import {
|
|
42
|
-
selectActiveTooltipDataKey,
|
|
43
|
-
selectActiveTooltipGraphicalItemId,
|
|
44
|
-
selectActiveTooltipIndex,
|
|
45
|
-
} from "../state/selectors/tooltipSelectors"
|
|
46
|
-
import { SetPolarLegendPayload } from "../state/SetLegendPayload"
|
|
47
|
-
import {
|
|
48
|
-
DATA_ITEM_GRAPHICAL_ITEM_ID_ATTRIBUTE_NAME,
|
|
49
|
-
DATA_ITEM_INDEX_ATTRIBUTE_NAME,
|
|
50
|
-
} from "../util/Constants"
|
|
51
|
-
import { RequiresDefaultProps, resolveDefaultProps } from "../util/resolveDefaultProps"
|
|
52
|
-
import { RegisterGraphicalItemId } from "../context/RegisterGraphicalItemId"
|
|
53
|
-
import { SetPolarGraphicalItem } from "../state/SetGraphicalItem"
|
|
54
|
-
import { RechartsStateContext } from "../state/RechartsStateContext"
|
|
55
|
-
import { PiePresentationProps, PieSettings } from "../state/types/PieSettings"
|
|
56
|
-
import {
|
|
57
|
-
svgPropertiesNoEvents,
|
|
58
|
-
svgPropertiesNoEventsFromUnknown,
|
|
59
|
-
SVGPropsNoEvents,
|
|
60
|
-
} from "../util/svgPropertiesNoEvents"
|
|
61
|
-
import { AnimatedItems, useAnimationCallbacks } from "../animation/AnimatedItems"
|
|
62
|
-
import type { AnimationInterpolateFn } from "../animation/AnimatedItems"
|
|
63
|
-
import { matchAppend } from "../animation/matchBy"
|
|
64
|
-
import type { AnimationMatchByProp } from "../animation/matchBy"
|
|
65
|
-
import { usePolarChartLayout } from "../context/chartLayoutContext"
|
|
66
|
-
import type { PolarLayout, ShapeAnimationProps } from "../util/types"
|
|
67
|
-
import {
|
|
68
|
-
LabelListContextBridge,
|
|
69
|
-
LabelListFromLabelProp,
|
|
70
|
-
PolarLabelListContextProvider,
|
|
71
|
-
PolarLabelListEntry,
|
|
72
|
-
Props as LabelListProps,
|
|
73
|
-
} from "../component/LabelList"
|
|
74
|
-
import { PolarLabelContextProvider } from "../component/Label"
|
|
75
|
-
import { GraphicalItemId } from "../state/graphicalItemsSlice"
|
|
76
|
-
import { ZIndexable, ZIndexLayer } from "../zIndex/ZIndexLayer"
|
|
77
|
-
import { DefaultZIndexes } from "../zIndex/DefaultZIndexes"
|
|
78
|
-
import { ChartData } from "../state/chartDataSlice"
|
|
79
|
-
import { getClassNameFromUnknown } from "../util/getClassNameFromUnknown"
|
|
80
|
-
import { cloneJsxNodeWithProps, isJsxNode } from "../util/ReactUtils"
|
|
81
|
-
import type { Formatter } from "../component/DefaultTooltipContent"
|
|
82
|
-
|
|
83
|
-
import { mergeProps, splitProps } from '../util/solid-1-compat';
|
|
84
|
-
interface PieDef {
|
|
85
|
-
/**
|
|
86
|
-
* The x-coordinate of center. If set a percentage, the final value is obtained by multiplying the percentage of container width.
|
|
87
|
-
*/
|
|
88
|
-
cx?: number | string
|
|
89
|
-
/**
|
|
90
|
-
* The y-coordinate of center. If set a percentage, the final value is obtained by multiplying the percentage of container height.
|
|
91
|
-
*/
|
|
92
|
-
cy?: number | string
|
|
93
|
-
/**
|
|
94
|
-
* Angle in degrees from which the chart should start.
|
|
95
|
-
*/
|
|
96
|
-
startAngle?: number
|
|
97
|
-
/**
|
|
98
|
-
* Angle, in degrees, at which the chart should end.
|
|
99
|
-
*/
|
|
100
|
-
endAngle?: number
|
|
101
|
-
/**
|
|
102
|
-
* The angle between two sectors.
|
|
103
|
-
*
|
|
104
|
-
* @example <Pie paddingAngle={5} />
|
|
105
|
-
* @example https://recharts.github.io/examples/PieChartWithPaddingAngle
|
|
106
|
-
*/
|
|
107
|
-
paddingAngle?: number
|
|
108
|
-
/**
|
|
109
|
-
* The inner radius of the sectors.
|
|
110
|
-
* If set a percentage, the final value is obtained by multiplying the percentage of maxRadius which is calculated by the width, height, cx, cy.
|
|
111
|
-
*/
|
|
112
|
-
innerRadius?: number | string
|
|
113
|
-
/**
|
|
114
|
-
* The outer radius of the sectors.
|
|
115
|
-
* If set a percentage, the final value is obtained by multiplying the percentage of maxRadius which is calculated by the width, height, cx, cy.
|
|
116
|
-
* Function should return a string percentage or number.
|
|
117
|
-
*/
|
|
118
|
-
outerRadius?: number | string | ((dataPoint: unknown) => number | string)
|
|
119
|
-
cornerRadius?: number | string
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
type PieLabelLine =
|
|
123
|
-
| ((props: Record<string, unknown>) => JSX.Element)
|
|
124
|
-
| JSX.PathSVGAttributes<SVGPathElement>
|
|
125
|
-
| boolean
|
|
126
|
-
|
|
127
|
-
interface PieLabelExtraProps {
|
|
128
|
-
stroke: string
|
|
129
|
-
index: number
|
|
130
|
-
textAnchor: string
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
export type PieLabelRenderProps = Omit<SVGPropsNoEvents<PieSvgAttributes>, "offset"> &
|
|
134
|
-
Omit<PieSectorDataItem, "offset"> &
|
|
135
|
-
PieLabelExtraProps &
|
|
136
|
-
Coordinate
|
|
137
|
-
|
|
138
|
-
export type LabelListPropsWithPosition = LabelListProps & { position: LabelListProps["position"] }
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* The `label` prop in Pie accepts a variety of alternatives.
|
|
142
|
-
*/
|
|
143
|
-
export type PieLabel =
|
|
144
|
-
| boolean
|
|
145
|
-
| LabelListPropsWithPosition
|
|
146
|
-
| Partial<PieLabelRenderProps>
|
|
147
|
-
| ((props: PieLabelRenderProps) => JSX.Element)
|
|
148
|
-
|
|
149
|
-
export type PieSectorData = GeometrySector &
|
|
150
|
-
TooltipTriggerInfo & {
|
|
151
|
-
dataKey?: DataKey<unknown>
|
|
152
|
-
midAngle?: number
|
|
153
|
-
middleRadius?: number
|
|
154
|
-
name?: string | number
|
|
155
|
-
paddingAngle?: number
|
|
156
|
-
payload?: unknown
|
|
157
|
-
percent?: number
|
|
158
|
-
value: number
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
* We spread the data object into the sector data item,
|
|
163
|
-
* so we can't really know what is going to be inside.
|
|
164
|
-
*
|
|
165
|
-
* This type represents our best effort, but it all depends on the input data
|
|
166
|
-
* and what is inside of it.
|
|
167
|
-
*
|
|
168
|
-
* https://github.com/recharts/recharts/issues/6380
|
|
169
|
-
* https://github.com/recharts/recharts/discussions/6375
|
|
170
|
-
*/
|
|
171
|
-
export type PieSectorDataItem = PiePresentationProps &
|
|
172
|
-
PieCoordinate &
|
|
173
|
-
PieSectorData & {
|
|
174
|
-
cornerRadius: number | undefined
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
export type PieSectorShapeProps = PieSectorDataItem & { isActive: boolean; index: number }
|
|
178
|
-
export type PieShape = JSX.Element | ((props: PieSectorShapeProps, index: number) => JSX.Element)
|
|
179
|
-
|
|
180
|
-
interface PieEvents {
|
|
181
|
-
/**
|
|
182
|
-
* The customized event handler of click on the sectors in this group.
|
|
183
|
-
*/
|
|
184
|
-
onClick?: (data: PieSectorDataItem, index: number, e: MouseEvent & { currentTarget: SVGGraphicsElement }) => void
|
|
185
|
-
/**
|
|
186
|
-
* The customized event handler of mousedown on the sectors in this group.
|
|
187
|
-
*/
|
|
188
|
-
onMouseDown?: (data: PieSectorDataItem, index: number, e: MouseEvent & { currentTarget: SVGGraphicsElement }) => void
|
|
189
|
-
/**
|
|
190
|
-
* The customized event handler of mouseup on the sectors in this group.
|
|
191
|
-
*/
|
|
192
|
-
onMouseUp?: (data: PieSectorDataItem, index: number, e: MouseEvent & { currentTarget: SVGGraphicsElement }) => void
|
|
193
|
-
/**
|
|
194
|
-
* The customized event handler of mousemove on the sectors in this group.
|
|
195
|
-
*/
|
|
196
|
-
onMouseMove?: (data: PieSectorDataItem, index: number, e: MouseEvent & { currentTarget: SVGGraphicsElement }) => void
|
|
197
|
-
/**
|
|
198
|
-
* The customized event handler of mouseover on the sectors in this group.
|
|
199
|
-
*/
|
|
200
|
-
onMouseOver?: (data: PieSectorDataItem, index: number, e: MouseEvent & { currentTarget: SVGGraphicsElement }) => void
|
|
201
|
-
/**
|
|
202
|
-
* The customized event handler of mouseout on the sectors in this group.
|
|
203
|
-
*/
|
|
204
|
-
onMouseOut?: (data: PieSectorDataItem, index: number, e: MouseEvent & { currentTarget: SVGGraphicsElement }) => void
|
|
205
|
-
/**
|
|
206
|
-
* The customized event handler of mouseenter on the sectors in this group.
|
|
207
|
-
*/
|
|
208
|
-
onMouseEnter?: (data: PieSectorDataItem, index: number, e: MouseEvent & { currentTarget: SVGGraphicsElement }) => void
|
|
209
|
-
/**
|
|
210
|
-
* The customized event handler of mouseleave on the sectors in this group.
|
|
211
|
-
*/
|
|
212
|
-
onMouseLeave?: (data: PieSectorDataItem, index: number, e: MouseEvent & { currentTarget: SVGGraphicsElement }) => void
|
|
213
|
-
onTouchStart?: (data: PieSectorDataItem, index: number, e: TouchEvent & { currentTarget: SVGGraphicsElement }) => void
|
|
214
|
-
onTouchMove?: (data: PieSectorDataItem, index: number, e: TouchEvent & { currentTarget: SVGGraphicsElement }) => void
|
|
215
|
-
onTouchEnd?: (data: PieSectorDataItem, index: number, e: TouchEvent & { currentTarget: SVGGraphicsElement }) => void
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
/**
|
|
219
|
-
* Internal props, combination of external props + defaultProps + private Recharts state
|
|
220
|
-
*/
|
|
221
|
-
interface InternalPieProps<DataPointType = unknown>
|
|
222
|
-
extends DataProvider<DataPointType>, PieDef, ZIndexable, PieEvents {
|
|
223
|
-
id: GraphicalItemId
|
|
224
|
-
className?: string
|
|
225
|
-
name?: string | number
|
|
226
|
-
dataKey: DataKey<DataPointType, unknown>
|
|
227
|
-
nameKey?: DataKey<DataPointType, string>
|
|
228
|
-
/** The minimum angle for no-zero element */
|
|
229
|
-
minAngle?: number
|
|
230
|
-
legendType?: LegendType
|
|
231
|
-
tooltipType?: TooltipType
|
|
232
|
-
formatter?: Formatter
|
|
233
|
-
/** the max radius of pie */
|
|
234
|
-
maxRadius?: number
|
|
235
|
-
hide?: boolean
|
|
236
|
-
sectors: ReadonlyArray<PieSectorDataItem>
|
|
237
|
-
/** @deprecated */
|
|
238
|
-
activeShape?: ActiveShape<PieSectorDataItem>
|
|
239
|
-
/** @deprecated */
|
|
240
|
-
inactiveShape?: ActiveShape<PieSectorDataItem>
|
|
241
|
-
shape?: PieShape
|
|
242
|
-
labelLine?: PieLabelLine
|
|
243
|
-
label?: PieLabel
|
|
244
|
-
animationEasing: AnimationTiming
|
|
245
|
-
animationInterpolateFn: AnimationInterpolateFn<PieSectorDataItem, PolarLayout>
|
|
246
|
-
animationMatchBy: AnimationMatchByProp<PieSectorDataItem>
|
|
247
|
-
isAnimationActive: boolean | "auto"
|
|
248
|
-
animationBegin: number
|
|
249
|
-
animationDuration: AnimationDuration
|
|
250
|
-
onAnimationStart?: () => void
|
|
251
|
-
onAnimationEnd?: () => void
|
|
252
|
-
rootTabIndex?: number
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
interface PieProps<DataPointType = unknown, DataValueType = unknown>
|
|
256
|
-
extends
|
|
257
|
-
DataProvider<DataPointType>,
|
|
258
|
-
DataConsumer<DataPointType, DataValueType>,
|
|
259
|
-
PieDef,
|
|
260
|
-
PieEvents,
|
|
261
|
-
ZIndexable {
|
|
262
|
-
/**
|
|
263
|
-
* This component is rendered when this graphical item is activated
|
|
264
|
-
* (could be by mouse hover, touch, keyboard, programmatically).
|
|
265
|
-
*
|
|
266
|
-
* @deprecated Use the `shape` prop to create each sector. `isActive` designates the "active" shape.
|
|
267
|
-
* @example <Pie activeShape={<CustomActiveShape />} />
|
|
268
|
-
* @example https://recharts.github.io/examples/CustomActiveShapePieChart
|
|
269
|
-
*/
|
|
270
|
-
activeShape?: ActiveShape<PieSectorDataItem>
|
|
271
|
-
/**
|
|
272
|
-
* Specifies when the animation should begin, the unit of this option is ms.
|
|
273
|
-
* @defaultValue 400
|
|
274
|
-
*/
|
|
275
|
-
animationBegin?: number
|
|
276
|
-
/**
|
|
277
|
-
* Specifies the duration of animation, the unit of this option is ms.
|
|
278
|
-
* @defaultValue 1500
|
|
279
|
-
*/
|
|
280
|
-
animationDuration?: AnimationDuration
|
|
281
|
-
/**
|
|
282
|
-
* The type of easing function.
|
|
283
|
-
* @defaultValue ease
|
|
284
|
-
*/
|
|
285
|
-
animationEasing?: AnimationTiming
|
|
286
|
-
/**
|
|
287
|
-
* Custom animation function for interpolating data items.
|
|
288
|
-
* When provided, this replaces the default animation interpolation.
|
|
289
|
-
*
|
|
290
|
-
* @since 3.9
|
|
291
|
-
* @see {@link https://recharts.github.io/en-US/guide/animations/ Animations guide}
|
|
292
|
-
*/
|
|
293
|
-
animationInterpolateFn?: AnimationInterpolateFn<PieSectorDataItem, PolarLayout>
|
|
294
|
-
/**
|
|
295
|
-
* Strategy for matching previous items to next items during animation.
|
|
296
|
-
*
|
|
297
|
-
* - `matchAppend` (default): match sequentially by index and treat newly appended items as new
|
|
298
|
-
* - `matchByIndex`: match by array position with proportional stretching
|
|
299
|
-
* - `matchByDataKey('someKey')`: match by a data key from the payload
|
|
300
|
-
* - Custom function `(item, index) => key`: match by the returned key
|
|
301
|
-
*
|
|
302
|
-
* @defaultValue append
|
|
303
|
-
*/
|
|
304
|
-
animationMatchBy?: AnimationMatchByProp<PieSectorDataItem>
|
|
305
|
-
className?: string
|
|
306
|
-
/**
|
|
307
|
-
* Hides the whole graphical element when true.
|
|
308
|
-
*
|
|
309
|
-
* Hiding an element is different from removing it from the chart:
|
|
310
|
-
* Hidden graphical elements are still visible in Legend,
|
|
311
|
-
* and can be included in axis domain calculations,
|
|
312
|
-
* depending on `includeHidden` props of your XAxis/YAxis.
|
|
313
|
-
*
|
|
314
|
-
* @defaultValue false
|
|
315
|
-
*/
|
|
316
|
-
hide?: boolean
|
|
317
|
-
id?: string
|
|
318
|
-
/**
|
|
319
|
-
* The shape of inactive sector.
|
|
320
|
-
* @deprecated Use the `shape` prop to modify each sector.
|
|
321
|
-
*/
|
|
322
|
-
inactiveShape?: ActiveShape<PieSectorDataItem>
|
|
323
|
-
/**
|
|
324
|
-
* If set false, animation will be disabled.
|
|
325
|
-
* If set "auto", animation is disabled during SSR and when the user prefers reduced motion.
|
|
326
|
-
* @defaultValue auto
|
|
327
|
-
*/
|
|
328
|
-
isAnimationActive?: boolean | "auto"
|
|
329
|
-
/**
|
|
330
|
-
* Renders one label for each pie sector. Options:
|
|
331
|
-
* - `true`: renders default labels;
|
|
332
|
-
* - `false`: no labels are rendered;
|
|
333
|
-
* - `object` that has `position` prop: the props of LabelList component;
|
|
334
|
-
* - `object` that does not have `position` prop: the props of a custom Pie label (similar to Label with position "outside"); this variant supports `labelLine`
|
|
335
|
-
* - `Element`: a custom label element;
|
|
336
|
-
* - `function`: a render function of custom label.
|
|
337
|
-
*
|
|
338
|
-
* Also see the `labelLine` prop that draws a line connecting each label to the corresponding sector.
|
|
339
|
-
*
|
|
340
|
-
* @defaultValue false
|
|
341
|
-
* @example <Pie label={<CustomizedLabel />} />
|
|
342
|
-
* @example https://recharts.github.io/examples/PieChartWithCustomizedLabel
|
|
343
|
-
*/
|
|
344
|
-
label?: PieLabel
|
|
345
|
-
/**
|
|
346
|
-
* If false set, label lines will not be drawn. If true set, label lines will be drawn which have the props calculated internally.
|
|
347
|
-
* If object set, label lines will be drawn which have the props merged by the internal calculated props and the option.
|
|
348
|
-
* If set a function, the function will be called to render customized label line.
|
|
349
|
-
* @defaultValue true
|
|
350
|
-
* @example <Pie labelLine={<CustomizedLabelLine />} />
|
|
351
|
-
* @example https://recharts.github.io/examples/PieChartWithCustomizedLabel
|
|
352
|
-
*/
|
|
353
|
-
labelLine?: PieLabelLine
|
|
354
|
-
/**
|
|
355
|
-
* The type of icon in legend. If set to 'none', no legend item will be rendered.
|
|
356
|
-
* @defaultValue rect
|
|
357
|
-
*/
|
|
358
|
-
legendType?: LegendType
|
|
359
|
-
/** the max radius of pie */
|
|
360
|
-
maxRadius?: number
|
|
361
|
-
/**
|
|
362
|
-
* The minimum angle of each unzero data.
|
|
363
|
-
* @defaultValue 0
|
|
364
|
-
*/
|
|
365
|
-
minAngle?: number
|
|
366
|
-
/**
|
|
367
|
-
* The name of this graphical item, used in tooltip and legend.
|
|
368
|
-
*/
|
|
369
|
-
name?: string | number
|
|
370
|
-
/**
|
|
371
|
-
* Name represents each sector in the tooltip, and legend.
|
|
372
|
-
* This allows you to extract the name from the data:
|
|
373
|
-
*
|
|
374
|
-
* - `string`: the name of the field in the data object;
|
|
375
|
-
* - `number`: the index of the field in the data;
|
|
376
|
-
* - `function`: a function that receives the data object and returns the name.
|
|
377
|
-
*
|
|
378
|
-
* @defaultValue name
|
|
379
|
-
*/
|
|
380
|
-
nameKey?: DataKey<DataPointType, DataValueType>
|
|
381
|
-
/**
|
|
382
|
-
* The customized event handler of animation end.
|
|
383
|
-
*/
|
|
384
|
-
onAnimationEnd?: () => void
|
|
385
|
-
/**
|
|
386
|
-
* The customized event handler of animation start.
|
|
387
|
-
*/
|
|
388
|
-
onAnimationStart?: () => void
|
|
389
|
-
/**
|
|
390
|
-
* The tabindex of wrapper surrounding the cells.
|
|
391
|
-
* @defaultValue 0
|
|
392
|
-
*/
|
|
393
|
-
rootTabIndex?: number
|
|
394
|
-
/**
|
|
395
|
-
* The custom shape of a Pie Sector.
|
|
396
|
-
* Can also be used to render active sector by checking isActive.
|
|
397
|
-
* If undefined, renders Sector shape.
|
|
398
|
-
*/
|
|
399
|
-
shape?: PieShape
|
|
400
|
-
tooltipType?: TooltipType
|
|
401
|
-
/**
|
|
402
|
-
* Formats the value displayed in the tooltip for this Pie.
|
|
403
|
-
* When set, takes precedence over the `formatter` prop on the Tooltip component.
|
|
404
|
-
*/
|
|
405
|
-
formatter?: Formatter
|
|
406
|
-
/**
|
|
407
|
-
* @defaultValue 100
|
|
408
|
-
*/
|
|
409
|
-
zIndex?: number
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
type PieSvgAttributes = Omit<
|
|
413
|
-
PresentationAttributesAdaptChildEvent<unknown, SVGElement>,
|
|
414
|
-
"ref" | keyof PieEvents
|
|
415
|
-
>
|
|
416
|
-
|
|
417
|
-
type InternalProps = PieSvgAttributes & InternalPieProps
|
|
418
|
-
|
|
419
|
-
/* eslint-disable-next-line typescript-eslint/no-explicit-any -- upstream contract: untyped items accept any data */
|
|
420
|
-
export type Props<DataPointType = any, DataValueType = any> = PieSvgAttributes & PieProps<DataPointType, DataValueType>
|
|
421
|
-
|
|
422
|
-
type RealPieData = Record<string, unknown>
|
|
423
|
-
|
|
424
|
-
export type PieCoordinate = {
|
|
425
|
-
cx: number
|
|
426
|
-
cy: number
|
|
427
|
-
innerRadius: number
|
|
428
|
-
outerRadius: number
|
|
429
|
-
maxRadius: number
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
function SetPiePayloadLegend(props: { children?: JSX.Element; id: GraphicalItemId }): JSX.Element {
|
|
433
|
-
const ctx = useChartStore()
|
|
434
|
-
/* Solid does not support React.Children iteration; cells passed as undefined */
|
|
435
|
-
const legendPayload = createMemo(() =>
|
|
436
|
-
ctx ? selectPieLegend(ctx.store, props.id, undefined) : undefined,
|
|
437
|
-
)
|
|
438
|
-
return (
|
|
439
|
-
<Show when={legendPayload()}>
|
|
440
|
-
{(payload) => <SetPolarLegendPayload legendPayload={payload()} />}
|
|
441
|
-
</Show>
|
|
442
|
-
)
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
type PieSectorsProps = ShapeAnimationProps & {
|
|
446
|
-
sectors: Readonly<PieSectorDataItem[]>
|
|
447
|
-
/**
|
|
448
|
-
* @deprecated
|
|
449
|
-
*/
|
|
450
|
-
activeShape: ActiveShape<Readonly<PieSectorDataItem>> | undefined
|
|
451
|
-
/**
|
|
452
|
-
* @deprecated
|
|
453
|
-
*/
|
|
454
|
-
inactiveShape: ActiveShape<Readonly<PieSectorDataItem>> | undefined
|
|
455
|
-
shape: PieShape
|
|
456
|
-
allOtherPieProps: WithoutId<InternalProps>
|
|
457
|
-
id: GraphicalItemId
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
function getActiveShapeFill(
|
|
461
|
-
activeShape: ActiveShape<Readonly<PieSectorDataItem>> | undefined,
|
|
462
|
-
): string | undefined {
|
|
463
|
-
/* activeShape can be boolean/function/element/object; only element/object can carry a static fill value. */
|
|
464
|
-
if (activeShape == null || typeof activeShape === "boolean" || typeof activeShape === "function") {
|
|
465
|
-
return undefined
|
|
466
|
-
}
|
|
467
|
-
if (isJsxNode(activeShape)) {
|
|
468
|
-
/* Solid element form: the evaluated node carries `fill` as an attribute. */
|
|
469
|
-
const fill = activeShape instanceof Element ? activeShape.getAttribute("fill") : null
|
|
470
|
-
return fill ?? undefined
|
|
471
|
-
}
|
|
472
|
-
const { fill } = activeShape as { fill?: unknown }
|
|
473
|
-
return typeof fill === "string" ? fill : undefined
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
function SetPieTooltipEntrySettings(
|
|
477
|
-
props: Pick<
|
|
478
|
-
InternalProps,
|
|
479
|
-
| "activeShape"
|
|
480
|
-
| "dataKey"
|
|
481
|
-
| "nameKey"
|
|
482
|
-
| "sectors"
|
|
483
|
-
| "stroke"
|
|
484
|
-
| "strokeWidth"
|
|
485
|
-
| "fill"
|
|
486
|
-
| "name"
|
|
487
|
-
| "hide"
|
|
488
|
-
| "tooltipType"
|
|
489
|
-
| "formatter"
|
|
490
|
-
| "id"
|
|
491
|
-
>,
|
|
492
|
-
): JSX.Element {
|
|
493
|
-
/* GOTCHA-005: createMemo so reactive props flow into the settings object. */
|
|
494
|
-
const tooltipEntrySettings = createMemo<TooltipPayloadConfiguration>(() => {
|
|
495
|
-
const activeShapeFill = getActiveShapeFill(props.activeShape)
|
|
496
|
-
return {
|
|
497
|
-
dataDefinedOnItem: props.sectors.map((sector: PieSectorDataItem) => {
|
|
498
|
-
const sectorTooltipPayload = sector.tooltipPayload
|
|
499
|
-
if (activeShapeFill == null || sectorTooltipPayload == null) {
|
|
500
|
-
return sectorTooltipPayload
|
|
501
|
-
}
|
|
502
|
-
return sectorTooltipPayload.map((item) => ({
|
|
503
|
-
...item,
|
|
504
|
-
color: activeShapeFill,
|
|
505
|
-
fill: activeShapeFill,
|
|
506
|
-
}))
|
|
507
|
-
}),
|
|
508
|
-
getPosition: (index) => props.sectors[Number(index)]?.tooltipPosition,
|
|
509
|
-
settings: {
|
|
510
|
-
color: props.fill,
|
|
511
|
-
dataKey: props.dataKey,
|
|
512
|
-
fill: props.fill,
|
|
513
|
-
formatter: props.formatter,
|
|
514
|
-
graphicalItemId: props.id,
|
|
515
|
-
hide: props.hide,
|
|
516
|
-
name: getTooltipNameProp(props.name, props.dataKey),
|
|
517
|
-
nameKey: props.nameKey,
|
|
518
|
-
stroke: props.stroke,
|
|
519
|
-
strokeWidth: props.strokeWidth,
|
|
520
|
-
type: props.tooltipType,
|
|
521
|
-
unit: "",
|
|
522
|
-
},
|
|
523
|
-
}
|
|
524
|
-
})
|
|
525
|
-
return <SetTooltipEntrySettings tooltipEntrySettings={tooltipEntrySettings()} />
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
const getTextAnchor = (x: number, cx: number) => {
|
|
529
|
-
if (x > cx) {
|
|
530
|
-
return "start"
|
|
531
|
-
}
|
|
532
|
-
if (x < cx) {
|
|
533
|
-
return "end"
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
return "middle"
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
const getOuterRadius = (
|
|
540
|
-
dataPoint: unknown,
|
|
541
|
-
outerRadius: number | string | ((element: unknown) => number | string),
|
|
542
|
-
maxPieRadius: number,
|
|
543
|
-
) => {
|
|
544
|
-
if (typeof outerRadius === "function") {
|
|
545
|
-
return getPercentValue(outerRadius(dataPoint), maxPieRadius, maxPieRadius * 0.8)
|
|
546
|
-
}
|
|
547
|
-
return getPercentValue(outerRadius, maxPieRadius, maxPieRadius * 0.8)
|
|
548
|
-
}
|
|
549
|
-
|
|
550
|
-
const parseCoordinateOfPie = (
|
|
551
|
-
pieSettings: PieSettings,
|
|
552
|
-
offset: ChartOffsetInternal,
|
|
553
|
-
dataPoint: unknown,
|
|
554
|
-
): PieCoordinate => {
|
|
555
|
-
const { top, left, width, height } = offset
|
|
556
|
-
const maxPieRadius = getMaxRadius(width, height)
|
|
557
|
-
const cx = left + getPercentValue(pieSettings.cx, width, width / 2)
|
|
558
|
-
const cy = top + getPercentValue(pieSettings.cy, height, height / 2)
|
|
559
|
-
const innerRadius = getPercentValue(pieSettings.innerRadius, maxPieRadius, 0)
|
|
560
|
-
|
|
561
|
-
const outerRadius = getOuterRadius(dataPoint, pieSettings.outerRadius, maxPieRadius)
|
|
562
|
-
|
|
563
|
-
const maxRadius = pieSettings.maxRadius || Math.sqrt(width * width + height * height) / 2
|
|
564
|
-
|
|
565
|
-
return { cx, cy, innerRadius, maxRadius, outerRadius }
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
const parseDeltaAngle = (startAngle: number, endAngle: number) => {
|
|
569
|
-
const sign = mathSign(endAngle - startAngle)
|
|
570
|
-
const deltaAngle = Math.min(Math.abs(endAngle - startAngle), 360)
|
|
571
|
-
|
|
572
|
-
return sign * deltaAngle
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
function renderLabelLineItem(option: PieLabelLine, lineProps: CurveProps): JSX.Element {
|
|
576
|
-
if (typeof option === "function") {
|
|
577
|
-
return option(lineProps as Record<string, unknown>)
|
|
578
|
-
}
|
|
579
|
-
|
|
580
|
-
if (isJsxNode(option)) {
|
|
581
|
-
return <>{cloneJsxNodeWithProps(option, lineProps as unknown as Record<string, unknown>) as unknown as JSX.Element}</>
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
const className = clsx(
|
|
585
|
-
"recharts-pie-label-line",
|
|
586
|
-
typeof option !== "boolean"
|
|
587
|
-
? String((option as unknown as Record<string, unknown>).className ?? "")
|
|
588
|
-
: "",
|
|
589
|
-
)
|
|
590
|
-
return <Curve {...lineProps} type="linear" class={className} />
|
|
591
|
-
}
|
|
592
|
-
|
|
593
|
-
function renderLabelItem(
|
|
594
|
-
option: PieLabel,
|
|
595
|
-
labelProps: PieLabelRenderProps,
|
|
596
|
-
value: unknown,
|
|
597
|
-
): JSX.Element {
|
|
598
|
-
let label: unknown = value
|
|
599
|
-
if (typeof option === "function") {
|
|
600
|
-
label = option(labelProps)
|
|
601
|
-
/* if the function returned a JSX element, use it directly */
|
|
602
|
-
if (label != null && typeof label === "object") {
|
|
603
|
-
return label as JSX.Element
|
|
604
|
-
}
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
if (isJsxNode(option)) {
|
|
608
|
-
return <>{cloneJsxNodeWithProps(option, labelProps as unknown as Record<string, unknown>) as unknown as JSX.Element}</>
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
const className = clsx("recharts-pie-label-text", getClassNameFromUnknown(option))
|
|
612
|
-
const { style: labelStyle, ref: _labelRef, ...restLabelProps } = labelProps
|
|
613
|
-
return (
|
|
614
|
-
<Text
|
|
615
|
-
{...restLabelProps}
|
|
616
|
-
style={typeof labelStyle === "string" ? undefined : labelStyle}
|
|
617
|
-
textAnchor={labelProps.textAnchor as import("../component/Text").TextAnchor}
|
|
618
|
-
alignmentBaseline="middle"
|
|
619
|
-
className={className}
|
|
620
|
-
>
|
|
621
|
-
{label as string | number}
|
|
622
|
-
</Text>
|
|
623
|
-
)
|
|
624
|
-
}
|
|
625
|
-
|
|
626
|
-
/* eslint-disable solid/reactivity -- PieLabels reads are structural checks + map at setup; called from reactive JSX so props are stable per render */
|
|
627
|
-
function PieLabels(props: {
|
|
628
|
-
sectors: ReadonlyArray<PieSectorDataItem>
|
|
629
|
-
pieProps: WithoutId<InternalProps>
|
|
630
|
-
showLabels: boolean
|
|
631
|
-
}): JSX.Element {
|
|
632
|
-
return (
|
|
633
|
-
<Show when={!!props.showLabels && !!props.pieProps.label && props.sectors != null}>
|
|
634
|
-
<PieLabelsBody pieProps={props.pieProps} sectors={props.sectors} />
|
|
635
|
-
</Show>
|
|
636
|
-
)
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
function PieLabelsBody(props: {
|
|
640
|
-
sectors: ReadonlyArray<PieSectorDataItem>
|
|
641
|
-
pieProps: WithoutId<InternalProps>
|
|
642
|
-
}): JSX.Element {
|
|
643
|
-
const pieProps = createMemo(() => svgPropertiesNoEvents(props.pieProps))
|
|
644
|
-
const customLabelProps = createMemo(() =>
|
|
645
|
-
svgPropertiesNoEventsFromUnknown(props.pieProps.label),
|
|
646
|
-
)
|
|
647
|
-
const customLabelLineProps = createMemo(() =>
|
|
648
|
-
svgPropertiesNoEventsFromUnknown(props.pieProps.labelLine),
|
|
649
|
-
)
|
|
650
|
-
const offsetRadius = createMemo(() => {
|
|
651
|
-
const label = props.pieProps.label
|
|
652
|
-
if (
|
|
653
|
-
typeof label === "object" &&
|
|
654
|
-
label != null &&
|
|
655
|
-
"offsetRadius" in label &&
|
|
656
|
-
typeof label.offsetRadius === "number"
|
|
657
|
-
) {
|
|
658
|
-
return label.offsetRadius
|
|
659
|
-
}
|
|
660
|
-
return 20
|
|
661
|
-
})
|
|
662
|
-
|
|
663
|
-
return (
|
|
664
|
-
<Layer class="recharts-pie-labels">
|
|
665
|
-
<For each={props.sectors}>
|
|
666
|
-
{(entry: PieSectorDataItem, iAccessor) => {
|
|
667
|
-
const i = untrack(() => iAccessor())
|
|
668
|
-
const node = createMemo(() => {
|
|
669
|
-
const midAngle = (entry.startAngle + entry.endAngle) / 2
|
|
670
|
-
const endPoint = polarToCartesian(
|
|
671
|
-
entry.cx,
|
|
672
|
-
entry.cy,
|
|
673
|
-
entry.outerRadius + offsetRadius(),
|
|
674
|
-
midAngle,
|
|
675
|
-
)
|
|
676
|
-
const labelItemProps: PieLabelRenderProps = {
|
|
677
|
-
...pieProps(),
|
|
678
|
-
...entry,
|
|
679
|
-
stroke: "none",
|
|
680
|
-
...customLabelProps(),
|
|
681
|
-
index: i,
|
|
682
|
-
textAnchor: getTextAnchor(endPoint.x, entry.cx),
|
|
683
|
-
...endPoint,
|
|
684
|
-
} as PieLabelRenderProps
|
|
685
|
-
const lineProps: CurveProps = {
|
|
686
|
-
...pieProps(),
|
|
687
|
-
...entry,
|
|
688
|
-
fill: "none",
|
|
689
|
-
stroke: entry.fill,
|
|
690
|
-
...customLabelLineProps(),
|
|
691
|
-
index: i,
|
|
692
|
-
points: [
|
|
693
|
-
polarToCartesian(entry.cx, entry.cy, entry.outerRadius, midAngle),
|
|
694
|
-
endPoint,
|
|
695
|
-
],
|
|
696
|
-
} as CurveProps
|
|
697
|
-
|
|
698
|
-
return (
|
|
699
|
-
<ZIndexLayer zIndex={DefaultZIndexes.label}>
|
|
700
|
-
<Layer>
|
|
701
|
-
<Show when={props.pieProps.labelLine}>
|
|
702
|
-
{renderLabelLineItem(props.pieProps.labelLine as PieLabelLine, lineProps)}
|
|
703
|
-
</Show>
|
|
704
|
-
{renderLabelItem(
|
|
705
|
-
props.pieProps.label as PieLabel,
|
|
706
|
-
labelItemProps,
|
|
707
|
-
getValueByDataKey(
|
|
708
|
-
entry,
|
|
709
|
-
props.pieProps.dataKey as DataKey<PieSectorDataItem>,
|
|
710
|
-
),
|
|
711
|
-
)}
|
|
712
|
-
</Layer>
|
|
713
|
-
</ZIndexLayer>
|
|
714
|
-
)
|
|
715
|
-
})
|
|
716
|
-
return node as unknown as JSX.Element
|
|
717
|
-
}}
|
|
718
|
-
</For>
|
|
719
|
-
</Layer>
|
|
720
|
-
)
|
|
721
|
-
}
|
|
722
|
-
/* eslint-enable solid/reactivity */
|
|
723
|
-
|
|
724
|
-
/* eslint-disable solid/reactivity -- PieLabelList reads are structural type checks at setup; called from reactive JSX, stable per render */
|
|
725
|
-
function PieLabelList(props: {
|
|
726
|
-
sectors: ReadonlyArray<PieSectorDataItem>
|
|
727
|
-
pieProps: WithoutId<InternalProps>
|
|
728
|
-
showLabels: boolean
|
|
729
|
-
}): JSX.Element {
|
|
730
|
-
if (
|
|
731
|
-
typeof props.pieProps.label === "object" &&
|
|
732
|
-
props.pieProps.label != null &&
|
|
733
|
-
"position" in props.pieProps.label
|
|
734
|
-
) {
|
|
735
|
-
return <LabelListFromLabelProp label={props.pieProps.label} />
|
|
736
|
-
}
|
|
737
|
-
return (
|
|
738
|
-
<PieLabels sectors={props.sectors} pieProps={props.pieProps} showLabels={props.showLabels} />
|
|
739
|
-
)
|
|
740
|
-
}
|
|
741
|
-
/* eslint-enable solid/reactivity */
|
|
742
|
-
|
|
743
|
-
function PieSectors(props: PieSectorsProps): JSX.Element {
|
|
744
|
-
const ctx = useChartStore()
|
|
745
|
-
/* GOTCHA-016-C: one entry per pointer move across both event pairs, shared by all sectors. */
|
|
746
|
-
const hover = createHoverDedupe()
|
|
747
|
-
const activeIndex = createMemo(() =>
|
|
748
|
-
ctx ? selectActiveTooltipIndex(ctx.store) : undefined,
|
|
749
|
-
)
|
|
750
|
-
const activeDataKey = createMemo(() =>
|
|
751
|
-
ctx ? selectActiveTooltipDataKey(ctx.store) : undefined,
|
|
752
|
-
)
|
|
753
|
-
const activeGraphicalItemId = createMemo(() =>
|
|
754
|
-
ctx ? selectActiveTooltipGraphicalItemId(ctx.store) : undefined,
|
|
755
|
-
)
|
|
756
|
-
|
|
757
|
-
/* eslint-disable solid/reactivity -- id is a stable identifier; handler and dataKey sources are accessors read at event time; sectors null check is structural */
|
|
758
|
-
/* GOTCHA-005-D: pass live accessors — dot-access at hook setup snapshots the value. */
|
|
759
|
-
const onMouseEnterFromContext = useMouseEnterItemDispatch(
|
|
760
|
-
() => props.allOtherPieProps.onMouseEnter as never,
|
|
761
|
-
() => props.allOtherPieProps.dataKey,
|
|
762
|
-
props.id,
|
|
763
|
-
)
|
|
764
|
-
const onMouseLeaveFromContext = useMouseLeaveItemDispatch(
|
|
765
|
-
() => props.allOtherPieProps.onMouseLeave as never,
|
|
766
|
-
)
|
|
767
|
-
const onClickFromContext = useMouseClickItemDispatch(
|
|
768
|
-
() => props.allOtherPieProps.onClick as never,
|
|
769
|
-
() => props.allOtherPieProps.dataKey,
|
|
770
|
-
props.id,
|
|
771
|
-
)
|
|
772
|
-
/* Once per series, not per sector: the rest-spread copies every Pie prop. */
|
|
773
|
-
const restOfAllOtherProps = createMemo((): Record<string, unknown> => {
|
|
774
|
-
const { onMouseEnter, onClick, onMouseLeave, ...rest } =
|
|
775
|
-
props.allOtherPieProps as unknown as Record<string, unknown>
|
|
776
|
-
void onMouseEnter
|
|
777
|
-
void onClick
|
|
778
|
-
void onMouseLeave
|
|
779
|
-
return rest
|
|
780
|
-
})
|
|
781
|
-
|
|
782
|
-
/* eslint-enable solid/reactivity */
|
|
783
|
-
|
|
784
|
-
return (
|
|
785
|
-
<Show when={props.sectors != null && props.sectors.length > 0}>
|
|
786
|
-
<For each={props.sectors}>
|
|
787
|
-
{(entry: PieSectorDataItem, iAccessor) => {
|
|
788
|
-
/* eslint-disable-next-line solid/reactivity -- iAccessor() snapshotted intentionally; i is used as a static index, not a reactive signal, per GOTCHA-014-H */
|
|
789
|
-
const i = untrack(() => iAccessor())
|
|
790
|
-
/* GOTCHA-014-H: per-sector reactive snapshots live INSIDE For's child fn so
|
|
791
|
-
activeIndex/activeDataKey changes do NOT re-run the outer JSX expression
|
|
792
|
-
that holds the For. Solid's plain `arr.map` inside JSX wraps the whole
|
|
793
|
-
map in one memo — any reactive read in the body re-creates every DOM
|
|
794
|
-
node, dropping `$$click` event delegation bindings between the
|
|
795
|
-
pointermove/pointerdown of `userEvent.click`. */
|
|
796
|
-
const isHidden = createMemo(
|
|
797
|
-
() =>
|
|
798
|
-
entry?.startAngle === 0 &&
|
|
799
|
-
entry?.endAngle === 0 &&
|
|
800
|
-
props.sectors.length !== 1,
|
|
801
|
-
)
|
|
802
|
-
const graphicalItemMatches = createMemo(
|
|
803
|
-
() => activeGraphicalItemId() == null || activeGraphicalItemId() === props.id,
|
|
804
|
-
)
|
|
805
|
-
const isActive = createMemo(
|
|
806
|
-
() =>
|
|
807
|
-
String(i) === activeIndex() &&
|
|
808
|
-
(activeDataKey() == null || props.allOtherPieProps.dataKey === activeDataKey()) &&
|
|
809
|
-
graphicalItemMatches(),
|
|
810
|
-
)
|
|
811
|
-
/* Not memoized: an element option must be evaluated where Shape reads it, inside
|
|
812
|
-
its ShapeElementPropsProvider (each read of an element prop mints a new shape). */
|
|
813
|
-
const sectorOptions = () => {
|
|
814
|
-
if (isActive()) {
|
|
815
|
-
const activeShape = props.activeShape
|
|
816
|
-
if (activeShape) {
|
|
817
|
-
return activeShape
|
|
818
|
-
}
|
|
819
|
-
}
|
|
820
|
-
return activeIndex() ? props.inactiveShape : null
|
|
821
|
-
}
|
|
822
|
-
const sectorProps = {
|
|
823
|
-
...entry,
|
|
824
|
-
/* Getters: the spread into <Shape> reads these inside its tracked props. */
|
|
825
|
-
get animationElapsedTime() {
|
|
826
|
-
return props.animationElapsedTime
|
|
827
|
-
},
|
|
828
|
-
get isAnimating() {
|
|
829
|
-
return props.isAnimating
|
|
830
|
-
},
|
|
831
|
-
get isEntrance() {
|
|
832
|
-
return props.isEntrance
|
|
833
|
-
},
|
|
834
|
-
stroke: entry.stroke,
|
|
835
|
-
tabindex: -1,
|
|
836
|
-
[DATA_ITEM_INDEX_ATTRIBUTE_NAME]: i,
|
|
837
|
-
[DATA_ITEM_GRAPHICAL_ITEM_ID_ATTRIBUTE_NAME]: props.id,
|
|
838
|
-
}
|
|
839
|
-
|
|
840
|
-
/* GOTCHA-016-C: React's synthetic onMouseEnter/Leave fired on native mouseover/mouseout. Solid binds 1:1 — bind both pairs so fireEvent.mouseEnter, fireEvent.mouseOver, and user.hover all dispatch; dedupe via per-instance entry flag. Compose adapted user onMouseOver/Out handlers ahead of context dispatch. */
|
|
841
|
-
const adapted = (adaptEventsOfChild(untrack(() => restOfAllOtherProps()), entry, i) ?? {}) as Record<
|
|
842
|
-
string,
|
|
843
|
-
((e: Event) => void) | undefined
|
|
844
|
-
>
|
|
845
|
-
const enterHandler = onMouseEnterFromContext(entry, i)
|
|
846
|
-
const leaveHandler = onMouseLeaveFromContext(entry, i)
|
|
847
|
-
const userOver = adapted.onMouseOver
|
|
848
|
-
const userOut = adapted.onMouseOut
|
|
849
|
-
const fireEnter = (e: MouseEvent & { currentTarget: SVGElement }) => {
|
|
850
|
-
if (!hover.enter(e)) return
|
|
851
|
-
userOver?.(e)
|
|
852
|
-
enterHandler(e)
|
|
853
|
-
}
|
|
854
|
-
const fireLeave = (e: MouseEvent & { currentTarget: SVGElement }) => {
|
|
855
|
-
if (!hover.leave(e)) return
|
|
856
|
-
userOut?.(e)
|
|
857
|
-
leaveHandler(e)
|
|
858
|
-
}
|
|
859
|
-
const clickHandler = onClickFromContext(entry, i)
|
|
860
|
-
return (
|
|
861
|
-
<Show when={!isHidden()}>
|
|
862
|
-
<Layer
|
|
863
|
-
tabindex={-1}
|
|
864
|
-
class="recharts-pie-sector"
|
|
865
|
-
{...adapted}
|
|
866
|
-
onMouseEnter={fireEnter}
|
|
867
|
-
onMouseOver={fireEnter}
|
|
868
|
-
onMouseLeave={fireLeave}
|
|
869
|
-
onMouseOut={fireLeave}
|
|
870
|
-
onClick={clickHandler}
|
|
871
|
-
>
|
|
872
|
-
<Shape
|
|
873
|
-
option={props.shape ?? sectorOptions()}
|
|
874
|
-
index={i}
|
|
875
|
-
shapeType="sector"
|
|
876
|
-
isActive={isActive()}
|
|
877
|
-
{...sectorProps}
|
|
878
|
-
/>
|
|
879
|
-
</Layer>
|
|
880
|
-
</Show>
|
|
881
|
-
)
|
|
882
|
-
}}
|
|
883
|
-
</For>
|
|
884
|
-
</Show>
|
|
885
|
-
)
|
|
886
|
-
}
|
|
887
|
-
|
|
888
|
-
export function computePieSectors({
|
|
889
|
-
pieSettings,
|
|
890
|
-
displayedData,
|
|
891
|
-
cells,
|
|
892
|
-
offset,
|
|
893
|
-
}: {
|
|
894
|
-
pieSettings: PieSettings
|
|
895
|
-
displayedData: ChartData
|
|
896
|
-
cells: ReadonlyArray<JSX.Element> | undefined
|
|
897
|
-
offset: ChartOffsetInternal
|
|
898
|
-
}): ReadonlyArray<PieSectorDataItem> | undefined {
|
|
899
|
-
const { cornerRadius, startAngle, endAngle, dataKey, nameKey, tooltipType } = pieSettings
|
|
900
|
-
const minAngle = Math.abs(pieSettings.minAngle)
|
|
901
|
-
const deltaAngle = parseDeltaAngle(startAngle, endAngle)
|
|
902
|
-
const absDeltaAngle = Math.abs(deltaAngle)
|
|
903
|
-
const paddingAngle = displayedData.length <= 1 ? 0 : (pieSettings.paddingAngle ?? 0)
|
|
904
|
-
|
|
905
|
-
const notZeroItemCount = displayedData.filter(
|
|
906
|
-
(entry) => getValueByDataKey(entry, dataKey, 0) !== 0,
|
|
907
|
-
).length
|
|
908
|
-
const totalPaddingAngle =
|
|
909
|
-
(absDeltaAngle >= 360 ? notZeroItemCount : notZeroItemCount - 1) * paddingAngle
|
|
910
|
-
|
|
911
|
-
const sum = displayedData.reduce((result: number, entry: unknown) => {
|
|
912
|
-
const val = getValueByDataKey(entry, dataKey, 0)
|
|
913
|
-
return result + (isNumber(val) ? val : 0)
|
|
914
|
-
}, 0)
|
|
915
|
-
|
|
916
|
-
/*
|
|
917
|
-
* Only apply minAngle redistribution when at least one non-zero segment's
|
|
918
|
-
* natural angle falls below the minAngle threshold. Otherwise, minAngle
|
|
919
|
-
* unnecessarily shifts all segments even when none need the boost.
|
|
920
|
-
* See: https://github.com/recharts/recharts/issues/6814
|
|
921
|
-
*/
|
|
922
|
-
const needsMinAngleAdjustment =
|
|
923
|
-
minAngle > 0 &&
|
|
924
|
-
sum > 0 &&
|
|
925
|
-
displayedData.some((entry) => {
|
|
926
|
-
const val = getValueByDataKey(entry, dataKey, 0)
|
|
927
|
-
const percent = (isNumber(val) ? val : 0) / sum
|
|
928
|
-
return val !== 0 && percent * absDeltaAngle < minAngle
|
|
929
|
-
})
|
|
930
|
-
const effectiveMinAngle = needsMinAngleAdjustment ? minAngle : 0
|
|
931
|
-
|
|
932
|
-
const realTotalAngle = absDeltaAngle - notZeroItemCount * effectiveMinAngle - totalPaddingAngle
|
|
933
|
-
let sectors: PieSectorDataItem[] | undefined
|
|
934
|
-
|
|
935
|
-
if (sum > 0) {
|
|
936
|
-
let prev: PieSectorDataItem
|
|
937
|
-
sectors = displayedData.map((entry: unknown, i: number) => {
|
|
938
|
-
const val: number = getValueByDataKey(entry, dataKey, 0)
|
|
939
|
-
const name: string = getValueByDataKey(entry, nameKey, i)
|
|
940
|
-
const coordinate: PieCoordinate = parseCoordinateOfPie(pieSettings, offset, entry)
|
|
941
|
-
const percent = (isNumber(val) ? val : 0) / sum
|
|
942
|
-
let tempStartAngle: number
|
|
943
|
-
|
|
944
|
-
const entryWithCellInfo: RealPieData = {
|
|
945
|
-
...(entry as Record<string, unknown>),
|
|
946
|
-
...(cells && cells[i] && (cells[i] as unknown as { props: Record<string, unknown> }).props),
|
|
947
|
-
}
|
|
948
|
-
const sectorColor =
|
|
949
|
-
entryWithCellInfo != null && "fill" in entryWithCellInfo && typeof entryWithCellInfo.fill === "string"
|
|
950
|
-
? entryWithCellInfo.fill
|
|
951
|
-
: pieSettings.fill
|
|
952
|
-
|
|
953
|
-
if (i) {
|
|
954
|
-
tempStartAngle = prev.endAngle + mathSign(deltaAngle) * paddingAngle * (val !== 0 ? 1 : 0)
|
|
955
|
-
} else {
|
|
956
|
-
tempStartAngle = startAngle
|
|
957
|
-
}
|
|
958
|
-
|
|
959
|
-
const tempEndAngle =
|
|
960
|
-
tempStartAngle +
|
|
961
|
-
mathSign(deltaAngle) * ((val !== 0 ? effectiveMinAngle : 0) + percent * realTotalAngle)
|
|
962
|
-
const midAngle = (tempStartAngle + tempEndAngle) / 2
|
|
963
|
-
const middleRadius = (coordinate.innerRadius + coordinate.outerRadius) / 2
|
|
964
|
-
|
|
965
|
-
const tooltipPayload: TooltipPayload = [
|
|
966
|
-
{
|
|
967
|
-
color: sectorColor,
|
|
968
|
-
dataKey,
|
|
969
|
-
fill: sectorColor,
|
|
970
|
-
graphicalItemId: pieSettings.id,
|
|
971
|
-
name,
|
|
972
|
-
payload: entryWithCellInfo,
|
|
973
|
-
type: tooltipType,
|
|
974
|
-
value: val,
|
|
975
|
-
},
|
|
976
|
-
]
|
|
977
|
-
const tooltipPosition = polarToCartesian(coordinate.cx, coordinate.cy, middleRadius, midAngle)
|
|
978
|
-
|
|
979
|
-
prev = {
|
|
980
|
-
...pieSettings.presentationProps,
|
|
981
|
-
percent,
|
|
982
|
-
cornerRadius: typeof cornerRadius === "string" ? parseFloat(cornerRadius) : cornerRadius,
|
|
983
|
-
name,
|
|
984
|
-
tooltipPayload,
|
|
985
|
-
midAngle,
|
|
986
|
-
middleRadius,
|
|
987
|
-
tooltipPosition,
|
|
988
|
-
...entryWithCellInfo,
|
|
989
|
-
...coordinate,
|
|
990
|
-
value: val,
|
|
991
|
-
dataKey,
|
|
992
|
-
startAngle: tempStartAngle,
|
|
993
|
-
endAngle: tempEndAngle,
|
|
994
|
-
payload: entryWithCellInfo,
|
|
995
|
-
paddingAngle: val !== 0 ? mathSign(deltaAngle) * paddingAngle : 0,
|
|
996
|
-
} as PieSectorDataItem
|
|
997
|
-
return prev
|
|
998
|
-
})
|
|
999
|
-
}
|
|
1000
|
-
return sectors
|
|
1001
|
-
}
|
|
1002
|
-
|
|
1003
|
-
function PieLabelListProvider(props: {
|
|
1004
|
-
showLabels: boolean
|
|
1005
|
-
sectors: ReadonlyArray<PieSectorDataItem>
|
|
1006
|
-
children: JSX.Element
|
|
1007
|
-
}): JSX.Element {
|
|
1008
|
-
const labelListEntries = createMemo((): ReadonlyArray<PolarLabelListEntry> => {
|
|
1009
|
-
if (!props.showLabels || !props.sectors) {
|
|
1010
|
-
return []
|
|
1011
|
-
}
|
|
1012
|
-
return props.sectors.map(
|
|
1013
|
-
(entry): PolarLabelListEntry => ({
|
|
1014
|
-
clockWise: false,
|
|
1015
|
-
fill: entry.fill,
|
|
1016
|
-
parentViewBox: undefined,
|
|
1017
|
-
payload: entry.payload,
|
|
1018
|
-
value: entry.value,
|
|
1019
|
-
viewBox: {
|
|
1020
|
-
clockWise: false,
|
|
1021
|
-
cx: entry.cx,
|
|
1022
|
-
cy: entry.cy,
|
|
1023
|
-
endAngle: entry.endAngle,
|
|
1024
|
-
innerRadius: entry.innerRadius,
|
|
1025
|
-
outerRadius: entry.outerRadius,
|
|
1026
|
-
startAngle: entry.startAngle,
|
|
1027
|
-
},
|
|
1028
|
-
}),
|
|
1029
|
-
)
|
|
1030
|
-
})
|
|
1031
|
-
/* eslint-disable solid/reactivity -- Provider value reads labelListEntries() and props.showLabels inside JSX attribute; both are reactive */
|
|
1032
|
-
return (
|
|
1033
|
-
<PolarLabelListContextProvider value={props.showLabels ? labelListEntries() : undefined}>
|
|
1034
|
-
{props.children}
|
|
1035
|
-
</PolarLabelListContextProvider>
|
|
1036
|
-
)
|
|
1037
|
-
/* eslint-enable solid/reactivity */
|
|
1038
|
-
}
|
|
1039
|
-
|
|
1040
|
-
type WithoutId<T> = Omit<T, "id">
|
|
1041
|
-
|
|
1042
|
-
const defaultPieAnimateItems: AnimationInterpolateFn<PieSectorDataItem, PolarLayout> = (
|
|
1043
|
-
items,
|
|
1044
|
-
animationElapsedTime,
|
|
1045
|
-
) => {
|
|
1046
|
-
if (items == null) return []
|
|
1047
|
-
const stepData: PieSectorDataItem[] = []
|
|
1048
|
-
const firstNonRemoved = items.find((item) => item.status !== "removed")
|
|
1049
|
-
let curAngle: number = firstNonRemoved ? firstNonRemoved.next.startAngle : 0
|
|
1050
|
-
|
|
1051
|
-
items.forEach((item, index) => {
|
|
1052
|
-
if (item.status === "removed") return
|
|
1053
|
-
const paddingAngle = index > 0 ? get(item.next, "paddingAngle", 0) : 0
|
|
1054
|
-
|
|
1055
|
-
if (item.status === "matched") {
|
|
1056
|
-
const angle = interpolate(
|
|
1057
|
-
item.prev.endAngle - item.prev.startAngle,
|
|
1058
|
-
item.next.endAngle - item.next.startAngle,
|
|
1059
|
-
animationElapsedTime,
|
|
1060
|
-
)
|
|
1061
|
-
const latest = {
|
|
1062
|
-
...item.next,
|
|
1063
|
-
endAngle: curAngle + angle + paddingAngle,
|
|
1064
|
-
startAngle: curAngle + paddingAngle,
|
|
1065
|
-
}
|
|
1066
|
-
stepData.push(latest)
|
|
1067
|
-
curAngle = latest.endAngle
|
|
1068
|
-
} else {
|
|
1069
|
-
// added
|
|
1070
|
-
const deltaAngle = interpolate(0, item.next.endAngle - item.next.startAngle, animationElapsedTime)
|
|
1071
|
-
const latest = {
|
|
1072
|
-
...item.next,
|
|
1073
|
-
endAngle: curAngle + deltaAngle + paddingAngle,
|
|
1074
|
-
startAngle: curAngle + paddingAngle,
|
|
1075
|
-
}
|
|
1076
|
-
stepData.push(latest)
|
|
1077
|
-
curAngle = latest.endAngle
|
|
1078
|
-
}
|
|
1079
|
-
})
|
|
1080
|
-
return stepData
|
|
1081
|
-
}
|
|
1082
|
-
|
|
1083
|
-
function SectorsWithAnimation(props: {
|
|
1084
|
-
pieProps: WithoutId<InternalProps>
|
|
1085
|
-
id: GraphicalItemId
|
|
1086
|
-
previousSectorsRef: { current: ReadonlyArray<PieSectorDataItem> | null }
|
|
1087
|
-
}): JSX.Element {
|
|
1088
|
-
const { isAnimating, handleAnimationStart, handleAnimationEnd } = useAnimationCallbacks(
|
|
1089
|
-
() => props.pieProps.onAnimationStart,
|
|
1090
|
-
() => props.pieProps.onAnimationEnd,
|
|
1091
|
-
)
|
|
1092
|
-
const layout = createMemo(() => usePolarChartLayout())
|
|
1093
|
-
|
|
1094
|
-
return (
|
|
1095
|
-
<Show when={layout()}>
|
|
1096
|
-
{(polarLayout) => (
|
|
1097
|
-
<PieLabelListProvider showLabels={!isAnimating()} sectors={props.pieProps.sectors}>
|
|
1098
|
-
<AnimatedItems
|
|
1099
|
-
animationInput={props.pieProps.sectors}
|
|
1100
|
-
animationIdPrefix="recharts-pie-"
|
|
1101
|
-
items={props.pieProps.sectors}
|
|
1102
|
-
previousItemsRef={props.previousSectorsRef}
|
|
1103
|
-
isAnimationActive={props.pieProps.isAnimationActive}
|
|
1104
|
-
animationBegin={props.pieProps.animationBegin}
|
|
1105
|
-
animationDuration={props.pieProps.animationDuration}
|
|
1106
|
-
animationEasing={props.pieProps.animationEasing}
|
|
1107
|
-
onAnimationStart={handleAnimationStart}
|
|
1108
|
-
onAnimationEnd={handleAnimationEnd}
|
|
1109
|
-
animationInterpolateFn={props.pieProps.animationInterpolateFn}
|
|
1110
|
-
animationMatchBy={props.pieProps.animationMatchBy}
|
|
1111
|
-
layout={polarLayout()}
|
|
1112
|
-
>
|
|
1113
|
-
{(stepData, animationElapsedTime, isEntrance) => (
|
|
1114
|
-
<Layer>
|
|
1115
|
-
<PieSectors
|
|
1116
|
-
sectors={stepData()}
|
|
1117
|
-
activeShape={props.pieProps.activeShape}
|
|
1118
|
-
inactiveShape={props.pieProps.inactiveShape}
|
|
1119
|
-
allOtherPieProps={props.pieProps}
|
|
1120
|
-
shape={props.pieProps.shape}
|
|
1121
|
-
id={props.id}
|
|
1122
|
-
animationElapsedTime={animationElapsedTime()}
|
|
1123
|
-
isAnimating={isAnimating() || animationElapsedTime() < 1}
|
|
1124
|
-
isEntrance={isEntrance()}
|
|
1125
|
-
/>
|
|
1126
|
-
</Layer>
|
|
1127
|
-
)}
|
|
1128
|
-
</AnimatedItems>
|
|
1129
|
-
<PieLabelList
|
|
1130
|
-
showLabels={!isAnimating()}
|
|
1131
|
-
sectors={props.pieProps.sectors}
|
|
1132
|
-
pieProps={props.pieProps}
|
|
1133
|
-
/>
|
|
1134
|
-
</PieLabelListProvider>
|
|
1135
|
-
)}
|
|
1136
|
-
</Show>
|
|
1137
|
-
)
|
|
1138
|
-
}
|
|
1139
|
-
|
|
1140
|
-
function RenderSectors(props: {
|
|
1141
|
-
pieProps: WithoutId<InternalProps>
|
|
1142
|
-
id: GraphicalItemId
|
|
1143
|
-
}): JSX.Element {
|
|
1144
|
-
const previousSectorsRef: { current: ReadonlyArray<PieSectorDataItem> | null } = {
|
|
1145
|
-
current: null,
|
|
1146
|
-
}
|
|
1147
|
-
return (
|
|
1148
|
-
<SectorsWithAnimation
|
|
1149
|
-
pieProps={props.pieProps}
|
|
1150
|
-
id={props.id}
|
|
1151
|
-
previousSectorsRef={previousSectorsRef}
|
|
1152
|
-
/>
|
|
1153
|
-
)
|
|
1154
|
-
}
|
|
1155
|
-
|
|
1156
|
-
export const defaultPieProps = {
|
|
1157
|
-
animationBegin: 400,
|
|
1158
|
-
animationDuration: 1500,
|
|
1159
|
-
animationEasing: "ease",
|
|
1160
|
-
animationInterpolateFn: defaultPieAnimateItems,
|
|
1161
|
-
animationMatchBy: matchAppend,
|
|
1162
|
-
cx: "50%",
|
|
1163
|
-
cy: "50%",
|
|
1164
|
-
dataKey: "value",
|
|
1165
|
-
endAngle: 360,
|
|
1166
|
-
fill: "#808080",
|
|
1167
|
-
hide: false,
|
|
1168
|
-
innerRadius: 0,
|
|
1169
|
-
isAnimationActive: "auto",
|
|
1170
|
-
label: false,
|
|
1171
|
-
labelLine: true,
|
|
1172
|
-
legendType: "rect",
|
|
1173
|
-
minAngle: 0,
|
|
1174
|
-
nameKey: "name",
|
|
1175
|
-
outerRadius: "80%",
|
|
1176
|
-
paddingAngle: 0,
|
|
1177
|
-
rootTabIndex: 0,
|
|
1178
|
-
startAngle: 0,
|
|
1179
|
-
stroke: "#fff",
|
|
1180
|
-
zIndex: DefaultZIndexes.area,
|
|
1181
|
-
} as const satisfies Partial<Props>
|
|
1182
|
-
|
|
1183
|
-
function PieChildrenScope(props: { childrenProps: { children?: JSX.Element } }): JSX.Element {
|
|
1184
|
-
/* GOTCHA-017: memoize children INSIDE PolarLabelContext + CellsContext so
|
|
1185
|
-
Label/Cell createComponent runs with those providers as owner. Reading
|
|
1186
|
-
`children` as a JSX child of PieImpl mints Label outside polar context. */
|
|
1187
|
-
const memoizedChildren = createMemo(() => props.childrenProps.children)
|
|
1188
|
-
return <>{memoizedChildren()}</>
|
|
1189
|
-
}
|
|
1190
|
-
|
|
1191
|
-
function PieImpl(
|
|
1192
|
-
props: Omit<InternalProps, "sectors"> & { childrenProps: { children?: JSX.Element } },
|
|
1193
|
-
): JSX.Element {
|
|
1194
|
-
/* keep `props` reactive end-to-end. destructuring/spreading freezes the Solid
|
|
1195
|
-
props proxy at this scope and downstream sectors/animation lose live updates. */
|
|
1196
|
-
const [idProps, rest] = splitProps(props, ["id"])
|
|
1197
|
-
const [childrenBag, propsWithoutId] = splitProps(rest, ["childrenProps"])
|
|
1198
|
-
const id = (): GraphicalItemId => idProps.id
|
|
1199
|
-
const ctx = useChartStore()
|
|
1200
|
-
const stateCtx = useContext(RechartsStateContext)
|
|
1201
|
-
|
|
1202
|
-
/* GOTCHA-013/017: Cell children register into this registry from inside the
|
|
1203
|
-
Provider scope; cells() returns insertion-ordered { props } records that
|
|
1204
|
-
selectPieSectors merges into per-sector data (fill/stroke/etc). */
|
|
1205
|
-
const cellsRegistry = createCellsRegistry()
|
|
1206
|
-
/* perf: memo so downstream selectors don't re-derive on every registry signal write
|
|
1207
|
-
that doesn't change the resolved array reference (e.g. no-op Cell re-renders). */
|
|
1208
|
-
const cells = createMemo((): ReadonlyArray<Record<string, unknown>> | undefined => {
|
|
1209
|
-
const list = cellsRegistry.cells()
|
|
1210
|
-
return list.length === 0 ? undefined : (list as unknown as ReadonlyArray<Record<string, unknown>>)
|
|
1211
|
-
})
|
|
1212
|
-
|
|
1213
|
-
const sectors = createMemo(() => {
|
|
1214
|
-
/* When new chartState has a settings entry, pass it as override so mutations
|
|
1215
|
-
to graphicalItems[id].settings (fine-grained Solid store) invalidate this
|
|
1216
|
-
memo and drive re-derivation without touching the legacy store. */
|
|
1217
|
-
const solidEntry = stateCtx?.state.graphicalItems[id()]
|
|
1218
|
-
const pieOverride =
|
|
1219
|
-
solidEntry != null && solidEntry.type === "pie"
|
|
1220
|
-
? (solidEntry.settings as PieSettings)
|
|
1221
|
-
: undefined
|
|
1222
|
-
return ctx ? selectPieSectors(ctx.store, id(), cells(), pieOverride) : undefined
|
|
1223
|
-
})
|
|
1224
|
-
|
|
1225
|
-
const layerClass = (): string => clsx("recharts-pie", props.className)
|
|
1226
|
-
const firstSector = createMemo(() => sectors()?.[0])
|
|
1227
|
-
|
|
1228
|
-
return (
|
|
1229
|
-
<LabelListContextBridge>
|
|
1230
|
-
{/* Children always mount so <Cell/>s register even before any sector exists (they
|
|
1231
|
-
can be the only data source); polar labels wait until the first sector. */}
|
|
1232
|
-
<PolarLabelContextProvider
|
|
1233
|
-
pending={firstSector() == null}
|
|
1234
|
-
cx={firstSector()?.cx ?? 0}
|
|
1235
|
-
cy={firstSector()?.cy ?? 0}
|
|
1236
|
-
innerRadius={firstSector()?.innerRadius ?? 0}
|
|
1237
|
-
outerRadius={firstSector()?.outerRadius ?? 0}
|
|
1238
|
-
startAngle={props.startAngle ?? 0}
|
|
1239
|
-
endAngle={props.endAngle ?? 0}
|
|
1240
|
-
clockWise={false}
|
|
1241
|
-
>
|
|
1242
|
-
<CellsContextProvider value={cellsRegistry}>
|
|
1243
|
-
<PieChildrenScope childrenProps={childrenBag.childrenProps} />
|
|
1244
|
-
</CellsContextProvider>
|
|
1245
|
-
</PolarLabelContextProvider>
|
|
1246
|
-
<Show
|
|
1247
|
-
when={!props.hide && sectors() != null}
|
|
1248
|
-
fallback={<Layer tabindex={props.rootTabIndex} class={layerClass()} />}
|
|
1249
|
-
>
|
|
1250
|
-
{(() => {
|
|
1251
|
-
const sx = (): Readonly<PieSectorDataItem[]> => sectors() ?? []
|
|
1252
|
-
const renderProps = mergeProps(propsWithoutId, {
|
|
1253
|
-
get sectors() {
|
|
1254
|
-
return sx()
|
|
1255
|
-
},
|
|
1256
|
-
}) as WithoutId<InternalProps>
|
|
1257
|
-
return (
|
|
1258
|
-
<ZIndexLayer zIndex={props.zIndex}>
|
|
1259
|
-
<SetPieTooltipEntrySettings
|
|
1260
|
-
activeShape={props.activeShape}
|
|
1261
|
-
dataKey={props.dataKey}
|
|
1262
|
-
nameKey={props.nameKey}
|
|
1263
|
-
sectors={sx()}
|
|
1264
|
-
stroke={props.stroke}
|
|
1265
|
-
strokeWidth={props.strokeWidth}
|
|
1266
|
-
fill={props.fill}
|
|
1267
|
-
name={props.name}
|
|
1268
|
-
hide={props.hide}
|
|
1269
|
-
tooltipType={props.tooltipType}
|
|
1270
|
-
formatter={props.formatter}
|
|
1271
|
-
id={id()}
|
|
1272
|
-
/>
|
|
1273
|
-
<Layer tabindex={props.rootTabIndex} class={layerClass()}>
|
|
1274
|
-
<RenderSectors pieProps={renderProps} id={id()} />
|
|
1275
|
-
</Layer>
|
|
1276
|
-
</ZIndexLayer>
|
|
1277
|
-
)
|
|
1278
|
-
})()}
|
|
1279
|
-
</Show>
|
|
1280
|
-
</LabelListContextBridge>
|
|
1281
|
-
)
|
|
1282
|
-
}
|
|
1283
|
-
|
|
1284
|
-
type PropsWithResolvedDefaults = RequiresDefaultProps<Props, typeof defaultPieProps>
|
|
1285
|
-
|
|
1286
|
-
/**
|
|
1287
|
-
* @consumes PolarChartContext
|
|
1288
|
-
* @provides LabelListContext
|
|
1289
|
-
* @provides CellReader
|
|
1290
|
-
*/
|
|
1291
|
-
function PieFn(outsideProps: Props): JSX.Element {
|
|
1292
|
-
/* GOTCHA-013: split children before resolveDefaultProps. The destructure
|
|
1293
|
-
`{ id, ...propsWithoutId } = resolveDefaultProps(...)` and the subsequent
|
|
1294
|
-
`{...propsWithoutId}` spreads enumerate the props proxy and read `children`
|
|
1295
|
-
eagerly — Cell/etc. children invoke before RegisterGraphicalItemId installs
|
|
1296
|
-
its Provider. */
|
|
1297
|
-
const [childrenProps, restProps] = splitProps(outsideProps, ["children"])
|
|
1298
|
-
const props: PropsWithResolvedDefaults = resolveDefaultProps(restProps, defaultPieProps)
|
|
1299
|
-
const [idProps, propsWithoutId] = splitProps(props, ["id"])
|
|
1300
|
-
const presentationProps = createMemo(
|
|
1301
|
-
(): PiePresentationProps | null => svgPropertiesNoEvents(propsWithoutId),
|
|
1302
|
-
)
|
|
1303
|
-
|
|
1304
|
-
return (
|
|
1305
|
-
<RegisterGraphicalItemId id={idProps.id} type="pie">
|
|
1306
|
-
{(id: GraphicalItemId) => {
|
|
1307
|
-
/* GOTCHA-017: do NOT evaluate childrenProps.children here — Cell
|
|
1308
|
-
createComponent calls would fire BEFORE PieImpl mounts its
|
|
1309
|
-
cellsRegistry Provider. Pass `childrenProps` reference; PieImpl
|
|
1310
|
-
memoizes inside its own Provider scope. */
|
|
1311
|
-
return (
|
|
1312
|
-
<>
|
|
1313
|
-
<SetPolarGraphicalItem
|
|
1314
|
-
type="pie"
|
|
1315
|
-
id={id}
|
|
1316
|
-
data={propsWithoutId.data}
|
|
1317
|
-
dataKey={propsWithoutId.dataKey}
|
|
1318
|
-
hide={propsWithoutId.hide}
|
|
1319
|
-
angleAxisId={0}
|
|
1320
|
-
radiusAxisId={0}
|
|
1321
|
-
name={propsWithoutId.name}
|
|
1322
|
-
nameKey={propsWithoutId.nameKey}
|
|
1323
|
-
tooltipType={propsWithoutId.tooltipType}
|
|
1324
|
-
legendType={propsWithoutId.legendType}
|
|
1325
|
-
fill={propsWithoutId.fill}
|
|
1326
|
-
cx={propsWithoutId.cx}
|
|
1327
|
-
cy={propsWithoutId.cy}
|
|
1328
|
-
startAngle={propsWithoutId.startAngle}
|
|
1329
|
-
endAngle={propsWithoutId.endAngle}
|
|
1330
|
-
paddingAngle={propsWithoutId.paddingAngle}
|
|
1331
|
-
minAngle={propsWithoutId.minAngle}
|
|
1332
|
-
innerRadius={propsWithoutId.innerRadius}
|
|
1333
|
-
outerRadius={propsWithoutId.outerRadius}
|
|
1334
|
-
cornerRadius={propsWithoutId.cornerRadius}
|
|
1335
|
-
presentationProps={presentationProps()}
|
|
1336
|
-
maxRadius={props.maxRadius}
|
|
1337
|
-
/>
|
|
1338
|
-
<SetPiePayloadLegend {...propsWithoutId} id={id} />
|
|
1339
|
-
<PieImpl
|
|
1340
|
-
{...(propsWithoutId as Omit<InternalProps, "sectors" | "id">)}
|
|
1341
|
-
id={id}
|
|
1342
|
-
childrenProps={childrenProps}
|
|
1343
|
-
/>
|
|
1344
|
-
</>
|
|
1345
|
-
)
|
|
1346
|
-
}}
|
|
1347
|
-
</RegisterGraphicalItemId>
|
|
1348
|
-
)
|
|
1349
|
-
}
|
|
1350
|
-
|
|
1351
|
-
/**
|
|
1352
|
-
* Typed entry point: the generics constrain props at the call site, like upstream.
|
|
1353
|
-
*/
|
|
1354
|
-
/* eslint-disable-next-line typescript-eslint/no-explicit-any -- upstream contract: untyped usage accepts any data */
|
|
1355
|
-
export const Pie = PieFn as {
|
|
1356
|
-
<DataPointType = any, DataValueType = any>(props: Props<DataPointType, DataValueType>): JSX.Element
|
|
1357
|
-
/* eslint-disable-next-line typescript-eslint/no-explicit-any -- upstream fallback overload for mismatched data/dataKey */
|
|
1358
|
-
(props: Props<any, any>): JSX.Element
|
|
1359
|
-
displayName?: string
|
|
1360
|
-
}
|