solid-recharts 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (639) hide show
  1. package/NEXT_SESSION_PROMPT.md +114 -0
  2. package/package.json +28 -0
  3. package/src/animation/AnimatedItems.tsx +169 -0
  4. package/src/animation/AnimationController.ts +24 -0
  5. package/src/animation/AnimationControllerImpl.ts +37 -0
  6. package/src/animation/AnimationHandle.ts +273 -0
  7. package/src/animation/CSSTransitionAnimate.tsx +142 -0
  8. package/src/animation/JavascriptAnimate.tsx +107 -0
  9. package/src/animation/easing.ts +261 -0
  10. package/src/animation/matchBy.ts +211 -0
  11. package/src/animation/timeoutController.ts +51 -0
  12. package/src/animation/useAnimationController.tsx +31 -0
  13. package/src/animation/useAnimationStartSnapshot.ts +73 -0
  14. package/src/animation/util.ts +16 -0
  15. package/src/cartesian/Area.tsx +810 -0
  16. package/src/cartesian/AreaRevealShape.tsx +250 -0
  17. package/src/cartesian/Bar.tsx +1216 -0
  18. package/src/cartesian/BarStack.tsx +148 -0
  19. package/src/cartesian/Brush.tsx +653 -0
  20. package/src/cartesian/CartesianAxis.tsx +541 -0
  21. package/src/cartesian/CartesianGrid.tsx +605 -0
  22. package/src/cartesian/ErrorBar.tsx +319 -0
  23. package/src/cartesian/Funnel.tsx +594 -0
  24. package/src/cartesian/GraphicalItemClipPath.tsx +75 -0
  25. package/src/cartesian/Line.tsx +742 -0
  26. package/src/cartesian/LineDrawShape.tsx +190 -0
  27. package/src/cartesian/ReferenceArea.tsx +275 -0
  28. package/src/cartesian/ReferenceDot.tsx +286 -0
  29. package/src/cartesian/ReferenceLine.tsx +414 -0
  30. package/src/cartesian/RenderedTicksReporter.tsx +49 -0
  31. package/src/cartesian/Scatter.tsx +741 -0
  32. package/src/cartesian/XAxis.tsx +293 -0
  33. package/src/cartesian/YAxis.tsx +333 -0
  34. package/src/cartesian/ZAxis.tsx +80 -0
  35. package/src/cartesian/getCartesianPosition.ts +255 -0
  36. package/src/cartesian/getEquidistantTicks.ts +126 -0
  37. package/src/cartesian/getTicks.ts +225 -0
  38. package/src/cartesian/useAnimatedLineLength.ts +84 -0
  39. package/src/chart/AreaChart.tsx +30 -0
  40. package/src/chart/BarChart.tsx +27 -0
  41. package/src/chart/CartesianChart.tsx +91 -0
  42. package/src/chart/CategoricalChart.tsx +60 -0
  43. package/src/chart/ComposedChart.tsx +29 -0
  44. package/src/chart/FunnelChart.tsx +29 -0
  45. package/src/chart/LineChart.tsx +29 -0
  46. package/src/chart/PieChart.tsx +41 -0
  47. package/src/chart/PolarChart.tsx +97 -0
  48. package/src/chart/RadarChart.tsx +37 -0
  49. package/src/chart/RadialBarChart.tsx +39 -0
  50. package/src/chart/RechartsWrapper.tsx +486 -0
  51. package/src/chart/Sankey.tsx +992 -0
  52. package/src/chart/ScatterChart.tsx +29 -0
  53. package/src/chart/SunburstChart.tsx +394 -0
  54. package/src/chart/Treemap.tsx +874 -0
  55. package/src/chart/types.ts +37 -0
  56. package/src/component/ActivePoints.tsx +136 -0
  57. package/src/component/Cell.tsx +72 -0
  58. package/src/component/Cursor.tsx +249 -0
  59. package/src/component/Customized.tsx +8 -0
  60. package/src/component/DefaultLegendContent.tsx +205 -0
  61. package/src/component/DefaultTooltipContent.tsx +247 -0
  62. package/src/component/Dots.tsx +128 -0
  63. package/src/component/Label.tsx +507 -0
  64. package/src/component/LabelList.tsx +270 -0
  65. package/src/component/Legend.tsx +273 -0
  66. package/src/component/ResponsiveContainer.tsx +397 -0
  67. package/src/component/Text.tsx +436 -0
  68. package/src/component/Tooltip.tsx +309 -0
  69. package/src/component/TooltipBoundingBox.tsx +152 -0
  70. package/src/component/responsiveContainerUtils.ts +128 -0
  71. package/src/container/ClipPathProvider.tsx +40 -0
  72. package/src/container/Layer.tsx +38 -0
  73. package/src/container/RootSurface.tsx +124 -0
  74. package/src/container/Surface.tsx +70 -0
  75. package/src/context/ErrorBarContext.tsx +85 -0
  76. package/src/context/PanoramaContext.tsx +13 -0
  77. package/src/context/RegisterGraphicalItemId.tsx +41 -0
  78. package/src/context/accessibilityContext.tsx +10 -0
  79. package/src/context/brushUpdateContext.ts +14 -0
  80. package/src/context/chartDataContext.tsx +79 -0
  81. package/src/context/chartLayoutContext.tsx +158 -0
  82. package/src/context/legendPayloadContext.ts +11 -0
  83. package/src/context/legendPortalContext.ts +11 -0
  84. package/src/context/tooltipContext.ts +72 -0
  85. package/src/context/tooltipPortalContext.ts +14 -0
  86. package/src/context/useTooltipAxis.ts +24 -0
  87. package/src/hooks.ts +312 -0
  88. package/src/index.ts +288 -0
  89. package/src/polar/Pie.tsx +912 -0
  90. package/src/polar/PolarAngleAxis.tsx +494 -0
  91. package/src/polar/PolarGrid.tsx +269 -0
  92. package/src/polar/PolarRadiusAxis.tsx +422 -0
  93. package/src/polar/Radar.tsx +652 -0
  94. package/src/polar/RadialBar.tsx +767 -0
  95. package/src/polar/defaultPolarAngleAxisProps.tsx +33 -0
  96. package/src/polar/defaultPolarRadiusAxisProps.tsx +28 -0
  97. package/src/shape/Cross.tsx +83 -0
  98. package/src/shape/Curve.tsx +335 -0
  99. package/src/shape/Dot.tsx +49 -0
  100. package/src/shape/Polygon.tsx +168 -0
  101. package/src/shape/Rectangle.tsx +301 -0
  102. package/src/shape/Sector.tsx +304 -0
  103. package/src/shape/Symbols.tsx +144 -0
  104. package/src/shape/Trapezoid.tsx +228 -0
  105. package/src/state/RechartsReduxContext.tsx +8 -0
  106. package/src/state/RechartsStoreContext.ts +15 -0
  107. package/src/state/RechartsStoreProvider.tsx +27 -0
  108. package/src/state/ReportChartProps.tsx +19 -0
  109. package/src/state/ReportEventSettings.tsx +19 -0
  110. package/src/state/ReportMainChartProps.tsx +35 -0
  111. package/src/state/ReportPolarOptions.tsx +28 -0
  112. package/src/state/SetLegendPayload.ts +50 -0
  113. package/src/state/SetTooltipEntrySettings.tsx +46 -0
  114. package/src/state/brushSlice.ts +60 -0
  115. package/src/state/cartesianAxisSlice.ts +288 -0
  116. package/src/state/chartDataSlice.ts +115 -0
  117. package/src/state/errorBarSlice.ts +84 -0
  118. package/src/state/eventSettingsSlice.ts +41 -0
  119. package/src/state/externalEventsMiddleware.ts +136 -0
  120. package/src/state/graphicalItemsSlice.ts +162 -0
  121. package/src/state/hooks.ts +42 -0
  122. package/src/state/keyboardEventsMiddleware.ts +213 -0
  123. package/src/state/layoutSlice.ts +71 -0
  124. package/src/state/legendSlice.ts +107 -0
  125. package/src/state/mouseEventsMiddleware.ts +103 -0
  126. package/src/state/optionsSlice.ts +64 -0
  127. package/src/state/polarAxisSlice.ts +65 -0
  128. package/src/state/polarOptionsSlice.ts +54 -0
  129. package/src/state/reduxDevtoolsJsonStringifyReplacer.ts +15 -0
  130. package/src/state/referenceElementsSlice.ts +121 -0
  131. package/src/state/renderedTicksSlice.ts +61 -0
  132. package/src/state/rootPropsSlice.ts +70 -0
  133. package/src/state/selectors/areaSelectors.ts +169 -0
  134. package/src/state/selectors/arrayEqualityCheck.ts +8 -0
  135. package/src/state/selectors/axisSelectors.ts +2196 -0
  136. package/src/state/selectors/barSelectors.ts +319 -0
  137. package/src/state/selectors/barStackSelectors.ts +79 -0
  138. package/src/state/selectors/brushSelectors.ts +40 -0
  139. package/src/state/selectors/combiners/combineActiveLabel.ts +21 -0
  140. package/src/state/selectors/combiners/combineActiveTooltipIndex.ts +93 -0
  141. package/src/state/selectors/combiners/combineAllBarPositions.ts +131 -0
  142. package/src/state/selectors/combiners/combineAxisRangeWithReverse.ts +17 -0
  143. package/src/state/selectors/combiners/combineBarPosition.ts +24 -0
  144. package/src/state/selectors/combiners/combineBarSizeList.ts +75 -0
  145. package/src/state/selectors/combiners/combineCheckedDomain.ts +49 -0
  146. package/src/state/selectors/combiners/combineConfiguredScale.ts +121 -0
  147. package/src/state/selectors/combiners/combineCoordinateForDefaultIndex.ts +43 -0
  148. package/src/state/selectors/combiners/combineDisplayedStackedData.ts +50 -0
  149. package/src/state/selectors/combiners/combineInverseScaleFunction.ts +17 -0
  150. package/src/state/selectors/combiners/combineRealScaleType.ts +48 -0
  151. package/src/state/selectors/combiners/combineStackedData.ts +28 -0
  152. package/src/state/selectors/combiners/combineTooltipInteractionState.ts +86 -0
  153. package/src/state/selectors/combiners/combineTooltipPayload.ts +203 -0
  154. package/src/state/selectors/combiners/combineTooltipPayloadConfigurations.ts +45 -0
  155. package/src/state/selectors/containerSelectors.ts +12 -0
  156. package/src/state/selectors/dataSelectors.ts +90 -0
  157. package/src/state/selectors/funnelSelectors.ts +83 -0
  158. package/src/state/selectors/graphicalItemSelectors.ts +23 -0
  159. package/src/state/selectors/legendSelectors.ts +29 -0
  160. package/src/state/selectors/lineSelectors.ts +111 -0
  161. package/src/state/selectors/numberDomainEqualityCheck.ts +8 -0
  162. package/src/state/selectors/pickAxisId.ts +6 -0
  163. package/src/state/selectors/pickAxisType.ts +4 -0
  164. package/src/state/selectors/pieSelectors.ts +103 -0
  165. package/src/state/selectors/polarAxisSelectors.ts +202 -0
  166. package/src/state/selectors/polarGridSelectors.ts +24 -0
  167. package/src/state/selectors/polarScaleSelectors.ts +149 -0
  168. package/src/state/selectors/polarSelectors.ts +211 -0
  169. package/src/state/selectors/radarSelectors.ts +152 -0
  170. package/src/state/selectors/radialBarSelectors.ts +328 -0
  171. package/src/state/selectors/rootPropsSelectors.ts +36 -0
  172. package/src/state/selectors/scatterSelectors.ts +77 -0
  173. package/src/state/selectors/selectAllAxes.ts +10 -0
  174. package/src/state/selectors/selectChartOffset.ts +15 -0
  175. package/src/state/selectors/selectChartOffsetInternal.ts +111 -0
  176. package/src/state/selectors/selectPlotArea.ts +27 -0
  177. package/src/state/selectors/selectTooltipAxisId.ts +6 -0
  178. package/src/state/selectors/selectTooltipAxisType.ts +33 -0
  179. package/src/state/selectors/selectTooltipEventType.ts +45 -0
  180. package/src/state/selectors/selectTooltipPayloadSearcher.ts +7 -0
  181. package/src/state/selectors/selectTooltipSettings.ts +6 -0
  182. package/src/state/selectors/selectTooltipState.ts +5 -0
  183. package/src/state/selectors/tooltipSelectors.ts +690 -0
  184. package/src/state/selectors/touchSelectors.ts +29 -0
  185. package/src/state/store.ts +167 -0
  186. package/src/state/tooltipSlice.ts +289 -0
  187. package/src/state/types/AreaSettings.ts +17 -0
  188. package/src/state/types/BarSettings.ts +16 -0
  189. package/src/state/types/LineSettings.ts +12 -0
  190. package/src/state/types/PieSettings.ts +32 -0
  191. package/src/state/types/RadarSettings.ts +6 -0
  192. package/src/state/types/RadialBarSettings.ts +10 -0
  193. package/src/state/types/ScatterSettings.ts +13 -0
  194. package/src/state/types/StackedGraphicalItem.ts +33 -0
  195. package/src/state/unregisterOnCleanup.ts +26 -0
  196. package/src/state/zIndexSlice.ts +128 -0
  197. package/src/synchronisation/syncRegistry.ts +131 -0
  198. package/src/synchronisation/syncSelectors.ts +7 -0
  199. package/src/synchronisation/types.ts +42 -0
  200. package/src/synchronisation/useChartSynchronisation.tsx +372 -0
  201. package/src/types.ts +39 -0
  202. package/src/util/ActiveShapeUtils.tsx +80 -0
  203. package/src/util/BarUtils.tsx +74 -0
  204. package/src/util/CartesianUtils.ts +53 -0
  205. package/src/util/ChartUtils.ts +696 -0
  206. package/src/util/Constants.ts +42 -0
  207. package/src/util/CssPrefixUtils.ts +24 -0
  208. package/src/util/DOMUtils.ts +141 -0
  209. package/src/util/DataUtils.ts +205 -0
  210. package/src/util/FunnelUtils.tsx +37 -0
  211. package/src/util/Global.ts +15 -0
  212. package/src/util/IfOverflow.ts +17 -0
  213. package/src/util/LRUCache.ts +46 -0
  214. package/src/util/LogUtils.ts +26 -0
  215. package/src/util/PolarUtils.ts +134 -0
  216. package/src/util/RadialBarUtils.tsx +35 -0
  217. package/src/util/ReduceCSSCalc.ts +186 -0
  218. package/src/util/ShallowEqual.ts +43 -0
  219. package/src/util/TickUtils.ts +61 -0
  220. package/src/util/YAxisUtils.ts +49 -0
  221. package/src/util/adaptEventHandlers.ts +69 -0
  222. package/src/util/axisPropsAreEqual.ts +42 -0
  223. package/src/util/collectionUtils.ts +83 -0
  224. package/src/util/createCartesianCharts.tsx +101 -0
  225. package/src/util/createEventProxy.ts +24 -0
  226. package/src/util/createPolarCharts.tsx +86 -0
  227. package/src/util/cursor/getCursorPoints.ts +48 -0
  228. package/src/util/cursor/getCursorRectangle.ts +31 -0
  229. package/src/util/cursor/getRadialCursorPoints.ts +34 -0
  230. package/src/util/excludeEventProps.ts +172 -0
  231. package/src/util/getActiveCoordinate.ts +205 -0
  232. package/src/util/getAxisTypeBasedOnLayout.ts +21 -0
  233. package/src/util/getEveryNth.ts +30 -0
  234. package/src/util/getRadiusAndStrokeWidthFromDot.ts +35 -0
  235. package/src/util/getRelativeCoordinate.ts +84 -0
  236. package/src/util/getSliced.ts +21 -0
  237. package/src/util/isDomainSpecifiedByUser.ts +217 -0
  238. package/src/util/isWellBehavedNumber.ts +10 -0
  239. package/src/util/objectPath.ts +129 -0
  240. package/src/util/payload/getUniqPayload.ts +31 -0
  241. package/src/util/propsAreEqual.ts +137 -0
  242. package/src/util/resolveDefaultProps.tsx +8 -0
  243. package/src/util/round.ts +35 -0
  244. package/src/util/scale/CartesianScaleHelper.ts +72 -0
  245. package/src/util/scale/CustomScaleDefinition.ts +82 -0
  246. package/src/util/scale/RechartsScale.ts +131 -0
  247. package/src/util/scale/createCategoricalInverse.ts +83 -0
  248. package/src/util/scale/getNiceTickValues.ts +334 -0
  249. package/src/util/scale/index.ts +3 -0
  250. package/src/util/scale/util/DecimalLite.ts +194 -0
  251. package/src/util/scale/util/arithmetic.ts +56 -0
  252. package/src/util/stacks/getStackSeriesIdentifier.ts +20 -0
  253. package/src/util/stacks/stackTypes.ts +53 -0
  254. package/src/util/svgPropertiesAndEvents.ts +84 -0
  255. package/src/util/svgPropertiesNoEvents.ts +520 -0
  256. package/src/util/tooltip/translate.ts +179 -0
  257. package/src/util/typedDataKey.ts +8 -0
  258. package/src/util/types.ts +724 -0
  259. package/src/util/useAnimationId.tsx +31 -0
  260. package/src/util/useElementOffset.ts +164 -0
  261. package/src/util/useId.ts +20 -0
  262. package/src/util/usePrefersReducedMotion.ts +44 -0
  263. package/src/util/useUniqueId.ts +34 -0
  264. package/src/zIndex/DefaultZIndexes.tsx +87 -0
  265. package/src/zIndex/ZIndexLayer.tsx +126 -0
  266. package/src/zIndex/ZIndexPortal.tsx +69 -0
  267. package/src/zIndex/getZIndexFromUnknown.tsx +17 -0
  268. package/src/zIndex/zIndexSelectors.ts +46 -0
  269. package/test/_data.ts +408 -0
  270. package/test/animation/AnimationController.typed.spec.ts +53 -0
  271. package/test/animation/AnimationControllerImpl.spec.ts +271 -0
  272. package/test/animation/CSSTransitionAnimate.timing.spec.tsx +473 -0
  273. package/test/animation/JavascriptAnimate.spec.tsx +62 -0
  274. package/test/animation/RechartsAnimation.spec.ts +636 -0
  275. package/test/animation/easing.spec.ts +218 -0
  276. package/test/animation/legacyAnimationLengthChange.spec.tsx +803 -0
  277. package/test/animation/matchBy.spec.ts +467 -0
  278. package/test/animation/mockAnimationController.ts +40 -0
  279. package/test/animation/mockControllerAnimationManager.ts +143 -0
  280. package/test/animation/mockTimeoutController.ts +114 -0
  281. package/test/animation/timeoutController.spec.ts +138 -0
  282. package/test/animation/useAnimationStartSnapshot.spec.ts +147 -0
  283. package/test/animation/util.spec.ts +28 -0
  284. package/test/cartesian/Area.animation.spec.tsx +363 -0
  285. package/test/cartesian/Area.range.spec.tsx +54 -0
  286. package/test/cartesian/Area.spec.tsx +1202 -0
  287. package/test/cartesian/Area.stacked.render.spec.tsx +69 -0
  288. package/test/cartesian/Area.typed.spec.tsx +209 -0
  289. package/test/cartesian/Axis.integration.spec.tsx +158 -0
  290. package/test/cartesian/Bar/Bar.csstransition.spec.tsx +299 -0
  291. package/test/cartesian/Bar/Bar.spec.tsx +2314 -0
  292. package/test/cartesian/Bar/Bar.typed.spec.tsx +192 -0
  293. package/test/cartesian/Bar.animation.spec.tsx +426 -0
  294. package/test/cartesian/Bar.stackDomain.spec.tsx +66 -0
  295. package/test/cartesian/Bar.stacked.render.spec.tsx +53 -0
  296. package/test/cartesian/Bar.truncateByDomain.spec.tsx +237 -0
  297. package/test/cartesian/Bar.zeroDimensionFiltering.spec.tsx +336 -0
  298. package/test/cartesian/BarStack.spec.tsx +91 -0
  299. package/test/cartesian/Brush.keyboard.spec.tsx +88 -0
  300. package/test/cartesian/Brush.panorama.spec.tsx +41 -0
  301. package/test/cartesian/Brush.props.spec.tsx +63 -0
  302. package/test/cartesian/Brush.render.spec.tsx +117 -0
  303. package/test/cartesian/Brush.spec.tsx +522 -0
  304. package/test/cartesian/Brush.stacked.spec.tsx +221 -0
  305. package/test/cartesian/CartesianAxis.render.spec.tsx +50 -0
  306. package/test/cartesian/CartesianAxis.spec.tsx +396 -0
  307. package/test/cartesian/CartesianGrid.render.spec.tsx +39 -0
  308. package/test/cartesian/CartesianGrid.spec.tsx +2103 -0
  309. package/test/cartesian/ErrorBar.render.spec.tsx +69 -0
  310. package/test/cartesian/ErrorBar.spec.tsx +2414 -0
  311. package/test/cartesian/Funnel.animation.spec.tsx +241 -0
  312. package/test/cartesian/Funnel.spec.tsx +226 -0
  313. package/test/cartesian/Funnel.typed.spec.tsx +221 -0
  314. package/test/cartesian/GraphicalItemClipPath.scale-behavior.spec.tsx +627 -0
  315. package/test/cartesian/GraphicalItemClipPath.spec.tsx +427 -0
  316. package/test/cartesian/Line.animation.spec.tsx +643 -0
  317. package/test/cartesian/Line.sparseAnimationPath.spec.tsx +98 -0
  318. package/test/cartesian/Line.spec.tsx +471 -0
  319. package/test/cartesian/Line.typed.spec.tsx +152 -0
  320. package/test/cartesian/ReferenceArea.render.spec.tsx +63 -0
  321. package/test/cartesian/ReferenceArea.spec.tsx +663 -0
  322. package/test/cartesian/ReferenceArea.typed.spec.tsx +74 -0
  323. package/test/cartesian/ReferenceDot.render.spec.tsx +55 -0
  324. package/test/cartesian/ReferenceDot.spec.tsx +462 -0
  325. package/test/cartesian/ReferenceDot.typed.spec.tsx +76 -0
  326. package/test/cartesian/ReferenceLine/ReferenceLine.panorama.spec.tsx +184 -0
  327. package/test/cartesian/ReferenceLine/ReferenceLine.spec.tsx +744 -0
  328. package/test/cartesian/ReferenceLine/ReferenceLine.typed.spec.tsx +74 -0
  329. package/test/cartesian/ReferenceLine/getEndPoints.spec.ts +399 -0
  330. package/test/cartesian/ReferenceLine.render.spec.tsx +134 -0
  331. package/test/cartesian/Scatter.animation.spec.tsx +381 -0
  332. package/test/cartesian/Scatter.render.spec.tsx +61 -0
  333. package/test/cartesian/Scatter.spec.tsx +406 -0
  334. package/test/cartesian/Scatter.typed.spec.tsx +153 -0
  335. package/test/cartesian/XAxis/XAxis.barSize.spec.tsx +336 -0
  336. package/test/cartesian/XAxis/XAxis.brush.spec.tsx +266 -0
  337. package/test/cartesian/XAxis/XAxis.categorydomain.spec.tsx +872 -0
  338. package/test/cartesian/XAxis/XAxis.dataKey.spec.tsx +86 -0
  339. package/test/cartesian/XAxis/XAxis.datatypes.spec.tsx +127 -0
  340. package/test/cartesian/XAxis/XAxis.hide.spec.tsx +106 -0
  341. package/test/cartesian/XAxis/XAxis.multiaxis.spec.tsx +336 -0
  342. package/test/cartesian/XAxis/XAxis.numberdomain.spec.tsx +1466 -0
  343. package/test/cartesian/XAxis/XAxis.padding.spec.tsx +758 -0
  344. package/test/cartesian/XAxis/XAxis.padding_clip.spec.tsx +65 -0
  345. package/test/cartesian/XAxis/XAxis.state.spec.tsx +355 -0
  346. package/test/cartesian/XAxis/XAxis.tick.spec.tsx +493 -0
  347. package/test/cartesian/XAxis/XAxis.timescale.spec.tsx +233 -0
  348. package/test/cartesian/XAxis/XAxis.type.spec.tsx +107 -0
  349. package/test/cartesian/XAxis/XAxis.typed.spec.tsx +102 -0
  350. package/test/cartesian/XAxis/XAxis.vertical.spec.tsx +265 -0
  351. package/test/cartesian/XAxis.tickFormatter.spec.tsx +54 -0
  352. package/test/cartesian/YAxis/YAxis.7362.derivedDomain.spec.tsx +230 -0
  353. package/test/cartesian/YAxis/YAxis.7362.spec.tsx +104 -0
  354. package/test/cartesian/YAxis/YAxis.interval-zero.spec.tsx +88 -0
  355. package/test/cartesian/YAxis/YAxis.label.spec.tsx +219 -0
  356. package/test/cartesian/YAxis/YAxis.spec.tsx +1595 -0
  357. package/test/cartesian/YAxis/YAxis.tick.spec.tsx +428 -0
  358. package/test/cartesian/YAxis/YAxis.tickFormatter.spec.tsx +54 -0
  359. package/test/cartesian/YAxis/YAxis.ticks.spec.tsx +263 -0
  360. package/test/cartesian/YAxis/YAxis.type.spec.tsx +107 -0
  361. package/test/cartesian/YAxis/YAxis.typed.spec.tsx +102 -0
  362. package/test/cartesian/ZAxis.spec.tsx +300 -0
  363. package/test/cartesian/ZAxis.typed.spec.tsx +33 -0
  364. package/test/cartesian/__snapshots__/Brush.spec.tsx.snap +5 -0
  365. package/test/cartesian/axisLineAndStroke.spec.tsx +72 -0
  366. package/test/cartesian/getCartesianPosition.spec.ts +907 -0
  367. package/test/cartesian/getEquidistantTicks.spec.ts +88 -0
  368. package/test/cartesian/getTicks.spec.ts +378 -0
  369. package/test/cartesian/miscFeatureGaps.spec.tsx +89 -0
  370. package/test/cartesian/useAnimatedLineLength.spec.ts +168 -0
  371. package/test/chart/AccessibilityLayer.spec.tsx +569 -0
  372. package/test/chart/AccessibilityScans.spec.tsx +286 -0
  373. package/test/chart/AreaChart.spec.tsx +409 -0
  374. package/test/chart/AreaChart.stacked.spec.tsx +1407 -0
  375. package/test/chart/AreaChart.typed.spec.tsx +39 -0
  376. package/test/chart/BarChart.spec.tsx +3719 -0
  377. package/test/chart/BarChart.typed.spec.tsx +60 -0
  378. package/test/chart/CategoricalChart.spec.tsx +255 -0
  379. package/test/chart/ComposedChart.spec.tsx +199 -0
  380. package/test/chart/ComposedChart.typed.spec.tsx +39 -0
  381. package/test/chart/FunnelChart.spec.tsx +215 -0
  382. package/test/chart/FunnelChart.typed.spec.tsx +39 -0
  383. package/test/chart/LineChart.multiseries.spec.tsx +50 -0
  384. package/test/chart/LineChart.smoke.spec.tsx +50 -0
  385. package/test/chart/LineChart.spec.tsx +930 -0
  386. package/test/chart/LineChart.typed.spec.tsx +39 -0
  387. package/test/chart/NicheChartTooltip.spec.tsx +81 -0
  388. package/test/chart/PieChart.spec.tsx +793 -0
  389. package/test/chart/PieChart.typed.spec.tsx +39 -0
  390. package/test/chart/RadarChart.spec.tsx +530 -0
  391. package/test/chart/RadarChart.typed.spec.tsx +39 -0
  392. package/test/chart/RadialBarChart.5966.spec.tsx +48 -0
  393. package/test/chart/RadialBarChart.spec.tsx +679 -0
  394. package/test/chart/RadialBarChart.typed.spec.tsx +39 -0
  395. package/test/chart/RechartsWrapper.spec.tsx +83 -0
  396. package/test/chart/Sankey.content.spec.tsx +46 -0
  397. package/test/chart/Sankey.spec.tsx +952 -0
  398. package/test/chart/Sankey.typed.spec.tsx +29 -0
  399. package/test/chart/ScatterChart.spec.tsx +2613 -0
  400. package/test/chart/ScatterChart.typed.spec.tsx +39 -0
  401. package/test/chart/SunburstChart.spec.tsx +146 -0
  402. package/test/chart/Treemap.animation.spec.tsx +52 -0
  403. package/test/chart/Treemap.spec.tsx +1003 -0
  404. package/test/chart/Treemap.typed.spec.tsx +26 -0
  405. package/test/chart/chartEvents.spec.tsx +127 -0
  406. package/test/chart/responsive.spec.tsx +620 -0
  407. package/test/component/Cell.render.spec.tsx +155 -0
  408. package/test/component/Cell.spec.tsx +12 -0
  409. package/test/component/Cursor.spec.tsx +186 -0
  410. package/test/component/DefaultTooltipContent.spec.tsx +102 -0
  411. package/test/component/Label.render.spec.tsx +63 -0
  412. package/test/component/Label.spec.tsx +686 -0
  413. package/test/component/Label.typed.spec.tsx +46 -0
  414. package/test/component/LabelList.spec.tsx +188 -0
  415. package/test/component/Legend.itemSorter.spec.tsx +704 -0
  416. package/test/component/Legend.render.spec.tsx +92 -0
  417. package/test/component/Legend.spec.tsx +2213 -0
  418. package/test/component/Legend.typed.spec.tsx +22 -0
  419. package/test/component/ResponsiveContainer.spec.tsx +523 -0
  420. package/test/component/ResponsiveContainerDataTest.spec.tsx +51 -0
  421. package/test/component/Text.spec.tsx +415 -0
  422. package/test/component/Text.typed.spec.tsx +46 -0
  423. package/test/component/Tooltip/ActiveDot.spec.tsx +370 -0
  424. package/test/component/Tooltip/Tooltip.animation.spec.tsx +209 -0
  425. package/test/component/Tooltip/Tooltip.content.spec.tsx +128 -0
  426. package/test/component/Tooltip/Tooltip.formatter.spec.tsx +152 -0
  427. package/test/component/Tooltip/Tooltip.includeHidden.spec.tsx +79 -0
  428. package/test/component/Tooltip/Tooltip.multipleDataArrays.spec.tsx +165 -0
  429. package/test/component/Tooltip/Tooltip.offset.spec.tsx +113 -0
  430. package/test/component/Tooltip/Tooltip.state.spec.tsx +74 -0
  431. package/test/component/Tooltip/Tooltip.sync.spec.tsx +639 -0
  432. package/test/component/Tooltip/defaultIndex.spec.tsx +227 -0
  433. package/test/component/Tooltip/graphicalItem.formatter.spec.tsx +138 -0
  434. package/test/component/Tooltip/itemSorter.spec.tsx +2815 -0
  435. package/test/component/Tooltip/tooltipEventType.spec.tsx +344 -0
  436. package/test/component/Tooltip/tooltipMouseHoverSelectors.ts +41 -0
  437. package/test/component/Tooltip/tooltipTestHelpers.tsx +162 -0
  438. package/test/component/Tooltip.defaultIndex.spec.tsx +48 -0
  439. package/test/component/Tooltip.hover.spec.tsx +61 -0
  440. package/test/component/Tooltip.item.spec.tsx +54 -0
  441. package/test/component/Tooltip.keyboard.spec.tsx +51 -0
  442. package/test/component/Tooltip.payload.spec.tsx +1716 -0
  443. package/test/component/Tooltip.touch.spec.tsx +39 -0
  444. package/test/component/Tooltip.visibility.spec.tsx +1889 -0
  445. package/test/component/TooltipBoundingBox.spec.tsx +89 -0
  446. package/test/component/responsiveContainerUtils.spec.ts +205 -0
  447. package/test/container/ClipPath.spec.tsx +602 -0
  448. package/test/container/chartDimensions.spec.tsx +368 -0
  449. package/test/context/chartLayoutContext.spec.tsx +378 -0
  450. package/test/helper/ExpectAxisDomain.tsx +27 -0
  451. package/test/helper/assertNotNull.ts +6 -0
  452. package/test/helper/assertZIndexLayerOrder.ts +19 -0
  453. package/test/helper/createSelectorTestCase.tsx +176 -0
  454. package/test/helper/expectAnimatedPieAngles.ts +100 -0
  455. package/test/helper/expectAnimatedPiePaths.ts +78 -0
  456. package/test/helper/expectAreaCurve.ts +15 -0
  457. package/test/helper/expectAxisTicks.ts +48 -0
  458. package/test/helper/expectBars.ts +54 -0
  459. package/test/helper/expectFunctionReturning.ts +58 -0
  460. package/test/helper/expectLabel.ts +32 -0
  461. package/test/helper/expectLastCalledWith.ts +48 -0
  462. package/test/helper/expectLine.ts +20 -0
  463. package/test/helper/expectPieSectors.ts +80 -0
  464. package/test/helper/expectScale.ts +37 -0
  465. package/test/helper/expectScatterPoints.ts +52 -0
  466. package/test/helper/expectStackGroups.ts +144 -0
  467. package/test/helper/mockAxes.ts +22 -0
  468. package/test/helper/mockGetBoundingClientRect.ts +66 -0
  469. package/test/helper/mockHTMLElementProperty.ts +19 -0
  470. package/test/helper/mockTouchingElement.ts +27 -0
  471. package/test/helper/offsetHelpers.ts +19 -0
  472. package/test/helper/parameterizedTestCases.tsx +99 -0
  473. package/test/helper/produceState.ts +32 -0
  474. package/test/helper/render.ts +7 -0
  475. package/test/helper/selectorTestHelpers.tsx +63 -0
  476. package/test/helper/trim.spec.ts +35 -0
  477. package/test/helper/trim.ts +11 -0
  478. package/test/hooks/useActiveTooltipDataPoints.spec.tsx +358 -0
  479. package/test/hooks/useAxisDomain.spec.tsx +361 -0
  480. package/test/hooks/useAxisScale.spec.tsx +283 -0
  481. package/test/hooks/useAxisTicks.spec.tsx +130 -0
  482. package/test/hooks/useOffset.spec.tsx +248 -0
  483. package/test/hooks/useTooltipStateHooks.spec.tsx +109 -0
  484. package/test/polar/Pie/Pie-TwoLevelPieChart.spec.tsx +135 -0
  485. package/test/polar/Pie/Pie.spec.tsx +784 -0
  486. package/test/polar/Pie/Pie.typed.spec.tsx +78 -0
  487. package/test/polar/Pie.animation.spec.tsx +529 -0
  488. package/test/polar/PieWithLegend.animation.spec.tsx +142 -0
  489. package/test/polar/PolarAngleAxis/PolarAngleAxis.events.spec.tsx +76 -0
  490. package/test/polar/PolarAngleAxis/PolarAngleAxis.spec.tsx +2079 -0
  491. package/test/polar/PolarAngleAxis/PolarAngleAxis.typed.spec.tsx +102 -0
  492. package/test/polar/PolarAngleAxis.render.spec.tsx +79 -0
  493. package/test/polar/PolarGrid.render.spec.tsx +75 -0
  494. package/test/polar/PolarGrid.spec.tsx +918 -0
  495. package/test/polar/PolarLegendPerRow.render.spec.tsx +85 -0
  496. package/test/polar/PolarRadiusAxis.events.spec.tsx +65 -0
  497. package/test/polar/PolarRadiusAxis.render.spec.tsx +52 -0
  498. package/test/polar/PolarRadiusAxis.spec.tsx +991 -0
  499. package/test/polar/PolarRadiusAxis.typed.spec.tsx +84 -0
  500. package/test/polar/PolarTooltipLegend.render.spec.tsx +80 -0
  501. package/test/polar/Radar.animation.spec.tsx +570 -0
  502. package/test/polar/Radar.render.spec.tsx +71 -0
  503. package/test/polar/Radar.spec.tsx +265 -0
  504. package/test/polar/Radar.typed.spec.tsx +119 -0
  505. package/test/polar/RadialBar/RadialBar.spec.tsx +1521 -0
  506. package/test/polar/RadialBar/RadialBar.typed.spec.tsx +132 -0
  507. package/test/polar/RadialBar.animation.spec.tsx +375 -0
  508. package/test/polar/RadialBar.render.spec.tsx +66 -0
  509. package/test/polar/RadialBar.stacked.spec.tsx +57 -0
  510. package/test/setup.ts +84 -0
  511. package/test/shape/ActiveShape.spec.tsx +181 -0
  512. package/test/shape/Cross.spec.tsx +60 -0
  513. package/test/shape/Cross.typed.spec.tsx +26 -0
  514. package/test/shape/Curve.spec.tsx +368 -0
  515. package/test/shape/Curve.typed.spec.tsx +69 -0
  516. package/test/shape/Dot.spec.tsx +73 -0
  517. package/test/shape/Dot.typed.spec.tsx +30 -0
  518. package/test/shape/Polygon.spec.tsx +357 -0
  519. package/test/shape/Polygon.typed.spec.tsx +28 -0
  520. package/test/shape/Rectangle.animation.spec.tsx +451 -0
  521. package/test/shape/Rectangle.spec.tsx +68 -0
  522. package/test/shape/Rectangle.typed.spec.tsx +24 -0
  523. package/test/shape/Sector.spec.tsx +76 -0
  524. package/test/shape/Sector.typed.spec.tsx +24 -0
  525. package/test/shape/Symbols.spec.tsx +43 -0
  526. package/test/shape/Symbols.typed.spec.tsx +24 -0
  527. package/test/shape/Trapezoid.spec.tsx +50 -0
  528. package/test/shape/Trapezoid.typed.spec.tsx +24 -0
  529. package/test/shape/__snapshots__/Cross.spec.tsx.snap +62 -0
  530. package/test/shape/__snapshots__/Curve.spec.tsx.snap +460 -0
  531. package/test/shape/__snapshots__/Polygon.spec.tsx.snap +58 -0
  532. package/test/shape/__snapshots__/Rectangle.spec.tsx.snap +117 -0
  533. package/test/shape/__snapshots__/Sector.spec.tsx.snap +71 -0
  534. package/test/shape/__snapshots__/Trapezoid.spec.tsx.snap +64 -0
  535. package/test/state/chartDataSlice.spec.ts +53 -0
  536. package/test/state/externalEventsMiddleware.spec.ts +178 -0
  537. package/test/state/graphicalItemsSlice.spec.ts +92 -0
  538. package/test/state/hooks.spec.tsx +68 -0
  539. package/test/state/legendSlice.spec.ts +44 -0
  540. package/test/state/mouseEventsMiddleware.spec.ts +75 -0
  541. package/test/state/optionsSlice.spec.ts +19 -0
  542. package/test/state/reduxDevtoolsJsonStringifyReplacer.spec.ts +25 -0
  543. package/test/state/referenceElementsSlice.spec.ts +84 -0
  544. package/test/state/selectors/areaSelectors.spec.tsx +77 -0
  545. package/test/state/selectors/axisSelectors.spec.tsx +1418 -0
  546. package/test/state/selectors/barStackSelectors.spec.tsx +752 -0
  547. package/test/state/selectors/brushSelectors.spec.tsx +30 -0
  548. package/test/state/selectors/cartesianAxisSlice.spec.ts +96 -0
  549. package/test/state/selectors/combineNiceTicks.spec.ts +207 -0
  550. package/test/state/selectors/combiners/combineActiveTooltipIndex.spec.ts +61 -0
  551. package/test/state/selectors/combiners/combineAllBarPositions.spec.ts +39 -0
  552. package/test/state/selectors/combiners/combineConfiguredScale.spec.ts +56 -0
  553. package/test/state/selectors/combiners/combineDisplayedStackedData.spec.ts +123 -0
  554. package/test/state/selectors/combiners/combineRealScaleType.spec.ts +80 -0
  555. package/test/state/selectors/containerSelectors.spec.tsx +168 -0
  556. package/test/state/selectors/dataSelectors.spec.tsx +136 -0
  557. package/test/state/selectors/legendSelectors.spec.tsx +113 -0
  558. package/test/state/selectors/lineSelectors.spec.tsx +60 -0
  559. package/test/state/selectors/pieSelectors.spec.tsx +72 -0
  560. package/test/state/selectors/radarSelectors.spec.tsx +496 -0
  561. package/test/state/selectors/rootPropsSelectors.spec.tsx +169 -0
  562. package/test/state/selectors/scatterSelectors.spec.tsx +47 -0
  563. package/test/state/selectors/selectActiveTooltipIndex.spec.tsx +234 -0
  564. package/test/state/selectors/selectAllAxes.spec.tsx +18 -0
  565. package/test/state/selectors/selectAxisDomain.spec.tsx +21 -0
  566. package/test/state/selectors/selectAxisDomainIncludingNiceTicks.spec.tsx +19 -0
  567. package/test/state/selectors/selectAxisRangeWithReverse.spec.tsx +22 -0
  568. package/test/state/selectors/selectAxisScale.spec.tsx +91 -0
  569. package/test/state/selectors/selectBarRectangles.stackOffset.spec.tsx +503 -0
  570. package/test/state/selectors/selectBaseAxis.spec.tsx +56 -0
  571. package/test/state/selectors/selectCartesianItemsSettings.spec.tsx +57 -0
  572. package/test/state/selectors/selectChartOffset.spec.tsx +26 -0
  573. package/test/state/selectors/selectDisplayedData.spec.tsx +282 -0
  574. package/test/state/selectors/selectIsTooltipActive.spec.tsx +231 -0
  575. package/test/state/selectors/selectNumericalDomain.spec.tsx +21 -0
  576. package/test/state/selectors/selectRealScaleType.spec.tsx +19 -0
  577. package/test/state/selectors/selectStackGroups.spec.tsx +322 -0
  578. package/test/state/selectors/selectXAxisPosition.spec.tsx +22 -0
  579. package/test/state/selectors/selectYAxisPosition.spec.tsx +22 -0
  580. package/test/state/selectors/selectors.spec.tsx +1613 -0
  581. package/test/state/throttling.spec.ts +200 -0
  582. package/test/state/zIndexSlice.spec.ts +85 -0
  583. package/test/synchronisation/useChartSynchronisation.spec.tsx +225 -0
  584. package/test/util/BarUtils.spec.ts +39 -0
  585. package/test/util/CartesianUtils/CartesianUtils.spec.ts +261 -0
  586. package/test/util/CartesianUtils/rectWithPoints.spec.ts +48 -0
  587. package/test/util/ChartUtils/ChartUtils.spec.ts +491 -0
  588. package/test/util/ChartUtils/appendOffsetOfLegend.spec.ts +136 -0
  589. package/test/util/ChartUtils/appendOffsetOfLegend.spec.tsx +133 -0
  590. package/test/util/ChartUtils/getCateCoordinateOfLine.spec.ts +83 -0
  591. package/test/util/ChartUtils/getStackedData.spec.ts +416 -0
  592. package/test/util/ChartUtils/truncateByDomain.spec.ts +70 -0
  593. package/test/util/DataUtils.spec.ts +385 -0
  594. package/test/util/DomUtils.spec.tsx +117 -0
  595. package/test/util/FunnelUtils.spec.tsx +70 -0
  596. package/test/util/Global.spec.ts +11 -0
  597. package/test/util/LRUCache.spec.ts +81 -0
  598. package/test/util/LogUtils.spec.ts +45 -0
  599. package/test/util/PolarUtils.spec.ts +66 -0
  600. package/test/util/ReduceCssCalcPrototype.spec.ts +141 -0
  601. package/test/util/ShallowEqual.spec.ts +102 -0
  602. package/test/util/TickUtils.spec.ts +29 -0
  603. package/test/util/axisPropsAreEqual.spec.ts +93 -0
  604. package/test/util/createChartHelpers.spec.tsx +210 -0
  605. package/test/util/cursor/getCursorPoints.spec.ts +136 -0
  606. package/test/util/cursor/getCursorRectangle.spec.ts +50 -0
  607. package/test/util/cursor/getRadialCursorPoints.spec.ts +36 -0
  608. package/test/util/errorValue.spec.ts +69 -0
  609. package/test/util/getEveryNth.spec.ts +39 -0
  610. package/test/util/getRadiusAndStrokeWidthFromDot.spec.ts +51 -0
  611. package/test/util/getRelativeCoordinate.spec.ts +250 -0
  612. package/test/util/getSliced.spec.ts +45 -0
  613. package/test/util/isDomainSpecifiedByUser.spec.ts +207 -0
  614. package/test/util/isWellBehavedNumber.spec.ts +54 -0
  615. package/test/util/payload/getUniqPayload.spec.ts +56 -0
  616. package/test/util/propsAreEqual.spec.ts +75 -0
  617. package/test/util/round.spec.ts +112 -0
  618. package/test/util/scale/arithmetic.spec.ts +61 -0
  619. package/test/util/scale/createCategoricalInverse.spec.ts +84 -0
  620. package/test/util/scale/getNiceTickValues.spec.ts +421 -0
  621. package/test/util/scale/getTickValuesFixedDomain.spec.ts +155 -0
  622. package/test/util/svgPropertiesAndEvents.spec.tsx +206 -0
  623. package/test/util/svgPropertiesNoEvents.spec.tsx +228 -0
  624. package/test/util/tooltip/translate.spec.ts +396 -0
  625. package/test/util/useAnimationId.spec.tsx +59 -0
  626. package/test/util/useElementOffset.spec.tsx +173 -0
  627. package/test/util/usePrefersReducedMotion.spec.ts +54 -0
  628. package/test/util/useUniqueId.spec.ts +99 -0
  629. package/test/utils/diagnostics-allowlist.ts +18 -0
  630. package/test/utils/diagnostics.ts +58 -0
  631. package/test/zIndex/AllZIndexPortals.spec.tsx +83 -0
  632. package/test/zIndex/DefaultZIndexes.spec.ts +80 -0
  633. package/test/zIndex/DynamicZIndex.spec.tsx +102 -0
  634. package/test/zIndex/ZIndexLayer.portalOwner.spec.tsx +125 -0
  635. package/test/zIndex/componentZIndex.spec.tsx +255 -0
  636. package/test/zIndex/getZIndexFromUnknown.spec.ts +51 -0
  637. package/test/zIndex/multiChartZIndexIsolation.spec.tsx +90 -0
  638. package/test/zIndex/zIndexSelectors.spec.ts +172 -0
  639. package/tsconfig.json +11 -0
