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,874 @@
1
+ // Ported from recharts 3.8.1 src/chart/Treemap.tsx (commit 7a23854).
2
+ //
3
+ // A hierarchical chart: the squarified-treemap layout (computeNode rolls values up
4
+ // the tree, squarify packs each node's children into aspect-ratio-optimal rows of
5
+ // rectangles) rendered as nested <Rectangle>s. Self-contained — owns its store.
6
+ //
7
+ // Solid deviations: `resolveDefaultProps`→`merge`; `useAppDispatch`→`useAppStore`;
8
+ // `RegisterGraphicalItemId`→`useUniqueId`; the recharts `AreaArray = Array & {area}`
9
+ // static-property hack → a plain `{ items, area }` row object; recursive
10
+ // `renderNode` → a recursive <TreemapNodeView> component (props-only reads, so no
11
+ // STRICT_READ); `es-toolkit get` → a tooltip-index path getter.
12
+ // Custom `content` (FUNCTION form: `(node) => JSX`) IS wired — replaces the default
13
+ // rect+label per node. type="nest" drill-down IS wired (currentRoot/nestIndex modelled
14
+ // as a signal-backed drill stack; breadcrumb strip + drill arrow). Node enter animation
15
+ // IS wired: each node slides in from the left via CSSTransitionAnimate (transform), with
16
+ // the animated style on the recreated depth layer and a stable pre-created `body` so the
17
+ // rect's handlers/refs survive the per-frame re-renders. ResponsiveContainer sizing
18
+ // works via the wrapper context (the reference itself hardcodes responsive={false}
19
+ // on its wrapper). DEFERRED: the element form of `content` & `nestIndexContent`,
20
+ // per-node name-fit text sizing nuances.
21
+ import { createMemo, createSignal, For, merge, Show } from "solid-js";
22
+ import type { JSX } from "@solidjs/web";
23
+ import { Surface } from "../container/Surface";
24
+ import { Layer } from "../container/Layer";
25
+ import { Rectangle } from "../shape/Rectangle";
26
+ import { Polygon } from "../shape/Polygon";
27
+ import { CSSTransitionAnimate } from "../animation/CSSTransitionAnimate";
28
+ import type { EasingInput } from "../animation/easing";
29
+ import { RechartsWrapper } from "./RechartsWrapper";
30
+ import { RechartsStoreProvider } from "../state/RechartsStoreProvider";
31
+ import { ReportChartMargin, useChartHeight, useChartWidth } from "../context/chartLayoutContext";
32
+ import { ReportEventSettings } from "../state/ReportEventSettings";
33
+ import { SetTooltipEntrySettings } from "../state/SetTooltipEntrySettings";
34
+ import { useAppStore } from "../state/hooks";
35
+ import { useUniqueId } from "../util/useUniqueId";
36
+ import { getValueByDataKey } from "../util/ChartUtils";
37
+ import { isNan } from "../util/DataUtils";
38
+ import { COLOR_PANEL, DATA_ITEM_INDEX_ATTRIBUTE_NAME } from "../util/Constants";
39
+ import type { ChartOptions } from "../state/optionsSlice";
40
+ import type {
41
+ TooltipIndex,
42
+ TooltipPayloadConfiguration,
43
+ TooltipPayloadSearcher,
44
+ } from "../state/tooltipSlice";
45
+ import type { RechartsRootState } from "../state/store";
46
+ import type {
47
+ Coordinate,
48
+ DataKey,
49
+ EventThrottlingProps,
50
+ Margin,
51
+ MousePointer,
52
+ Percent,
53
+ } from "../util/types";
54
+
55
+ const NODE_VALUE_KEY = "value";
56
+ const NEST_INDEX_HEIGHT = 30;
57
+
58
+ // In 'nest' mode the breadcrumb strip steals 30px off the bottom of the drawing
59
+ // surface (recharts getTreemapRenderHeight).
60
+ const getTreemapRenderHeight = (height: number, type: "flat" | "nest"): number =>
61
+ type === "nest" ? height - NEST_INDEX_HEIGHT : height;
62
+
63
+ export interface TreemapDataType {
64
+ children?: ReadonlyArray<TreemapDataType>;
65
+ [key: string]: unknown;
66
+ }
67
+
68
+ export interface TreemapNode {
69
+ children: ReadonlyArray<TreemapNode> | null;
70
+ value: number;
71
+ depth: number;
72
+ index: number;
73
+ x: number;
74
+ y: number;
75
+ width: number;
76
+ height: number;
77
+ name: string;
78
+ tooltipIndex: TooltipIndex;
79
+ [k: string]: unknown;
80
+ }
81
+
82
+ interface RectanglePosition {
83
+ x: number;
84
+ y: number;
85
+ width: number;
86
+ height: number;
87
+ }
88
+
89
+ const isObj = (v: unknown): v is Record<string, unknown> => typeof v === "object" && v != null;
90
+ const isArr = (v: unknown): v is ReadonlyArray<unknown> => Array.isArray(v);
91
+ const toNum = (v: unknown): number => (typeof v === "number" ? v : 0);
92
+
93
+ const isTreemapNode = (value: unknown): value is TreemapNode =>
94
+ isObj(value) &&
95
+ typeof value.x === "number" &&
96
+ typeof value.y === "number" &&
97
+ typeof value.width === "number" &&
98
+ typeof value.height === "number";
99
+
100
+ export const addToTreemapNodeIndex = (
101
+ i: number,
102
+ soFar: TooltipIndex | undefined = "",
103
+ ): TooltipIndex => `${soFar ?? ""}children[${i}]`;
104
+
105
+ // Resolves a Treemap tooltipIndex path (e.g. "children[0]children[1]") against the
106
+ // formatted root — replaces es-toolkit `get`.
107
+ const normalizeTreemapTooltipIndex = (activeIndex: TooltipIndex): TooltipIndex => {
108
+ const indexStr = String(activeIndex);
109
+ return /^\d+$/.test(indexStr) ? addToTreemapNodeIndex(Number(indexStr), "") : activeIndex;
110
+ };
111
+
112
+ export const treemapPayloadSearcher: TooltipPayloadSearcher = (
113
+ data: unknown,
114
+ activeIndex: TooltipIndex,
115
+ ): unknown => {
116
+ if (!data || !activeIndex) {
117
+ return undefined;
118
+ }
119
+ const normalizedIndex = normalizeTreemapTooltipIndex(activeIndex);
120
+ if (normalizedIndex == null) {
121
+ return undefined;
122
+ }
123
+ const tokens = normalizedIndex.match(/children|\[\d+\]/g) ?? [];
124
+ if (tokens.length === 0) {
125
+ return undefined;
126
+ }
127
+ let cur: unknown = data;
128
+ for (const t of tokens) {
129
+ if (t === "children") {
130
+ cur = isObj(cur) ? cur.children : undefined;
131
+ } else {
132
+ cur = isArr(cur) ? cur[Number(t.slice(1, -1))] : undefined;
133
+ }
134
+ }
135
+ return cur;
136
+ };
137
+
138
+ // Rolls each node's value up from its leaves and assigns depth/index/name/tooltipIndex.
139
+ export const computeNode = ({
140
+ depth,
141
+ node,
142
+ index,
143
+ dataKey,
144
+ nameKey,
145
+ nestedActiveTooltipIndex,
146
+ }: {
147
+ depth: number;
148
+ // Raw data OR an already-computed node (nest drill-in recomputes from a TreemapNode).
149
+ node: TreemapDataType | TreemapNode;
150
+ index: number;
151
+ dataKey: DataKey<unknown>;
152
+ nameKey: DataKey<unknown>;
153
+ nestedActiveTooltipIndex: TooltipIndex | undefined;
154
+ }): TreemapNode => {
155
+ const currentTooltipIndex =
156
+ depth === 0 ? "" : addToTreemapNodeIndex(index, nestedActiveTooltipIndex);
157
+ const children: ReadonlyArray<TreemapDataType | TreemapNode> | null | undefined = node.children;
158
+ const computedChildren =
159
+ children && children.length > 0
160
+ ? children.map((child, i) =>
161
+ computeNode({
162
+ depth: depth + 1,
163
+ node: child,
164
+ index: i,
165
+ dataKey,
166
+ nameKey,
167
+ nestedActiveTooltipIndex: currentTooltipIndex,
168
+ }),
169
+ )
170
+ : null;
171
+ let nodeValue: number;
172
+ if (computedChildren && computedChildren.length > 0) {
173
+ nodeValue = computedChildren.reduce((result, child) => result + child.value, 0);
174
+ } else {
175
+ const numericValue = toNum(node[String(dataKey)]);
176
+ nodeValue = isNan(numericValue) || numericValue <= 0 ? 0 : numericValue;
177
+ }
178
+ const nameRaw = getValueByDataKey(node, nameKey, "");
179
+ return {
180
+ ...node,
181
+ x: toNum(node.x),
182
+ y: toNum(node.y),
183
+ width: toNum(node.width),
184
+ height: toNum(node.height),
185
+ children: computedChildren,
186
+ name: typeof nameRaw === "string" || typeof nameRaw === "number" ? String(nameRaw) : "",
187
+ value: nodeValue,
188
+ depth,
189
+ index,
190
+ tooltipIndex: currentTooltipIndex,
191
+ };
192
+ };
193
+
194
+ const filterRect = (node: TreemapNode): RectanglePosition => ({
195
+ x: node.x,
196
+ y: node.y,
197
+ width: node.width,
198
+ height: node.height,
199
+ });
200
+
201
+ const insetRect = (rect: RectanglePosition, nodeInset: number): RectanglePosition => {
202
+ if (!Number.isFinite(nodeInset) || nodeInset <= 0) {
203
+ return rect;
204
+ }
205
+ const pad = Math.min(nodeInset, rect.width / 2, rect.height / 2);
206
+ return {
207
+ x: rect.x + pad,
208
+ y: rect.y + pad,
209
+ width: Math.max(rect.width - pad * 2, 0),
210
+ height: Math.max(rect.height - pad * 2, 0),
211
+ };
212
+ };
213
+
214
+ type TreemapNodeWithArea = TreemapNode & { area: number };
215
+ // recharts hangs a static `.area` off the row array; here a plain object instead.
216
+ interface Row {
217
+ items: TreemapNodeWithArea[];
218
+ area: number;
219
+ }
220
+
221
+ const applyGapToChildren = (
222
+ children: ReadonlyArray<TreemapNodeWithArea>,
223
+ parentRect: RectanglePosition,
224
+ nodeGap: number,
225
+ ): ReadonlyArray<TreemapNodeWithArea> => {
226
+ if (!Number.isFinite(nodeGap) || nodeGap <= 0) {
227
+ return children;
228
+ }
229
+ const halfGap = nodeGap / 2;
230
+ const parentRight = parentRect.x + parentRect.width;
231
+ const parentBottom = parentRect.y + parentRect.height;
232
+ return children.map((child) => {
233
+ const childRight = child.x + child.width;
234
+ const childBottom = child.y + child.height;
235
+ const leftInset = child.x > parentRect.x ? halfGap : 0;
236
+ const rightInset = childRight < parentRight ? halfGap : 0;
237
+ const topInset = child.y > parentRect.y ? halfGap : 0;
238
+ const bottomInset = childBottom < parentBottom ? halfGap : 0;
239
+ return {
240
+ ...child,
241
+ x: child.x + leftInset,
242
+ y: child.y + topInset,
243
+ width: Math.max(child.width - leftInset - rightInset, 0),
244
+ height: Math.max(child.height - topInset - bottomInset, 0),
245
+ };
246
+ });
247
+ };
248
+
249
+ const getAreaOfChildren = (
250
+ children: ReadonlyArray<TreemapNode>,
251
+ areaValueRatio: number,
252
+ ): TreemapNodeWithArea[] => {
253
+ const ratio = areaValueRatio < 0 ? 0 : areaValueRatio;
254
+ return children.map((child) => {
255
+ const area = child[NODE_VALUE_KEY] * ratio;
256
+ return { ...child, area: isNan(area) || area <= 0 ? 0 : area };
257
+ });
258
+ };
259
+
260
+ const getWorstScore = (row: Row, parentSize: number, aspectRatio: number): number => {
261
+ const parentArea = parentSize * parentSize;
262
+ const rowArea = row.area * row.area;
263
+ const { min, max } = row.items.reduce(
264
+ (result, child) => ({
265
+ min: Math.min(result.min, child.area),
266
+ max: Math.max(result.max, child.area),
267
+ }),
268
+ { min: Infinity, max: 0 },
269
+ );
270
+ return rowArea
271
+ ? Math.max(
272
+ (parentArea * max * aspectRatio) / rowArea,
273
+ rowArea / (parentArea * min * aspectRatio),
274
+ )
275
+ : Infinity;
276
+ };
277
+
278
+ const horizontalPosition = (
279
+ row: Row,
280
+ parentSize: number,
281
+ parentRect: RectanglePosition,
282
+ isFlush: boolean,
283
+ ): RectanglePosition => {
284
+ let rowHeight = parentSize ? Math.round(row.area / parentSize) : 0;
285
+ if (isFlush || rowHeight > parentRect.height) {
286
+ rowHeight = parentRect.height;
287
+ }
288
+ let curX = parentRect.x;
289
+ let last: TreemapNodeWithArea | undefined;
290
+ for (const child of row.items) {
291
+ child.x = curX;
292
+ child.y = parentRect.y;
293
+ child.height = rowHeight;
294
+ child.width = Math.min(
295
+ rowHeight ? Math.round(child.area / rowHeight) : 0,
296
+ parentRect.x + parentRect.width - curX,
297
+ );
298
+ curX += child.width;
299
+ last = child;
300
+ }
301
+ if (last != null) {
302
+ last.width += parentRect.x + parentRect.width - curX;
303
+ }
304
+ return { ...parentRect, y: parentRect.y + rowHeight, height: parentRect.height - rowHeight };
305
+ };
306
+
307
+ const verticalPosition = (
308
+ row: Row,
309
+ parentSize: number,
310
+ parentRect: RectanglePosition,
311
+ isFlush: boolean,
312
+ ): RectanglePosition => {
313
+ let rowWidth = parentSize ? Math.round(row.area / parentSize) : 0;
314
+ if (isFlush || rowWidth > parentRect.width) {
315
+ rowWidth = parentRect.width;
316
+ }
317
+ let curY = parentRect.y;
318
+ let last: TreemapNodeWithArea | undefined;
319
+ for (const child of row.items) {
320
+ child.x = parentRect.x;
321
+ child.y = curY;
322
+ child.width = rowWidth;
323
+ child.height = Math.min(
324
+ rowWidth ? Math.round(child.area / rowWidth) : 0,
325
+ parentRect.y + parentRect.height - curY,
326
+ );
327
+ curY += child.height;
328
+ last = child;
329
+ }
330
+ if (last != null) {
331
+ last.height += parentRect.y + parentRect.height - curY;
332
+ }
333
+ return { ...parentRect, x: parentRect.x + rowWidth, width: parentRect.width - rowWidth };
334
+ };
335
+
336
+ const position = (
337
+ row: Row,
338
+ parentSize: number,
339
+ parentRect: RectanglePosition,
340
+ isFlush: boolean,
341
+ ): RectanglePosition =>
342
+ parentSize === parentRect.width
343
+ ? horizontalPosition(row, parentSize, parentRect, isFlush)
344
+ : verticalPosition(row, parentSize, parentRect, isFlush);
345
+
346
+ // Recursively arranges a node's children into squarified rows.
347
+ const squarify = (
348
+ node: TreemapNode,
349
+ aspectRatio: number,
350
+ nodeInset: number,
351
+ nodeGap: number,
352
+ ): TreemapNode => {
353
+ const children = node.children;
354
+ if (!children || children.length === 0) {
355
+ return node;
356
+ }
357
+ const layoutRect = insetRect(filterRect(node), nodeInset);
358
+ let rect: RectanglePosition = layoutRect;
359
+ const row: Row = { items: [], area: 0 };
360
+ let best = Infinity;
361
+ let size = Math.min(rect.width, rect.height);
362
+ const scaleChildren = getAreaOfChildren(
363
+ children,
364
+ (rect.width * rect.height) / node[NODE_VALUE_KEY],
365
+ );
366
+ const tempChildren = scaleChildren.slice();
367
+
368
+ while (tempChildren.length > 0) {
369
+ const child = tempChildren[0];
370
+ if (child == null) {
371
+ break;
372
+ }
373
+ row.items.push(child);
374
+ row.area += child.area;
375
+ const score = getWorstScore(row, size, aspectRatio);
376
+ if (score <= best) {
377
+ tempChildren.shift();
378
+ best = score;
379
+ } else {
380
+ row.area -= row.items.pop()?.area ?? 0;
381
+ rect = position(row, size, rect, false);
382
+ size = Math.min(rect.width, rect.height);
383
+ row.items.length = 0;
384
+ row.area = 0;
385
+ best = Infinity;
386
+ }
387
+ }
388
+ if (row.items.length > 0) {
389
+ rect = position(row, size, rect, true);
390
+ row.items.length = 0;
391
+ row.area = 0;
392
+ }
393
+
394
+ const childrenWithGaps = applyGapToChildren(scaleChildren, layoutRect, nodeGap);
395
+ return {
396
+ ...node,
397
+ children: childrenWithGaps.map((c) => squarify(c, aspectRatio, nodeInset, nodeGap)),
398
+ };
399
+ };
400
+
401
+ /**
402
+ * recharts parity name for the Treemap `content` prop. The port supports the
403
+ * function form only (the upstream element form is a React cloneElement pattern).
404
+ */
405
+ export type TreemapContentType = (node: TreemapNode) => JSX.Element;
406
+
407
+ export interface TreemapProps extends EventThrottlingProps {
408
+ class?: string;
409
+ /** Top-level nodes; wrapped as the children of an implicit root that fills the chart. */
410
+ data?: ReadonlyArray<TreemapDataType>;
411
+ width?: number | Percent;
412
+ height?: number | Percent;
413
+ responsive?: boolean;
414
+ dataKey?: DataKey<unknown>;
415
+ nameKey?: DataKey<unknown>;
416
+ aspectRatio?: number;
417
+ nodeInset?: number;
418
+ nodeGap?: number;
419
+ isAnimationActive?: boolean | "auto";
420
+ isUpdateAnimationActive?: boolean | "auto";
421
+ animationBegin?: number;
422
+ animationDuration?: number;
423
+ animationEasing?: EasingInput;
424
+ fill?: string;
425
+ stroke?: string;
426
+ colorPanel?: ReadonlyArray<string>;
427
+ /**
428
+ * 'flat' (default) renders the whole tree. 'nest' renders an interactive nested
429
+ * treemap: clicking a parent drills in, and a breadcrumb strip navigates back up.
430
+ */
431
+ type?: "flat" | "nest";
432
+ /** Custom breadcrumb-cell renderer for nest mode (function form). */
433
+ nestIndexContent?: (item: TreemapNode, i: number) => JSX.Element;
434
+ /** Custom node renderer (function form). When set, replaces the default rect+label. */
435
+ content?: TreemapContentType;
436
+ onMouseEnter?: (node: TreemapNode, e: MousePointer) => void;
437
+ onMouseLeave?: (node: TreemapNode, e: MousePointer) => void;
438
+ onClick?: (node: TreemapNode) => void;
439
+ children?: JSX.Element;
440
+ id?: string;
441
+ }
442
+
443
+ export const treemapDefaultProps = {
444
+ data: [],
445
+ dataKey: "value",
446
+ nameKey: "name",
447
+ aspectRatio: 0.5 * (1 + Math.sqrt(5)),
448
+ nodeInset: 0,
449
+ nodeGap: 0,
450
+ responsive: false,
451
+ type: "flat",
452
+ isAnimationActive: "auto",
453
+ isUpdateAnimationActive: "auto",
454
+ animationBegin: 0,
455
+ animationDuration: 1500,
456
+ animationEasing: "linear",
457
+ } as const satisfies Partial<TreemapProps>;
458
+
459
+ const treemapOptions: ChartOptions = {
460
+ chartName: "Treemap",
461
+ defaultTooltipEventType: "item",
462
+ validateTooltipEventTypes: ["item"],
463
+ tooltipPayloadSearcher: treemapPayloadSearcher,
464
+ eventEmitter: undefined,
465
+ };
466
+
467
+ const zeroMargin: Margin = { top: 0, right: 0, bottom: 0, left: 0 };
468
+
469
+ // Depth-first flatten so all nodes render in a single <For> (whose callback reads
470
+ // the For-item, not a reactive prop — avoids the STRICT_READ a recursive component
471
+ // hits). Children come after their parent → they paint on top, as recharts intends.
472
+ const flattenNodes = (node: TreemapNode | null): TreemapNode[] => {
473
+ if (node == null) {
474
+ return [];
475
+ }
476
+ const out: TreemapNode[] = [node];
477
+ if (node.children) {
478
+ for (const child of node.children) {
479
+ out.push(...flattenNodes(child));
480
+ }
481
+ }
482
+ return out;
483
+ };
484
+
485
+ const TreemapImpl = (props: TreemapProps & { id: string }): JSX.Element => {
486
+ const store = useAppStore();
487
+ const merged = merge(treemapDefaultProps, props);
488
+ const width = useChartWidth();
489
+ const height = useChartHeight();
490
+
491
+ const dims = (): { width: number; height: number } | undefined => {
492
+ const w = width();
493
+ const h = height();
494
+ return w != null && h != null ? { width: w, height: h } : undefined;
495
+ };
496
+
497
+ // Layout a (raw) node as a depth-0 root filling the drawing surface.
498
+ const layoutFrom = (
499
+ node: TreemapDataType | TreemapNode,
500
+ d: { width: number; height: number },
501
+ nestedActiveTooltipIndex: TooltipIndex | undefined,
502
+ ): TreemapNode => {
503
+ // A computed TreemapNode is also valid input to computeNode (it reads name /
504
+ // value / children) — recharts drills in by recomputing from the clicked node.
505
+ const root = computeNode({
506
+ depth: 0,
507
+ node: {
508
+ ...node,
509
+ x: 0,
510
+ y: 0,
511
+ width: d.width,
512
+ height: getTreemapRenderHeight(d.height, merged.type),
513
+ },
514
+ index: 0,
515
+ dataKey: merged.dataKey,
516
+ nameKey: merged.nameKey,
517
+ nestedActiveTooltipIndex,
518
+ });
519
+ return squarify(root, merged.aspectRatio, merged.nodeInset, merged.nodeGap);
520
+ };
521
+
522
+ // nest-mode drill stack: each entry is the raw node we computed a root from, plus
523
+ // the nestedActiveTooltipIndex it carried. nestStack[0] is the implicit top root.
524
+ type NestEntry = {
525
+ node: TreemapDataType | TreemapNode;
526
+ nestedActiveTooltipIndex: TooltipIndex | undefined;
527
+ };
528
+ const topEntry = (): NestEntry => ({
529
+ node: { children: merged.data },
530
+ nestedActiveTooltipIndex: undefined,
531
+ });
532
+ const [nestStack, setNestStack] = createSignal<NestEntry[]>([topEntry()]);
533
+ const currentEntry = (): NestEntry => {
534
+ const stack = nestStack();
535
+ return stack[stack.length - 1] ?? topEntry();
536
+ };
537
+
538
+ // The fully-laid-out tree for the *current* drill root, recomputed on
539
+ // size / data / layout-param / drill change.
540
+ const formatRoot = createMemo<TreemapNode | null>(() => {
541
+ const d = dims();
542
+ if (d == null) {
543
+ return null;
544
+ }
545
+ const entry = currentEntry();
546
+ return layoutFrom(entry.node, d, entry.nestedActiveTooltipIndex);
547
+ });
548
+
549
+ // Breadcrumb entries (computed roots), one per drill level.
550
+ const nestIndex = createMemo<TreemapNode[]>(() => {
551
+ const d = dims();
552
+ if (d == null || merged.type !== "nest") {
553
+ return [];
554
+ }
555
+ return nestStack().map((entry) => layoutFrom(entry.node, d, entry.nestedActiveTooltipIndex));
556
+ });
557
+
558
+ // Flat render descriptors with fill/stroke BAKED IN, so the <For> callback reads
559
+ // only the For-item (no accessor/prop reads → no STRICT_READ). In nest mode only
560
+ // the current root + its direct children render (recharts' isCurrentRootChild gate).
561
+ const renderNodes = createMemo<
562
+ Array<{ node: TreemapNode; fill: string; stroke: string; isLeaf: boolean; arrow: boolean }>
563
+ >(() => {
564
+ const panel = merged.colorPanel ?? COLOR_PANEL;
565
+ const stroke = merged.stroke ?? "#fff";
566
+ const root = formatRoot();
567
+ const nest = merged.type === "nest";
568
+ const nodes = nest
569
+ ? root == null
570
+ ? []
571
+ : [root, ...(root.children ?? [])]
572
+ : flattenNodes(root);
573
+ return nodes.map((node) => ({
574
+ node,
575
+ fill: node.depth < 2 ? (panel[node.index % panel.length] ?? "#000") : "rgba(255,255,255,0)",
576
+ stroke,
577
+ isLeaf: !node.children || node.children.length === 0,
578
+ // drill-down arrow on nest children that have their own children.
579
+ arrow:
580
+ nest &&
581
+ node.depth > 0 &&
582
+ node.width > 10 &&
583
+ node.height > 10 &&
584
+ node.children != null &&
585
+ node.children.length > 0,
586
+ }));
587
+ });
588
+
589
+ // Augment a node with `id` + `root` (the current computed root) for user handlers,
590
+ // matching recharts' renderNode `{ ...node, root }` plus the registered item id.
591
+ const withRoot = (node: TreemapNode): TreemapNode => ({
592
+ ...node,
593
+ id: props.id,
594
+ root: formatRoot() ?? undefined,
595
+ });
596
+
597
+ const activeCoordinate = (node: TreemapNode): Coordinate => ({
598
+ x: node.x + node.width / 2,
599
+ y: node.y + node.height / 2,
600
+ });
601
+ const onUserMouseEnter = (node: TreemapNode, isLeaf: boolean, e: MousePointer): void => {
602
+ if (isLeaf || merged.type === "nest") {
603
+ merged.onMouseEnter?.(withRoot(node), e);
604
+ }
605
+ };
606
+ const onUserMouseLeave = (node: TreemapNode, isLeaf: boolean, e: MousePointer): void => {
607
+ if (isLeaf || merged.type === "nest") {
608
+ merged.onMouseLeave?.(withRoot(node), e);
609
+ }
610
+ };
611
+ // nest drill-in: clicking a non-root node with children recomputes the root from
612
+ // it. depth === 0 is the current root cell, which must not drill again.
613
+ const onNestClick = (node: TreemapNode): void => {
614
+ if (merged.type === "nest" && node.depth > 0 && node.children && node.children.length > 0) {
615
+ setNestStack((stack) => [...stack, { node, nestedActiveTooltipIndex: node.tooltipIndex }]);
616
+ }
617
+ };
618
+ const onUserClick = (node: TreemapNode, isLeaf: boolean): void => {
619
+ onNestClick(node);
620
+ if (isLeaf || merged.type === "nest") {
621
+ merged.onClick?.(withRoot(node));
622
+ }
623
+ };
624
+ // Breadcrumb click: slice the stack back to that level.
625
+ const onNestIndexClick = (i: number): void => {
626
+ setNestStack((stack) => stack.slice(0, i + 1));
627
+ };
628
+ const onItemMouseEnter = (node: TreemapNode): void => {
629
+ store?.actions.tooltip.setActiveMouseOverItemIndex({
630
+ activeIndex: node.tooltipIndex,
631
+ activeDataKey: merged.dataKey,
632
+ activeCoordinate: activeCoordinate(node),
633
+ activeGraphicalItemId: props.id,
634
+ });
635
+ };
636
+ const onItemClick = (node: TreemapNode): void => {
637
+ store?.actions.tooltip.setActiveClickItemIndex({
638
+ activeIndex: node.tooltipIndex,
639
+ activeDataKey: merged.dataKey,
640
+ activeCoordinate: activeCoordinate(node),
641
+ activeGraphicalItemId: props.id,
642
+ });
643
+ };
644
+
645
+ const tooltipConfig = createMemo<TooltipPayloadConfiguration>(() => ({
646
+ dataDefinedOnItem: formatRoot() ?? undefined,
647
+ getPosition: (index) => {
648
+ const node = treemapPayloadSearcher(formatRoot(), normalizeTreemapTooltipIndex(index));
649
+ if (!isObj(node)) {
650
+ return undefined;
651
+ }
652
+ return {
653
+ x: toNum(node.x) + toNum(node.width) / 2,
654
+ y: toNum(node.y) + toNum(node.height) / 2,
655
+ };
656
+ },
657
+ settings: {
658
+ stroke: merged.stroke,
659
+ strokeWidth: undefined,
660
+ fill: merged.fill,
661
+ nameKey: merged.nameKey,
662
+ dataKey: merged.dataKey,
663
+ name: undefined,
664
+ hide: false,
665
+ type: undefined,
666
+ color: merged.fill,
667
+ unit: "",
668
+ graphicalItemId: props.id,
669
+ },
670
+ }));
671
+
672
+ const layerClass = (): string =>
673
+ ["recharts-treemap", merged.class].filter((c): c is string => Boolean(c)).join(" ");
674
+
675
+ // Captured once (a render prop rarely changes); reading it in the <For> callback
676
+ // would be an untracked prop read.
677
+ const content = merged.content;
678
+ const nestIndexContent = merged.nestIndexContent;
679
+
680
+ const handleTouchMove = (event: TouchEvent): void => {
681
+ const touch = event.touches[0];
682
+ if (touch == null || document.elementFromPoint == null) {
683
+ return;
684
+ }
685
+ const target = document.elementFromPoint(touch.clientX, touch.clientY);
686
+ if (target == null || !("getAttribute" in target)) {
687
+ return;
688
+ }
689
+ const itemIndex = target.getAttribute(DATA_ITEM_INDEX_ATTRIBUTE_NAME);
690
+ const root = formatRoot();
691
+ if (itemIndex == null || root == null) {
692
+ return;
693
+ }
694
+ const activeNode = treemapPayloadSearcher(root, itemIndex);
695
+ if (!isTreemapNode(activeNode)) {
696
+ return;
697
+ }
698
+ store?.actions.tooltip.setActiveMouseOverItemIndex({
699
+ activeIndex: itemIndex,
700
+ activeDataKey: merged.dataKey,
701
+ activeCoordinate: {
702
+ x: activeNode.x + activeNode.width / 2,
703
+ y: activeNode.y + activeNode.height / 2,
704
+ },
705
+ activeGraphicalItemId: props.id,
706
+ });
707
+ };
708
+
709
+ return (
710
+ <Show when={dims()}>
711
+ {(d) => (
712
+ <>
713
+ <Surface
714
+ width={d().width}
715
+ height={getTreemapRenderHeight(d().height, merged.type)}
716
+ onTouchMove={handleTouchMove}
717
+ >
718
+ <Layer class={layerClass()}>
719
+ <For each={renderNodes()}>
720
+ {(item) => {
721
+ // The interactive node body (handler layer + rect/label, or custom
722
+ // content) is created ONCE. recharts slides each node in from the
723
+ // left (transform translate(-x-width,0)→translate(0,0)); the animated
724
+ // style lives on the recreated depth layer while `body` keeps a stable
725
+ // DOM identity (Solid moves it, doesn't recreate) — so the rect's
726
+ // handlers/refs survive the per-frame re-renders. isActive=false renders
727
+ // the settled transform statically.
728
+ const body = (
729
+ // The inner layer (plain recharts-layer g) carries the handlers —
730
+ // recharts' TreemapItem structure, `.recharts-treemap-depth-N g`.
731
+ <Layer
732
+ onMouseEnter={(e) => {
733
+ onUserMouseEnter(item.node, item.isLeaf, e);
734
+ // jsdom does not bubble mouseenter from the rect; layer enter drives tooltips.
735
+ onItemMouseEnter(item.node);
736
+ }}
737
+ // mouseenter does not bubble, so function-form custom content (whose
738
+ // user element carries no handler) wouldn't activate the tooltip.
739
+ // mousemove DOES bubble up from the child to this layer → drive the
740
+ // item tooltip here too (idempotent with the default rect's handler).
741
+ onMouseMove={() => onItemMouseEnter(item.node)}
742
+ onMouseLeave={(e) => onUserMouseLeave(item.node, item.isLeaf, e)}
743
+ onClick={() => onUserClick(item.node, item.isLeaf)}
744
+ >
745
+ {content ? (
746
+ content(item.node)
747
+ ) : (
748
+ <>
749
+ <Rectangle
750
+ fill={item.fill}
751
+ stroke={item.stroke}
752
+ x={item.node.x}
753
+ y={item.node.y}
754
+ width={item.node.width}
755
+ height={item.node.height}
756
+ data-recharts-item-index={item.node.tooltipIndex}
757
+ data-recharts-item-id={props.id}
758
+ onMouseEnter={() => onItemMouseEnter(item.node)}
759
+ onClick={() => onItemClick(item.node)}
760
+ />
761
+ {item.arrow ? (
762
+ <Polygon
763
+ points={[
764
+ { x: item.node.x + 2, y: item.node.y + item.node.height / 2 },
765
+ { x: item.node.x + 6, y: item.node.y + item.node.height / 2 + 3 },
766
+ { x: item.node.x + 2, y: item.node.y + item.node.height / 2 + 6 },
767
+ ]}
768
+ />
769
+ ) : null}
770
+ {item.node.width > 20 && item.node.height > 20 ? (
771
+ <text
772
+ x={item.node.x + 8}
773
+ y={item.node.y + item.node.height / 2 + 7}
774
+ font-size="14"
775
+ >
776
+ {item.node.name}
777
+ </text>
778
+ ) : null}
779
+ </>
780
+ )}
781
+ </Layer>
782
+ );
783
+ return (
784
+ <CSSTransitionAnimate
785
+ animationId={`treemap-${props.id}-${item.node.tooltipIndex}`}
786
+ from={`translate(${-item.node.x - item.node.width}px, 0px)`}
787
+ to="translate(0px, 0px)"
788
+ attributeName="transform"
789
+ begin={merged.animationBegin}
790
+ easing={
791
+ typeof merged.animationEasing === "string"
792
+ ? merged.animationEasing
793
+ : undefined
794
+ }
795
+ isActive={merged.isAnimationActive}
796
+ duration={merged.animationDuration}
797
+ >
798
+ {(style) => (
799
+ <Layer
800
+ class={`recharts-treemap-depth-${item.node.depth}`}
801
+ style={{
802
+ transform: style.transform,
803
+ transition: style.transition,
804
+ "transform-origin": `${item.node.x}px ${item.node.y}px`,
805
+ }}
806
+ >
807
+ {body}
808
+ </Layer>
809
+ )}
810
+ </CSSTransitionAnimate>
811
+ );
812
+ }}
813
+ </For>
814
+ </Layer>
815
+ <SetTooltipEntrySettings tooltipEntrySettings={tooltipConfig()} />
816
+ {merged.children}
817
+ </Surface>
818
+ {merged.type === "nest" ? (
819
+ <div
820
+ class="recharts-treemap-nest-index-wrapper"
821
+ style={{ "margin-top": "8px", "text-align": "center" }}
822
+ >
823
+ <For each={nestIndex()}>
824
+ {(item, i) => (
825
+ <div
826
+ class="recharts-treemap-nest-index-box"
827
+ style={{
828
+ cursor: "pointer",
829
+ display: "inline-block",
830
+ padding: "0 7px",
831
+ background: "#000",
832
+ color: "#fff",
833
+ "margin-right": "3px",
834
+ }}
835
+ onClick={() => onNestIndexClick(i())}
836
+ >
837
+ {nestIndexContent ? nestIndexContent(item, i()) : item.name || "root"}
838
+ </div>
839
+ )}
840
+ </For>
841
+ </div>
842
+ ) : null}
843
+ </>
844
+ )}
845
+ </Show>
846
+ );
847
+ };
848
+
849
+ /**
850
+ * A hierarchical chart that packs the tree into nested, area-proportional
851
+ * rectangles (a squarified treemap).
852
+ */
853
+ export const Treemap = (props: TreemapProps): JSX.Element => {
854
+ const id = useUniqueId("recharts-treemap", props.id);
855
+ return (
856
+ <RechartsStoreProvider
857
+ preloadedState={{ options: treemapOptions } satisfies Partial<RechartsRootState>}
858
+ >
859
+ <ReportChartMargin margin={zeroMargin} />
860
+ <ReportEventSettings
861
+ throttleDelay={props.throttleDelay}
862
+ throttledEvents={props.throttledEvents}
863
+ />
864
+ <RechartsWrapper
865
+ class={props.class}
866
+ width={props.width}
867
+ height={props.height}
868
+ responsive={props.responsive ?? false}
869
+ >
870
+ <TreemapImpl {...props} id={id} />
871
+ </RechartsWrapper>
872
+ </RechartsStoreProvider>
873
+ );
874
+ };