@@ -0,0 +1,912 @@
1
+ // Ported from recharts 3.8.1 src/polar/Pie.tsx (commit 7a23854).
2
+ //
3
+ // MINIMAL PORT — renders one <Sector> per data slice with byte-identical
4
+ // geometry. `computePieSectors` is the pure sector-geometry function, ported
5
+ // faithfully (sum>0 branch, minAngle redistribution, paddingAngle). It is
6
+ // consumed by `pieSelectors.selectPieSectors`.
7
+ //
8
+ // Solid deviations: `resolveDefaultProps`→`merge`; effect-dispatch registration
9
+ // (RegisterGraphicalItemId + SetPolarGraphicalItem) → `createEffect`/`onCleanup`
10
+ // pushing PieSettings into the graphicalItems slice (matched by id); the
11
+ // `@ts-expect-error`-laden unknown-data spreads are replaced with typed coercion
12
+ // (no `any`/`as`).
13
+ //
14
+ // Tooltip-entry + legend-payload registration + per-sector item-hover dispatch
15
+ // are WIRED (item-type tooltip). selectPieLegend drives the (sector-independent)
16
+ // legend so it renders even when every value is 0.
17
+ // WIRED: labels + labelLine (function/object/boolean forms; default text+connector),
18
+ // `<Label>` children (position=center incl. dx/dy via the polar Label path),
19
+ // activeShape / inactiveShape (function + object + boolean forms, via <Shape> keyed
20
+ // off the active-tooltip index/dataKey/graphical-item id, with `recharts-active-shape`),
21
+ // the function-form custom `shape` render prop, the full external event surface
22
+ // (onClick/onMouse*/onTouch*, called `(sector, index, event)`), per-sector
23
+ // data-attrs + tabIndex, the empty-data render gate (root `.recharts-pie` always
24
+ // rendered), and onAnimationStart/End callbacks.
25
+ // Cells ARE wired: a <Cell> child (or a data-row `fill`/`stroke`) overrides the
26
+ // per-slice fill/stroke/class; with no `data` prop the <Cell> rows become the data.
27
+ // PERMANENT-N/A (by design, NOT deferred): element-form shape/activeShape/
28
+ // inactiveShape/label (Solid has no cloneElement — use the function form).
29
+ // zIndex relayering IS wired: the whole `.recharts-pie` root Layer is wrapped in
30
+ // <ZIndexLayer> (default DefaultZIndexes.area = 100) when it has sectors, matching
31
+ // recharts (the empty/hidden root Layer stays inline, mounting no portal).
32
+ // DEFERRED: `maxRadius`/`cornerRadius` rounding edge cases, float-precise per-frame
33
+ // animation angle matrices.
34
+ import { createEffect, createMemo, For, merge, Show, untrack } from "solid-js";
35
+ import type { JSX } from "@solidjs/web";
36
+ import { useAppSelector, useAppStore } from "../state/hooks";
37
+ import { useUniqueId } from "../util/useUniqueId";
38
+ import {
39
+ AnimatedItems,
40
+ type AnimationInterpolateFn,
41
+ useAnimationCallbacks,
42
+ } from "../animation/AnimatedItems";
43
+ import { matchAppend, type AnimationMatchByProp } from "../animation/matchBy";
44
+ import type { MutableRef } from "../animation/useAnimationStartSnapshot";
45
+ import { usePolarChartLayout } from "../context/chartLayoutContext";
46
+ import type { EasingInput } from "../animation/easing";
47
+ import type { AnimationDuration, PolarLayout } from "../util/types";
48
+ import { Layer } from "../container/Layer";
49
+ import { Sector } from "../shape/Sector";
50
+ import { Text } from "../component/Text";
51
+ import { Shape } from "../util/ActiveShapeUtils";
52
+ import type { ActiveShape, ShapeAnimationProps } from "../util/types";
53
+ import { type CellProps, collectCells } from "../component/Cell";
54
+ import { selectPieSectors, selectPieLegend } from "../state/selectors/pieSelectors";
55
+ import {
56
+ selectActiveTooltipIndex,
57
+ selectActiveTooltipDataKey,
58
+ selectActiveTooltipGraphicalItemId,
59
+ } from "../state/selectors/tooltipSelectors";
60
+ import {
61
+ DATA_ITEM_INDEX_ATTRIBUTE_NAME,
62
+ DATA_ITEM_GRAPHICAL_ITEM_ID_ATTRIBUTE_NAME,
63
+ } from "../util/Constants";
64
+ import { SetTooltipEntrySettings } from "../state/SetTooltipEntrySettings";
65
+ import type { Formatter } from "../component/DefaultTooltipContent";
66
+ import { SetLegendPayload } from "../state/SetLegendPayload";
67
+ import { TooltipPayloadConfiguration } from "../state/tooltipSlice";
68
+ import {
69
+ useMouseClickItemDispatch,
70
+ useMouseEnterItemDispatch,
71
+ useMouseLeaveItemDispatch,
72
+ } from "../context/tooltipContext";
73
+ import { getTooltipNameProp } from "../util/ChartUtils";
74
+ import { PieSettings } from "../state/types/PieSettings";
75
+ import { ChartData } from "../state/chartDataSlice";
76
+ import { GraphicalItemId } from "../state/graphicalItemsSlice";
77
+ import { TooltipPayload } from "../state/tooltipSlice";
78
+ import { ChartOffsetInternal, Coordinate, DataKey, LegendType, TooltipType } from "../util/types";
79
+ import { DefaultZIndexes } from "../zIndex/DefaultZIndexes";
80
+ import { ZIndexLayer } from "../zIndex/ZIndexLayer";
81
+ import { getMaxRadius, polarToCartesian } from "../util/PolarUtils";
82
+ import { getPercentValue, interpolate, isNumber, isNumOrStr, mathSign } from "../util/DataUtils";
83
+ import { getValueByDataKey } from "../util/ChartUtils";
84
+ import { unregisterOnCleanup } from "../state/unregisterOnCleanup";
85
+
86
+ export type PieCoordinate = {
87
+ cx: number;
88
+ cy: number;
89
+ innerRadius: number;
90
+ outerRadius: number;
91
+ maxRadius: number;
92
+ };
93
+
94
+ /**
95
+ * One computed pie slice. Carries the sector geometry plus the data needed for
96
+ * tooltips/labels (the label/tooltip consumers are deferred in the minimal port).
97
+ */
98
+ export interface PieSectorDataItem extends PieCoordinate {
99
+ startAngle: number;
100
+ endAngle: number;
101
+ midAngle: number;
102
+ middleRadius: number;
103
+ cornerRadius: number | undefined;
104
+ paddingAngle: number;
105
+ percent: number;
106
+ name: string | number;
107
+ value: number;
108
+ dataKey: DataKey<unknown> | undefined;
109
+ payload: unknown;
110
+ fill: string;
111
+ stroke: string | undefined;
112
+ /** Per-slice strokeWidth from the data row / a matching <Cell> (if any). */
113
+ strokeWidth: number | string | undefined;
114
+ /** Per-slice class from a matching <Cell> (if any). */
115
+ class: string | undefined;
116
+ tooltipPayload: TooltipPayload;
117
+ tooltipPosition: Coordinate;
118
+ }
119
+
120
+ /** Extra props recharts passes to the shape render-prop / active+inactive shapes. */
121
+ export type PieSectorShapeProps = PieSectorDataItem &
122
+ ShapeAnimationProps & {
123
+ index: number;
124
+ isActive: boolean;
125
+ tabIndex: number;
126
+ "data-recharts-item-index": number;
127
+ "data-recharts-item-id": string;
128
+ };
129
+
130
+ /** The type of the Pie `shape` / `activeShape` / `inactiveShape` props (recharts parity name). */
131
+ export type PieShape = ActiveShape<PieSectorShapeProps, SVGPathElement>;
132
+
133
+ /** Props a Pie label render-function / element receives (sector + computed text anchor + endpoint). */
134
+ export type PieLabelRenderProps = PieSectorDataItem & {
135
+ index: number;
136
+ textAnchor: string;
137
+ x: number;
138
+ y: number;
139
+ };
140
+
141
+ // Element-form label/labelLine (a pre-built JSX element) is PERMANENT-N/A — Solid
142
+ // has no cloneElement to inject computed props. The boolean/object/function forms
143
+ // ARE supported (and cover the ported tests).
144
+ export type PieLabel =
145
+ | boolean
146
+ | Partial<PieLabelRenderProps>
147
+ | ((props: PieLabelRenderProps) => JSX.Element | string | number);
148
+
149
+ export type PieLabelLine =
150
+ | boolean
151
+ | Record<string, unknown>
152
+ | ((props: { points?: ReadonlyArray<Coordinate>; [k: string]: unknown }) => JSX.Element);
153
+
154
+ /** Spread an unknown data entry into a plain record (`{}` for non-objects). */
155
+ const toRecord = (entry: unknown): Record<string, unknown> =>
156
+ typeof entry === "object" && entry != null ? { ...entry } : {};
157
+
158
+ const getOuterRadius = (
159
+ dataPoint: unknown,
160
+ outerRadius: number | string | ((element: unknown) => number | string),
161
+ maxPieRadius: number,
162
+ ): number => {
163
+ if (typeof outerRadius === "function") {
164
+ return getPercentValue(outerRadius(dataPoint), maxPieRadius, maxPieRadius * 0.8);
165
+ }
166
+ return getPercentValue(outerRadius, maxPieRadius, maxPieRadius * 0.8);
167
+ };
168
+
169
+ const parseCoordinateOfPie = (
170
+ pieSettings: PieSettings,
171
+ offset: ChartOffsetInternal,
172
+ dataPoint: unknown,
173
+ ): PieCoordinate => {
174
+ const { top, left, width, height } = offset;
175
+ const maxPieRadius = getMaxRadius(width, height);
176
+ const cx = left + getPercentValue(pieSettings.cx, width, width / 2);
177
+ const cy = top + getPercentValue(pieSettings.cy, height, height / 2);
178
+ const innerRadius = getPercentValue(pieSettings.innerRadius, maxPieRadius, 0);
179
+ const outerRadius = getOuterRadius(dataPoint, pieSettings.outerRadius, maxPieRadius);
180
+ const maxRadius = pieSettings.maxRadius || Math.sqrt(width * width + height * height) / 2;
181
+
182
+ return { cx, cy, innerRadius, outerRadius, maxRadius };
183
+ };
184
+
185
+ const parseDeltaAngle = (startAngle: number, endAngle: number): number => {
186
+ const sign = mathSign(endAngle - startAngle);
187
+ const deltaAngle = Math.min(Math.abs(endAngle - startAngle), 360);
188
+
189
+ return sign * deltaAngle;
190
+ };
191
+
192
+ export function computePieSectors({
193
+ pieSettings,
194
+ displayedData,
195
+ cells,
196
+ offset,
197
+ }: {
198
+ pieSettings: PieSettings;
199
+ displayedData: ChartData;
200
+ /** Per-slice <Cell> presentation props, indexed by data position. */
201
+ cells?: ReadonlyArray<CellProps> | undefined;
202
+ offset: ChartOffsetInternal;
203
+ }): ReadonlyArray<PieSectorDataItem> | undefined {
204
+ const { cornerRadius, startAngle, endAngle, dataKey, nameKey, tooltipType } = pieSettings;
205
+ const minAngle = Math.abs(pieSettings.minAngle);
206
+ const deltaAngle = parseDeltaAngle(startAngle, endAngle);
207
+ const absDeltaAngle = Math.abs(deltaAngle);
208
+ const paddingAngle = displayedData.length <= 1 ? 0 : (pieSettings.paddingAngle ?? 0);
209
+
210
+ const notZeroItemCount = displayedData.filter(
211
+ (entry) => getValueByDataKey(entry, dataKey, 0) !== 0,
212
+ ).length;
213
+ const totalPaddingAngle =
214
+ (absDeltaAngle >= 360 ? notZeroItemCount : notZeroItemCount - 1) * paddingAngle;
215
+
216
+ const sum = displayedData.reduce<number>((result, entry) => {
217
+ const val: unknown = getValueByDataKey(entry, dataKey, 0);
218
+ return result + (isNumber(val) ? val : 0);
219
+ }, 0);
220
+
221
+ // Only apply minAngle redistribution when at least one non-zero segment's
222
+ // natural angle falls below the minAngle threshold.
223
+ const needsMinAngleAdjustment =
224
+ minAngle > 0 &&
225
+ sum > 0 &&
226
+ displayedData.some((entry) => {
227
+ const val: unknown = getValueByDataKey(entry, dataKey, 0);
228
+ const percent = (isNumber(val) ? val : 0) / sum;
229
+ return val !== 0 && percent * absDeltaAngle < minAngle;
230
+ });
231
+ const effectiveMinAngle = needsMinAngleAdjustment ? minAngle : 0;
232
+
233
+ const realTotalAngle = absDeltaAngle - notZeroItemCount * effectiveMinAngle - totalPaddingAngle;
234
+
235
+ if (sum <= 0) {
236
+ return undefined;
237
+ }
238
+
239
+ let prev: PieSectorDataItem | undefined;
240
+ return displayedData.map((entry: unknown, i: number): PieSectorDataItem => {
241
+ const valRaw: unknown = getValueByDataKey(entry, dataKey, 0);
242
+ const val: number = isNumber(valRaw) ? valRaw : 0;
243
+ const nameRaw: unknown = getValueByDataKey(entry, nameKey, i);
244
+ const name: string | number = isNumOrStr(nameRaw) ? nameRaw : i;
245
+ const coordinate = parseCoordinateOfPie(pieSettings, offset, entry);
246
+ const percent = val / sum;
247
+
248
+ // <Cell> props win over the raw data row (recharts merges cells[i].props
249
+ // onto the entry); both can supply fill/stroke/class.
250
+ const entryWithCellInfo = { ...toRecord(entry), ...toRecord(cells?.[i]) };
251
+ const sectorColor =
252
+ typeof entryWithCellInfo.fill === "string" ? entryWithCellInfo.fill : pieSettings.fill;
253
+ const sectorStroke =
254
+ typeof entryWithCellInfo.stroke === "string" ? entryWithCellInfo.stroke : pieSettings.stroke;
255
+ // PieSettings carries no strokeWidth (the presentationProps-reduced deviation,
256
+ // see PieSettings.ts) — the component-level strokeWidth is applied at render.
257
+ const sectorStrokeWidth =
258
+ typeof entryWithCellInfo.strokeWidth === "number" ||
259
+ typeof entryWithCellInfo.strokeWidth === "string"
260
+ ? entryWithCellInfo.strokeWidth
261
+ : undefined;
262
+ const sectorClass =
263
+ typeof entryWithCellInfo.class === "string" ? entryWithCellInfo.class : undefined;
264
+
265
+ let tempStartAngle: number;
266
+ if (i) {
267
+ // prev is defined for i > 0.
268
+ tempStartAngle =
269
+ (prev?.endAngle ?? startAngle) +
270
+ mathSign(deltaAngle) * paddingAngle * (valRaw !== 0 ? 1 : 0);
271
+ } else {
272
+ tempStartAngle = startAngle;
273
+ }
274
+
275
+ const tempEndAngle =
276
+ tempStartAngle +
277
+ mathSign(deltaAngle) * ((valRaw !== 0 ? effectiveMinAngle : 0) + percent * realTotalAngle);
278
+ const midAngle = (tempStartAngle + tempEndAngle) / 2;
279
+ const middleRadius = (coordinate.innerRadius + coordinate.outerRadius) / 2;
280
+
281
+ const tooltipPayload: TooltipPayload = [
282
+ {
283
+ name,
284
+ value: val,
285
+ payload: entryWithCellInfo,
286
+ dataKey,
287
+ type: tooltipType,
288
+ color: sectorColor,
289
+ fill: sectorColor,
290
+ graphicalItemId: pieSettings.id,
291
+ },
292
+ ];
293
+ const tooltipPosition = polarToCartesian(coordinate.cx, coordinate.cy, middleRadius, midAngle);
294
+
295
+ const sector: PieSectorDataItem = {
296
+ // recharts spreads the raw data row (entryWithCellInfo) into the sector so
297
+ // arbitrary per-row fields (e.g. amt/pv/uv) surface on the item passed to
298
+ // event handlers and labels. The geometry (coordinate) and computed fields
299
+ // below intentionally win over any same-named raw field.
300
+ ...entryWithCellInfo,
301
+ ...coordinate,
302
+ percent,
303
+ cornerRadius: typeof cornerRadius === "string" ? parseFloat(cornerRadius) : cornerRadius,
304
+ name,
305
+ tooltipPayload,
306
+ midAngle,
307
+ middleRadius,
308
+ tooltipPosition,
309
+ value: val,
310
+ dataKey,
311
+ startAngle: tempStartAngle,
312
+ endAngle: tempEndAngle,
313
+ payload: entryWithCellInfo,
314
+ paddingAngle: valRaw !== 0 ? mathSign(deltaAngle) * paddingAngle : 0,
315
+ fill: sectorColor,
316
+ stroke: sectorStroke,
317
+ strokeWidth: sectorStrokeWidth,
318
+ class: sectorClass,
319
+ };
320
+ prev = sector;
321
+ return sector;
322
+ });
323
+ }
324
+
325
+ // Default per-frame interpolation for Pie sectors (the `animationInterpolateFn`
326
+ // the new AnimatedItems engine drives). Mirrors recharts 3.9 `defaultPieAnimateItems`:
327
+ // it walks the matched/added items in order, accumulating `curAngle` from the first
328
+ // non-removed sector's `next.startAngle`, and interpolates each sector's angular
329
+ // SWEEP (matched: prev-sweep→next-sweep; added: 0→next-sweep) per frame. Removed
330
+ // sectors are dropped. `interpolate` rounds the delta to 4 decimals, so the settled
331
+ // (t=1) frame is byte-identical to the reference (e.g. the closing sector lands at
332
+ // 255.0003, not 255). Pie is POLAR, so the LayoutType is PolarLayout (unused here,
333
+ // matching the reference — angle accumulation is layout-independent).
334
+ export const defaultPieAnimateItems: AnimationInterpolateFn<PieSectorDataItem, PolarLayout> = (
335
+ items,
336
+ animationElapsedTime,
337
+ ) => {
338
+ if (items == null) return [];
339
+ const stepData: PieSectorDataItem[] = [];
340
+ // The arrow predicate is an inferred type guard (TS 5.5+), so `firstNonRemoved`
341
+ // is already narrowed to a non-`removed` item — both `added` and `matched` carry `next`.
342
+ const firstNonRemoved = items.find((item) => item.status !== "removed");
343
+ let curAngle: number = firstNonRemoved != null ? firstNonRemoved.next.startAngle : 0;
344
+
345
+ items.forEach((item, index) => {
346
+ if (item.status === "removed") return;
347
+ const paddingAngle = index > 0 ? (item.next.paddingAngle ?? 0) : 0;
348
+
349
+ if (item.status === "matched") {
350
+ const angle = interpolate(
351
+ item.prev.endAngle - item.prev.startAngle,
352
+ item.next.endAngle - item.next.startAngle,
353
+ animationElapsedTime,
354
+ );
355
+ const latest = {
356
+ ...item.next,
357
+ startAngle: curAngle + paddingAngle,
358
+ endAngle: curAngle + angle + paddingAngle,
359
+ };
360
+ stepData.push(latest);
361
+ curAngle = latest.endAngle;
362
+ } else {
363
+ // added
364
+ const deltaAngle = interpolate(
365
+ 0,
366
+ item.next.endAngle - item.next.startAngle,
367
+ animationElapsedTime,
368
+ );
369
+ const latest = {
370
+ ...item.next,
371
+ startAngle: curAngle + paddingAngle,
372
+ endAngle: curAngle + deltaAngle + paddingAngle,
373
+ };
374
+ stepData.push(latest);
375
+ curAngle = latest.endAngle;
376
+ }
377
+ });
378
+ return stepData;
379
+ };
380
+
381
+ export interface PieProps<DataPointType = Record<string, unknown>, DataValueType = unknown> {
382
+ cx?: number | string;
383
+ cy?: number | string;
384
+ startAngle?: number;
385
+ endAngle?: number;
386
+ paddingAngle?: number;
387
+ innerRadius?: number | string;
388
+ outerRadius?: number | string | ((element: unknown) => number | string);
389
+ cornerRadius?: number | string;
390
+ data?: ChartData;
391
+ dataKey?: DataKey<DataPointType, DataValueType>;
392
+ nameKey?: DataKey<DataPointType>;
393
+ name?: string | number;
394
+ fill?: string;
395
+ stroke?: string;
396
+ strokeWidth?: number | string;
397
+ legendType?: LegendType;
398
+ tooltipType?: TooltipType;
399
+ /** Formats this Pie's tooltip value; takes precedence over the Tooltip-level `formatter`. */
400
+ formatter?: Formatter;
401
+ minAngle?: number;
402
+ maxRadius?: number;
403
+ hide?: boolean;
404
+ /**
405
+ * Custom sector shape (function form): called per slice with its computed
406
+ * geometry + payload, its return replaces the default <Sector>. (recharts also
407
+ * accepts an element / activeShape — those forms are deferred, see header.)
408
+ */
409
+ shape?: ActiveShape<PieSectorShapeProps, SVGPathElement>;
410
+ /**
411
+ * The shape rendered for the ACTIVE sector (hover/touch/keyboard). Object form
412
+ * merges its fields onto the sector; function form is called with the sector
413
+ * props; boolean true uses the default Sector with the `recharts-active-shape`
414
+ * class. (Element form is N/A by design — Solid has no cloneElement.)
415
+ */
416
+ activeShape?: ActiveShape<PieSectorShapeProps, SVGPathElement>;
417
+ /** The shape rendered for INACTIVE sectors when there is an active sector. */
418
+ inactiveShape?: ActiveShape<PieSectorShapeProps, SVGPathElement>;
419
+ /** Renders one label per sector (see {@link PieLabel}). */
420
+ label?: PieLabel;
421
+ /** Draws a connector line from each sector to its label (see {@link PieLabelLine}). */
422
+ labelLine?: PieLabelLine;
423
+ rootTabIndex?: number;
424
+ onAnimationStart?: () => void;
425
+ onAnimationEnd?: () => void;
426
+ /** Per-sector pointer/touch handlers, called `(sector, index, event)`. */
427
+ onClick?: (data: PieSectorDataItem, index: number, event: MouseEvent) => void;
428
+ onMouseDown?: (data: PieSectorDataItem, index: number, event: MouseEvent) => void;
429
+ onMouseUp?: (data: PieSectorDataItem, index: number, event: MouseEvent) => void;
430
+ onMouseMove?: (data: PieSectorDataItem, index: number, event: MouseEvent) => void;
431
+ onMouseOver?: (data: PieSectorDataItem, index: number, event: MouseEvent) => void;
432
+ onMouseOut?: (data: PieSectorDataItem, index: number, event: MouseEvent) => void;
433
+ onMouseEnter?: (data: PieSectorDataItem, index: number, event: MouseEvent) => void;
434
+ onMouseLeave?: (data: PieSectorDataItem, index: number, event: MouseEvent) => void;
435
+ onTouchStart?: (data: PieSectorDataItem, index: number, event: TouchEvent) => void;
436
+ onTouchMove?: (data: PieSectorDataItem, index: number, event: TouchEvent) => void;
437
+ onTouchEnd?: (data: PieSectorDataItem, index: number, event: TouchEvent) => void;
438
+ isAnimationActive?: boolean | "auto";
439
+ animationBegin?: number;
440
+ animationDuration?: AnimationDuration;
441
+ animationEasing?: EasingInput;
442
+ /** Custom per-frame interpolation for the pie sectors (v3.9). */
443
+ animationInterpolateFn?: AnimationInterpolateFn<PieSectorDataItem, PolarLayout>;
444
+ /** How prev/next sectors are matched across data updates (v3.9). @defaultValue matchAppend */
445
+ animationMatchBy?: AnimationMatchByProp<PieSectorDataItem>;
446
+ /**
447
+ * Z-Index of this component and its children; the higher, the more on top.
448
+ * @defaultValue 100 (DefaultZIndexes.area)
449
+ */
450
+ zIndex?: number;
451
+ id?: string;
452
+ class?: string;
453
+ angleAxisId?: GraphicalItemId | number;
454
+ radiusAxisId?: GraphicalItemId | number;
455
+ /** <Cell> children supplying per-slice fill/stroke/class overrides. */
456
+ children?: JSX.Element;
457
+ }
458
+
459
+ const getTextAnchor = (x: number, cx: number): string => {
460
+ if (x > cx) {
461
+ return "start";
462
+ }
463
+ if (x < cx) {
464
+ return "end";
465
+ }
466
+ return "middle";
467
+ };
468
+
469
+ /** Class string from a label/labelLine object option (`{ className }` or `{ class }`). */
470
+ const getClassFromOption = (option: unknown): string | undefined => {
471
+ if (typeof option === "object" && option != null) {
472
+ const rec: Record<string, unknown> = { ...option };
473
+ if (typeof rec.className === "string") {
474
+ return rec.className;
475
+ }
476
+ if (typeof rec.class === "string") {
477
+ return rec.class;
478
+ }
479
+ }
480
+ return undefined;
481
+ };
482
+
483
+ /** Renders the connector line for one label (element / function / object / default Curve). */
484
+ function renderLabelLineItem(
485
+ option: PieLabelLine,
486
+ lineProps: {
487
+ points: ReadonlyArray<Coordinate>;
488
+ stroke: string | undefined;
489
+ [k: string]: unknown;
490
+ },
491
+ ): JSX.Element {
492
+ if (typeof option === "function") {
493
+ return option(lineProps);
494
+ }
495
+ const cls = ["recharts-pie-label-line", getClassFromOption(option)]
496
+ .filter((c): c is string => Boolean(c))
497
+ .join(" ");
498
+ // The connector is a straight 2-point line; render a plain <path> (recharts uses
499
+ // a linear <Curve>, but Curve reads chart-layout context which would trip a
500
+ // STRICT_READ inside the label <For>).
501
+ const [p0, p1] = lineProps.points;
502
+ const d = p0 != null && p1 != null ? `M${p0.x},${p0.y}L${p1.x},${p1.y}` : "";
503
+ return <path class={cls} fill="none" stroke={lineProps.stroke} d={d} />;
504
+ }
505
+
506
+ const isTextAnchor = (v: string): v is "start" | "middle" | "end" | "inherit" =>
507
+ v === "start" || v === "middle" || v === "end" || v === "inherit";
508
+
509
+ /** The object-form props of a label/labelLine option (`{}` for boolean/function). */
510
+ const optionProps = (option: unknown): Record<string, unknown> =>
511
+ typeof option === "object" && option != null ? { ...option } : {};
512
+
513
+ /** Numeric `offsetRadius` from an object-form label option, else the default 20. */
514
+ const getOffsetRadius = (option: unknown): number => {
515
+ const props = optionProps(option);
516
+ return typeof props.offsetRadius === "number" ? props.offsetRadius : 20;
517
+ };
518
+
519
+ /** Renders one label (function/element/object/default Text). */
520
+ function renderLabelItem(
521
+ option: PieLabel,
522
+ labelProps: PieLabelRenderProps,
523
+ value: unknown,
524
+ ): JSX.Element {
525
+ let label: unknown = value;
526
+ if (typeof option === "function") {
527
+ const rendered = option(labelProps);
528
+ // A function returning an element renders that element directly.
529
+ if (rendered != null && typeof rendered === "object") {
530
+ return rendered;
531
+ }
532
+ label = rendered;
533
+ }
534
+ const cls = ["recharts-pie-label-text", getClassFromOption(option)]
535
+ .filter((c): c is string => Boolean(c))
536
+ .join(" ");
537
+ const text = typeof label === "string" || typeof label === "number" ? label : undefined;
538
+ const fill = typeof labelProps.fill === "string" ? labelProps.fill : undefined;
539
+ const textAnchor = isTextAnchor(labelProps.textAnchor) ? labelProps.textAnchor : "middle";
540
+ return (
541
+ <Text
542
+ x={labelProps.x}
543
+ y={labelProps.y}
544
+ stroke="none"
545
+ fill={fill}
546
+ textAnchor={textAnchor}
547
+ verticalAnchor="middle"
548
+ class={cls}
549
+ >
550
+ {text}
551
+ </Text>
552
+ );
553
+ }
554
+
555
+ export const pieDefaultProps = {
556
+ animationBegin: 400,
557
+ animationDuration: 1500,
558
+ animationEasing: "ease",
559
+ animationInterpolateFn: defaultPieAnimateItems,
560
+ animationMatchBy: matchAppend,
561
+ isAnimationActive: "auto",
562
+ cx: "50%",
563
+ cy: "50%",
564
+ dataKey: "value",
565
+ endAngle: 360,
566
+ fill: "#808080",
567
+ hide: false,
568
+ innerRadius: 0,
569
+ legendType: "rect",
570
+ minAngle: 0,
571
+ nameKey: "name",
572
+ outerRadius: "80%",
573
+ paddingAngle: 0,
574
+ startAngle: 0,
575
+ stroke: "#fff",
576
+ zIndex: DefaultZIndexes.area,
577
+ } as const satisfies Partial<PieProps>;
578
+
579
+ export function Pie<DataPointType = Record<string, unknown>, DataValueType = unknown>(
580
+ props: PieProps<DataPointType, DataValueType>,
581
+ ): JSX.Element {
582
+ const store = useAppStore();
583
+ const merged = merge(pieDefaultProps, props);
584
+ const id = useUniqueId("recharts-pie", props.id);
585
+
586
+ let prev: PieSettings | null = null;
587
+
588
+ createEffect(
589
+ (): PieSettings => ({
590
+ id,
591
+ type: "pie",
592
+ data: merged.data,
593
+ dataKey: merged.dataKey,
594
+ hide: merged.hide,
595
+ angleAxisId: merged.angleAxisId ?? 0,
596
+ radiusAxisId: merged.radiusAxisId ?? 0,
597
+ name: merged.name,
598
+ nameKey: merged.nameKey,
599
+ tooltipType: merged.tooltipType,
600
+ legendType: merged.legendType,
601
+ fill: merged.fill,
602
+ stroke: merged.stroke,
603
+ cx: merged.cx,
604
+ cy: merged.cy,
605
+ startAngle: merged.startAngle,
606
+ endAngle: merged.endAngle,
607
+ paddingAngle: merged.paddingAngle,
608
+ minAngle: merged.minAngle,
609
+ innerRadius: merged.innerRadius,
610
+ outerRadius: merged.outerRadius,
611
+ cornerRadius: merged.cornerRadius,
612
+ maxRadius: merged.maxRadius,
613
+ }),
614
+ (settings) => {
615
+ if (store == null) {
616
+ return;
617
+ }
618
+ if (prev === null) {
619
+ store.actions.graphicalItems.addPolarGraphicalItem(settings);
620
+ } else if (prev !== settings) {
621
+ store.actions.graphicalItems.replacePolarGraphicalItem({ prev, next: settings });
622
+ }
623
+ prev = settings;
624
+ },
625
+ );
626
+
627
+ unregisterOnCleanup(() => {
628
+ if (prev && store != null) {
629
+ store.actions.graphicalItems.removePolarGraphicalItem(prev);
630
+ prev = null;
631
+ }
632
+ });
633
+
634
+ // Per-slice <Cell> overrides (collected from children, in data order).
635
+ const cells = collectCells(() => props.children);
636
+ const sectors = useAppSelector((state) => selectPieSectors(state, id, cells()));
637
+
638
+ // Layer takes a single class string (user-class forwarding parity with clsx).
639
+ const layerClass = (): string =>
640
+ ["recharts-pie", merged.class].filter((c): c is string => Boolean(c)).join(" ");
641
+
642
+ // Item-type tooltip: one payload per sector, positioned at the sector's middle.
643
+ const tooltipConfig = createMemo<TooltipPayloadConfiguration>(() => ({
644
+ dataDefinedOnItem: sectors()?.map((s) => s.tooltipPayload),
645
+ getPosition: (index) => sectors()?.[Number(index)]?.tooltipPosition,
646
+ settings: {
647
+ stroke: merged.stroke,
648
+ strokeWidth: merged.strokeWidth,
649
+ fill: merged.fill,
650
+ dataKey: merged.dataKey,
651
+ nameKey: merged.nameKey,
652
+ name: getTooltipNameProp(merged.name, merged.dataKey),
653
+ hide: merged.hide,
654
+ type: merged.tooltipType,
655
+ color: merged.fill,
656
+ unit: "",
657
+ formatter: merged.formatter,
658
+ graphicalItemId: id,
659
+ },
660
+ }));
661
+
662
+ // Legend: one entry per displayed-data row (selectPieLegend) — independent of
663
+ // the sectors, so it still renders when every value is zero (sum<=0 → no sectors).
664
+ const legendPayload = useAppSelector((state) => selectPieLegend(state, id, cells()) ?? []);
665
+
666
+ // Active-sector tracking (hover/touch/keyboard) drives activeShape/inactiveShape.
667
+ const activeIndex = useAppSelector(selectActiveTooltipIndex);
668
+ const activeDataKey = useAppSelector(selectActiveTooltipDataKey);
669
+ const activeGraphicalItemId = useAppSelector(selectActiveTooltipGraphicalItemId);
670
+
671
+ // Per-sector item-hover dispatch, chained with the user handlers (data, index, event).
672
+ // Getter args: the hooks read handler/dataKey at event time (fresh, never stale).
673
+ const onItemEnter = useMouseEnterItemDispatch<PieSectorDataItem>(
674
+ () => props.onMouseEnter,
675
+ () => merged.dataKey,
676
+ id,
677
+ );
678
+ const onItemLeave = useMouseLeaveItemDispatch<PieSectorDataItem>(() => props.onMouseLeave);
679
+ const onItemClick = useMouseClickItemDispatch<PieSectorDataItem>(
680
+ () => props.onClick,
681
+ () => merged.dataKey,
682
+ id,
683
+ );
684
+
685
+ // Plain per-sector handlers (no tooltip dispatch) forwarded to the wrapping Layer.
686
+ const fwdMouse =
687
+ (
688
+ handler: ((data: PieSectorDataItem, index: number, e: MouseEvent) => void) | undefined,
689
+ entry: PieSectorDataItem,
690
+ index: number,
691
+ ) =>
692
+ (event: MouseEvent): void =>
693
+ handler?.(entry, index, event);
694
+ const fwdTouch =
695
+ (
696
+ handler: ((data: PieSectorDataItem, index: number, e: TouchEvent) => void) | undefined,
697
+ entry: PieSectorDataItem,
698
+ index: number,
699
+ ) =>
700
+ (event: TouchEvent): void =>
701
+ handler?.(entry, index, event);
702
+
703
+ // Enter / re-animation: the sectors grow from their start angle, driven by the
704
+ // new v3.9 engine via <AnimatedItems>. `previousSectorsRef` holds the latest
705
+ // visible frame so a re-animation (data change) tweens from where the sectors
706
+ // currently are; it is managed by AnimatedItems via useAnimationStartSnapshot.
707
+ // Pie is POLAR — the AnimatedItems LayoutType is PolarLayout ("centric" for a
708
+ // PieChart). At isAnimationActive=false the engine jumps to t=1 →
709
+ // defaultPieAnimateItems(_, 1) === the byte-identical final frame.
710
+ const previousSectorsRef: MutableRef<ReadonlyArray<PieSectorDataItem> | null | undefined> = {
711
+ current: null,
712
+ };
713
+ // recharts parity (Pie.tsx PieImpl: `if (hide || sectors == null) previousSectorsRef.current
714
+ // = null`): while hidden or without sectors, drop the previous-frame snapshot so a Pie that
715
+ // re-appears re-runs the ENTER animation from a collapsed state instead of resuming the
716
+ // tween from the last visible (mid-progress) frame. Plain-ref write (no reactive graph).
717
+ createEffect(
718
+ () => merged.hide || sectors() == null,
719
+ (shouldReset) => {
720
+ if (shouldReset) {
721
+ previousSectorsRef.current = null;
722
+ }
723
+ },
724
+ );
725
+ const polarLayout = usePolarChartLayout();
726
+
727
+ // Tracks animation in-progress (gates the labels). ownedWrite: handleAnimationEnd
728
+ // can fire from the driver's effect-cleanup when a mid-animation chart is disposed
729
+ // (route/soft navigation) — a legal teardown write.
730
+ const { isAnimating, handleAnimationStart, handleAnimationEnd } = useAnimationCallbacks(
731
+ () => props.onAnimationStart?.(),
732
+ () => props.onAnimationEnd?.(),
733
+ );
734
+
735
+ const rootTabIndex = (): number => merged.rootTabIndex ?? 0;
736
+
737
+ const isSectorActive = (index: number): boolean => {
738
+ const ai = activeIndex();
739
+ return (
740
+ String(index) === ai &&
741
+ (activeDataKey() == null || merged.dataKey === activeDataKey()) &&
742
+ (activeGraphicalItemId() == null || activeGraphicalItemId() === id)
743
+ );
744
+ };
745
+
746
+ const showLabels = (): boolean => !isAnimating();
747
+
748
+ const renderLabels = (secs: ReadonlyArray<PieSectorDataItem>): JSX.Element => {
749
+ // Capture reactive props ONCE here (this fn runs inside a tracking scope);
750
+ // the <For> child below must not read reactive values directly (STRICT_READ).
751
+ const label = merged.label;
752
+ if (!label) {
753
+ return null;
754
+ }
755
+ const labelLine = merged.labelLine ?? true;
756
+ const offsetRadius = getOffsetRadius(label);
757
+ // Recharts builds the labels with a plain `.map` over the (static) sectors —
758
+ // do the same here (no <For>): each entry is a plain object cloned from the
759
+ // sector, so the rendered <Text>/<path> read only plain values.
760
+ const labels = secs.map((src, i) => {
761
+ const entry = { ...src };
762
+ const midAngle = (entry.startAngle + entry.endAngle) / 2;
763
+ const endPoint = polarToCartesian(
764
+ entry.cx,
765
+ entry.cy,
766
+ entry.outerRadius + offsetRadius,
767
+ midAngle,
768
+ );
769
+ const labelProps: PieLabelRenderProps = {
770
+ ...entry,
771
+ stroke: "none",
772
+ ...(typeof label !== "function" ? optionProps(label) : {}),
773
+ index: i,
774
+ textAnchor: getTextAnchor(endPoint.x, entry.cx),
775
+ x: endPoint.x,
776
+ y: endPoint.y,
777
+ };
778
+ const lineProps = {
779
+ stroke: entry.fill,
780
+ ...(typeof labelLine !== "function" ? optionProps(labelLine) : {}),
781
+ points: [polarToCartesian(entry.cx, entry.cy, entry.outerRadius, midAngle), endPoint],
782
+ };
783
+ return (
784
+ <Layer>
785
+ {labelLine ? renderLabelLineItem(labelLine, lineProps) : null}
786
+ {/* The fallback label text (when `label` is `true`) is the slice value. */}
787
+ {renderLabelItem(label, labelProps, entry.value)}
788
+ </Layer>
789
+ );
790
+ });
791
+ return <Layer class="recharts-pie-labels">{labels}</Layer>;
792
+ };
793
+
794
+ // recharts always renders the root <Layer class="recharts-pie"> (with rootTabIndex)
795
+ // even when hidden / empty; only the sectors live behind the data gate. When there
796
+ // ARE sectors, recharts wraps that root Layer in <ZIndexLayer> (default 100) so a
797
+ // `zIndex` prop relayers the whole pie into its portal. Following Bar's template,
798
+ // the ZIndexLayer lives INSIDE the gate <Show> (never wrapping it) so an empty/
799
+ // hidden pie mounts NO portal — the `fallback` renders the inline empty root Layer.
800
+ return (
801
+ <>
802
+ <SetTooltipEntrySettings tooltipEntrySettings={tooltipConfig()} />
803
+ <SetLegendPayload id={id} legendPayload={legendPayload() ?? []} />
804
+ <Show
805
+ when={!merged.hide && polarLayout() ? sectors() : undefined}
806
+ fallback={
807
+ <Layer tabIndex={rootTabIndex()} class={layerClass()}>
808
+ {props.children}
809
+ </Layer>
810
+ }
811
+ >
812
+ {(secs) => (
813
+ <ZIndexLayer zIndex={merged.zIndex}>
814
+ <Layer tabIndex={rootTabIndex()} class={layerClass()}>
815
+ <AnimatedItems
816
+ animationInput={secs()}
817
+ animationIdPrefix="recharts-pie-"
818
+ items={secs()}
819
+ previousItemsRef={previousSectorsRef}
820
+ isAnimationActive={merged.isAnimationActive}
821
+ animationBegin={merged.animationBegin}
822
+ animationDuration={merged.animationDuration}
823
+ animationEasing={merged.animationEasing}
824
+ onAnimationStart={handleAnimationStart}
825
+ onAnimationEnd={handleAnimationEnd}
826
+ animationInterpolateFn={merged.animationInterpolateFn}
827
+ animationMatchBy={merged.animationMatchBy}
828
+ layout={untrack(() => polarLayout()) ?? "centric"}
829
+ >
830
+ {(frame, animationElapsedTime, isEntrance) => (
831
+ <Layer>
832
+ <For each={frame}>
833
+ {(entry, i) => {
834
+ // recharts skips fully-collapsed sectors (start === end
835
+ // === 0) unless it is the only one — the first entrance
836
+ // frame renders no sectors at all (reference Pie L722).
837
+ if (entry.startAngle === 0 && entry.endAngle === 0 && frame.length !== 1) {
838
+ return null;
839
+ }
840
+ const isActive = (): boolean => isSectorActive(i());
841
+ const hasActive = (): boolean => {
842
+ const ai = activeIndex();
843
+ return ai != null && ai !== "";
844
+ };
845
+ const sectorOption = ():
846
+ | ActiveShape<PieSectorShapeProps, SVGPathElement>
847
+ | undefined => {
848
+ if (isActive()) {
849
+ return merged.activeShape;
850
+ }
851
+ if (hasActive()) {
852
+ return merged.inactiveShape;
853
+ }
854
+ return undefined;
855
+ };
856
+ const shapeProps = (): PieSectorShapeProps => ({
857
+ ...entry,
858
+ // Entry-level (data row / <Cell>) strokeWidth wins over
859
+ // the component prop, mirroring the reference's
860
+ // presentationProps-then-entry spread order.
861
+ strokeWidth: entry.strokeWidth ?? merged.strokeWidth,
862
+ cornerRadius: entry.cornerRadius ?? 0,
863
+ index: i(),
864
+ isActive: isActive(),
865
+ tabIndex: -1,
866
+ // v3.9 ShapeAnimationProps forwarded into the function-form
867
+ // shape: the AnimatedItems frame's elapsed-time + entrance
868
+ // flag, and isAnimating combined per upstream (still true
869
+ // until the settled t=1 frame).
870
+ animationElapsedTime,
871
+ isAnimating: isAnimating() || animationElapsedTime < 1,
872
+ isEntrance,
873
+ [DATA_ITEM_INDEX_ATTRIBUTE_NAME]: i(),
874
+ [DATA_ITEM_GRAPHICAL_ITEM_ID_ATTRIBUTE_NAME]: id,
875
+ });
876
+ return (
877
+ <Layer
878
+ tabIndex={-1}
879
+ class="recharts-pie-sector"
880
+ onMouseEnter={onItemEnter(entry, i())}
881
+ onMouseLeave={onItemLeave(entry, i())}
882
+ onClick={onItemClick(entry, i())}
883
+ onMouseDown={fwdMouse(props.onMouseDown, entry, i())}
884
+ onMouseUp={fwdMouse(props.onMouseUp, entry, i())}
885
+ onMouseMove={fwdMouse(props.onMouseMove, entry, i())}
886
+ onMouseOver={fwdMouse(props.onMouseOver, entry, i())}
887
+ onMouseOut={fwdMouse(props.onMouseOut, entry, i())}
888
+ onTouchStart={fwdTouch(props.onTouchStart, entry, i())}
889
+ onTouchMove={fwdTouch(props.onTouchMove, entry, i())}
890
+ onTouchEnd={fwdTouch(props.onTouchEnd, entry, i())}
891
+ >
892
+ <Shape<PieSectorShapeProps, SVGPathElement>
893
+ option={sectorOption() ?? merged.shape}
894
+ DefaultShape={Sector}
895
+ shapeProps={shapeProps()}
896
+ />
897
+ </Layer>
898
+ );
899
+ }}
900
+ </For>
901
+ </Layer>
902
+ )}
903
+ </AnimatedItems>
904
+ <Show when={showLabels()}>{renderLabels(untrack(secs))}</Show>
905
+ {props.children}
906
+ </Layer>
907
+ </ZIndexLayer>
908
+ )}
909
+ </Show>
910
+ </>
911
+ );
912
+ }