@solidports/recharts 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (306) hide show
  1. package/LICENSE +22 -0
  2. package/NOTICE +19 -0
  3. package/README.md +102 -0
  4. package/dist/dev.js +28564 -0
  5. package/dist/index.d.ts +7859 -0
  6. package/dist/index.js +28546 -0
  7. package/package.json +98 -0
  8. package/src/animation/AnimatedItems.tsx +183 -0
  9. package/src/animation/AnimationController.ts +33 -0
  10. package/src/animation/AnimationControllerImpl.ts +36 -0
  11. package/src/animation/AnimationHandle.ts +307 -0
  12. package/src/animation/CSSTransitionAnimate.tsx +170 -0
  13. package/src/animation/JavascriptAnimate.tsx +119 -0
  14. package/src/animation/easing.ts +221 -0
  15. package/src/animation/matchBy.ts +164 -0
  16. package/src/animation/timeoutController.ts +70 -0
  17. package/src/animation/useAnimationController.tsx +34 -0
  18. package/src/animation/useAnimationStartSnapshot.ts +118 -0
  19. package/src/animation/util.ts +41 -0
  20. package/src/cartesian/Area.tsx +915 -0
  21. package/src/cartesian/AreaRevealShape.tsx +190 -0
  22. package/src/cartesian/Bar.tsx +1369 -0
  23. package/src/cartesian/BarStack.tsx +152 -0
  24. package/src/cartesian/Brush.tsx +951 -0
  25. package/src/cartesian/CartesianAxis.tsx +722 -0
  26. package/src/cartesian/CartesianGrid.tsx +711 -0
  27. package/src/cartesian/ErrorBar.tsx +361 -0
  28. package/src/cartesian/Funnel.tsx +803 -0
  29. package/src/cartesian/GraphicalItemClipPath.tsx +67 -0
  30. package/src/cartesian/Line.tsx +863 -0
  31. package/src/cartesian/LineDrawShape.tsx +89 -0
  32. package/src/cartesian/ReferenceArea.tsx +331 -0
  33. package/src/cartesian/ReferenceDot.tsx +304 -0
  34. package/src/cartesian/ReferenceLine.tsx +474 -0
  35. package/src/cartesian/Scatter.tsx +888 -0
  36. package/src/cartesian/XAxis.tsx +433 -0
  37. package/src/cartesian/YAxis.tsx +443 -0
  38. package/src/cartesian/ZAxis.tsx +155 -0
  39. package/src/cartesian/cartesianPositionToCSSTranslate.tsx +29 -0
  40. package/src/cartesian/cartesianViewBoxToTrapezoid.tsx +21 -0
  41. package/src/cartesian/getCartesianPosition.tsx +267 -0
  42. package/src/cartesian/getEquidistantTicks.ts +144 -0
  43. package/src/cartesian/getTicks.ts +225 -0
  44. package/src/cartesian/isOutsidePosition.ts +15 -0
  45. package/src/cartesian/useAnimatedLineLength.ts +54 -0
  46. package/src/chart/AreaChart.tsx +29 -0
  47. package/src/chart/BarChart.tsx +29 -0
  48. package/src/chart/CartesianChart.tsx +131 -0
  49. package/src/chart/CategoricalChart.tsx +94 -0
  50. package/src/chart/ComposedChart.tsx +29 -0
  51. package/src/chart/FunnelChart.tsx +29 -0
  52. package/src/chart/LineChart.tsx +29 -0
  53. package/src/chart/PieChart.tsx +50 -0
  54. package/src/chart/PolarChart.tsx +164 -0
  55. package/src/chart/RadarChart.tsx +70 -0
  56. package/src/chart/RadialBarChart.tsx +46 -0
  57. package/src/chart/RechartsWrapper.tsx +551 -0
  58. package/src/chart/Sankey.tsx +1534 -0
  59. package/src/chart/ScatterChart.tsx +29 -0
  60. package/src/chart/SunburstChart.tsx +504 -0
  61. package/src/chart/Treemap.tsx +1223 -0
  62. package/src/chart/createInitialRootProps.ts +24 -0
  63. package/src/chart/types.ts +53 -0
  64. package/src/component/ActivePoints.tsx +144 -0
  65. package/src/component/Cell.tsx +37 -0
  66. package/src/component/Cursor.tsx +185 -0
  67. package/src/component/Customized.tsx +50 -0
  68. package/src/component/DefaultLegendContent.tsx +348 -0
  69. package/src/component/DefaultTooltipContent.tsx +224 -0
  70. package/src/component/Dots.tsx +157 -0
  71. package/src/component/Label.tsx +636 -0
  72. package/src/component/LabelList.tsx +375 -0
  73. package/src/component/Legend.tsx +512 -0
  74. package/src/component/ResponsiveContainer.tsx +348 -0
  75. package/src/component/Text.tsx +541 -0
  76. package/src/component/Tooltip.tsx +470 -0
  77. package/src/component/TooltipBoundingBox.tsx +146 -0
  78. package/src/component/responsiveContainerUtils.ts +134 -0
  79. package/src/container/ClipPathProvider.tsx +51 -0
  80. package/src/container/Layer.tsx +38 -0
  81. package/src/container/RootSurface.tsx +120 -0
  82. package/src/container/Surface.tsx +61 -0
  83. package/src/context/CellsContext.tsx +54 -0
  84. package/src/context/ErrorBarContext.tsx +146 -0
  85. package/src/context/GraphicalItemChildrenScope.tsx +18 -0
  86. package/src/context/PanoramaContext.tsx +9 -0
  87. package/src/context/RegisterGraphicalItemId.tsx +30 -0
  88. package/src/context/accessibilityContext.tsx +6 -0
  89. package/src/context/brushUpdateContext.tsx +9 -0
  90. package/src/context/chartDataContext.tsx +97 -0
  91. package/src/context/chartLayoutContext.tsx +201 -0
  92. package/src/context/legendPayloadContext.tsx +20 -0
  93. package/src/context/legendPortalContext.tsx +12 -0
  94. package/src/context/tooltipContext.tsx +89 -0
  95. package/src/context/tooltipPortalContext.tsx +12 -0
  96. package/src/context/useTooltipAxis.ts +22 -0
  97. package/src/hooks.ts +476 -0
  98. package/src/index.ts +280 -0
  99. package/src/polar/Pie.tsx +1360 -0
  100. package/src/polar/PolarAngleAxis.tsx +616 -0
  101. package/src/polar/PolarGrid.tsx +312 -0
  102. package/src/polar/PolarRadiusAxis.tsx +547 -0
  103. package/src/polar/Radar.tsx +734 -0
  104. package/src/polar/RadialBar.tsx +917 -0
  105. package/src/polar/defaultPolarAngleAxisProps.tsx +27 -0
  106. package/src/polar/defaultPolarRadiusAxisProps.tsx +25 -0
  107. package/src/shape/Cross.tsx +89 -0
  108. package/src/shape/Curve.tsx +343 -0
  109. package/src/shape/Dot.tsx +70 -0
  110. package/src/shape/Polygon.tsx +195 -0
  111. package/src/shape/Rectangle.tsx +470 -0
  112. package/src/shape/Sector.tsx +347 -0
  113. package/src/shape/Symbols.tsx +139 -0
  114. package/src/shape/Trapezoid.tsx +280 -0
  115. package/src/state/RechartsStateContext.tsx +12 -0
  116. package/src/state/RechartsStateProvider.tsx +87 -0
  117. package/src/state/RechartsStoreContext.tsx +25 -0
  118. package/src/state/RechartsStoreProvider.tsx +35 -0
  119. package/src/state/ReportChartProps.tsx +40 -0
  120. package/src/state/ReportEventSettings.tsx +30 -0
  121. package/src/state/ReportMainChartProps.tsx +61 -0
  122. package/src/state/ReportPolarOptions.tsx +35 -0
  123. package/src/state/SetGraphicalItem.ts +79 -0
  124. package/src/state/SetLegendPayload.ts +134 -0
  125. package/src/state/SetTooltipEntrySettings.tsx +72 -0
  126. package/src/state/actions.ts +464 -0
  127. package/src/state/brushSlice.ts +13 -0
  128. package/src/state/cartesianAxisSlice.ts +141 -0
  129. package/src/state/chartDataSlice.ts +50 -0
  130. package/src/state/chartState.ts +297 -0
  131. package/src/state/errorBarSlice.ts +29 -0
  132. package/src/state/eventSettingsSlice.ts +8 -0
  133. package/src/state/events.ts +76 -0
  134. package/src/state/externalEventsMiddleware.ts +255 -0
  135. package/src/state/graphicalItemsSlice.ts +74 -0
  136. package/src/state/hooks/useChartSelectors.tsx +45 -0
  137. package/src/state/keyboardEventsMiddleware.ts +228 -0
  138. package/src/state/layoutSlice.ts +21 -0
  139. package/src/state/legendSlice.ts +57 -0
  140. package/src/state/mouseEventsMiddleware.ts +185 -0
  141. package/src/state/optionsSlice.ts +47 -0
  142. package/src/state/polarAxisSlice.ts +10 -0
  143. package/src/state/polarOptionsSlice.ts +12 -0
  144. package/src/state/rawData.ts +26 -0
  145. package/src/state/referenceElementsSlice.ts +40 -0
  146. package/src/state/renderedTicksSlice.ts +15 -0
  147. package/src/state/rootPropsSlice.ts +47 -0
  148. package/src/state/selectors/areaSelectors.ts +240 -0
  149. package/src/state/selectors/arrayEqualityCheck.ts +29 -0
  150. package/src/state/selectors/axisSelectors.ts +2157 -0
  151. package/src/state/selectors/barSelectors.ts +310 -0
  152. package/src/state/selectors/barStackSelectors.ts +77 -0
  153. package/src/state/selectors/brushSelectors.ts +33 -0
  154. package/src/state/selectors/chartSelector.ts +185 -0
  155. package/src/state/selectors/combiners/combineActiveLabel.ts +16 -0
  156. package/src/state/selectors/combiners/combineActiveTooltipIndex.ts +95 -0
  157. package/src/state/selectors/combiners/combineAllBarPositions.ts +122 -0
  158. package/src/state/selectors/combiners/combineAxisRangeWithReverse.ts +16 -0
  159. package/src/state/selectors/combiners/combineBarPosition.ts +23 -0
  160. package/src/state/selectors/combiners/combineBarSizeList.ts +80 -0
  161. package/src/state/selectors/combiners/combineCheckedDomain.ts +48 -0
  162. package/src/state/selectors/combiners/combineConfiguredScale.ts +111 -0
  163. package/src/state/selectors/combiners/combineCoordinateForDefaultIndex.ts +45 -0
  164. package/src/state/selectors/combiners/combineDisplayedStackedData.ts +50 -0
  165. package/src/state/selectors/combiners/combineInverseScaleFunction.ts +16 -0
  166. package/src/state/selectors/combiners/combineRealScaleType.ts +44 -0
  167. package/src/state/selectors/combiners/combineStackedData.ts +27 -0
  168. package/src/state/selectors/combiners/combineTooltipInteractionState.ts +86 -0
  169. package/src/state/selectors/combiners/combineTooltipPayload.ts +205 -0
  170. package/src/state/selectors/combiners/combineTooltipPayloadConfigurations.ts +58 -0
  171. package/src/state/selectors/containerSelectors.ts +12 -0
  172. package/src/state/selectors/dataSelectors.ts +88 -0
  173. package/src/state/selectors/funnelSelectors.ts +75 -0
  174. package/src/state/selectors/graphicalItemSelectors.ts +30 -0
  175. package/src/state/selectors/legendSelectors.ts +29 -0
  176. package/src/state/selectors/lineSelectors.ts +134 -0
  177. package/src/state/selectors/numberDomainEqualityCheck.ts +14 -0
  178. package/src/state/selectors/pickAxisId.ts +5 -0
  179. package/src/state/selectors/pickAxisType.ts +3 -0
  180. package/src/state/selectors/pieSelectors.ts +97 -0
  181. package/src/state/selectors/polarAxisSelectors.ts +201 -0
  182. package/src/state/selectors/polarGridSelectors.ts +28 -0
  183. package/src/state/selectors/polarScaleSelectors.ts +133 -0
  184. package/src/state/selectors/polarSelectors.ts +219 -0
  185. package/src/state/selectors/radarSelectors.ts +191 -0
  186. package/src/state/selectors/radialBarSelectors.ts +435 -0
  187. package/src/state/selectors/rootPropsSelectors.ts +25 -0
  188. package/src/state/selectors/scatterSelectors.ts +96 -0
  189. package/src/state/selectors/selectActivePropsFromChartPointer.ts +26 -0
  190. package/src/state/selectors/selectAllAxes.ts +17 -0
  191. package/src/state/selectors/selectChartOffset.ts +16 -0
  192. package/src/state/selectors/selectChartOffsetInternal.ts +136 -0
  193. package/src/state/selectors/selectLegendArea.ts +20 -0
  194. package/src/state/selectors/selectPlotArea.ts +22 -0
  195. package/src/state/selectors/selectTooltipAxisId.ts +7 -0
  196. package/src/state/selectors/selectTooltipAxisType.ts +32 -0
  197. package/src/state/selectors/selectTooltipEventType.ts +48 -0
  198. package/src/state/selectors/selectTooltipPayloadSearcher.ts +6 -0
  199. package/src/state/selectors/selectTooltipSettings.ts +39 -0
  200. package/src/state/selectors/selectTooltipState.ts +8 -0
  201. package/src/state/selectors/selectors.ts +271 -0
  202. package/src/state/selectors/tooltipSelectors.ts +578 -0
  203. package/src/state/selectors/touchSelectors.ts +31 -0
  204. package/src/state/store.ts +29 -0
  205. package/src/state/storeIdentity.ts +9 -0
  206. package/src/state/teardownWrite.ts +10 -0
  207. package/src/state/tooltipInteraction.ts +23 -0
  208. package/src/state/tooltipSlice.ts +334 -0
  209. package/src/state/touchEventsMiddleware.ts +214 -0
  210. package/src/state/types/AnimationSettings.ts +20 -0
  211. package/src/state/types/AreaSettings.ts +14 -0
  212. package/src/state/types/BarSettings.ts +15 -0
  213. package/src/state/types/LineSettings.ts +9 -0
  214. package/src/state/types/PieSettings.ts +34 -0
  215. package/src/state/types/RadarSettings.ts +5 -0
  216. package/src/state/types/RadialBarSettings.ts +10 -0
  217. package/src/state/types/ScatterSettings.ts +12 -0
  218. package/src/state/types/StackedGraphicalItem.ts +34 -0
  219. package/src/state/useChartState.ts +17 -0
  220. package/src/state/zIndexSlice.ts +39 -0
  221. package/src/synchronisation/syncSelectors.ts +7 -0
  222. package/src/synchronisation/types.ts +44 -0
  223. package/src/synchronisation/useChartSynchronisation.tsx +404 -0
  224. package/src/theme/RechartsTheme.ts +16 -0
  225. package/src/theme/RechartsThemeContext.ts +19 -0
  226. package/src/theme/darkTheme.ts +13 -0
  227. package/src/theme/graphicalItemIdentity.ts +70 -0
  228. package/src/theme/legacyTheme.ts +17 -0
  229. package/src/theme/lightTheme.ts +13 -0
  230. package/src/types.ts +54 -0
  231. package/src/util/ActiveShapeUtils.tsx +162 -0
  232. package/src/util/BarUtils.tsx +62 -0
  233. package/src/util/BarePortal.tsx +50 -0
  234. package/src/util/CamelCaseSVGAttrs.ts +34 -0
  235. package/src/util/CartesianUtils.ts +48 -0
  236. package/src/util/ChartUtils.ts +802 -0
  237. package/src/util/Constants.ts +42 -0
  238. package/src/util/CssPrefixUtils.ts +20 -0
  239. package/src/util/DOMUtils.ts +129 -0
  240. package/src/util/DataUtils.ts +216 -0
  241. package/src/util/Events.ts +16 -0
  242. package/src/util/FunnelUtils.tsx +15 -0
  243. package/src/util/Global.ts +12 -0
  244. package/src/util/IfOverflow.ts +15 -0
  245. package/src/util/LRUCache.ts +41 -0
  246. package/src/util/LogUtils.ts +22 -0
  247. package/src/util/PolarUtils.ts +132 -0
  248. package/src/util/RadialBarUtils.tsx +24 -0
  249. package/src/util/ReactUtils.ts +95 -0
  250. package/src/util/ReduceCSSCalc.ts +187 -0
  251. package/src/util/ScatterUtils.tsx +52 -0
  252. package/src/util/ShapeElementProps.tsx +87 -0
  253. package/src/util/TickUtils.ts +60 -0
  254. package/src/util/XAxisUtils.ts +48 -0
  255. package/src/util/YAxisUtils.ts +48 -0
  256. package/src/util/axisPropsAreEqual.ts +48 -0
  257. package/src/util/createCartesianCharts.tsx +150 -0
  258. package/src/util/createEventProxy.ts +20 -0
  259. package/src/util/createPolarCharts.tsx +112 -0
  260. package/src/util/cursor/getCursorPoints.ts +46 -0
  261. package/src/util/cursor/getCursorRectangle.ts +28 -0
  262. package/src/util/cursor/getRadialCursorPoints.ts +32 -0
  263. package/src/util/excludeEventProps.ts +171 -0
  264. package/src/util/getActiveCoordinate.ts +213 -0
  265. package/src/util/getAxisTypeBasedOnLayout.ts +21 -0
  266. package/src/util/getClassNameFromUnknown.ts +6 -0
  267. package/src/util/getEveryNth.ts +27 -0
  268. package/src/util/getRadiusAndStrokeWidthFromDot.ts +35 -0
  269. package/src/util/getRelativeCoordinate.ts +80 -0
  270. package/src/util/getSliced.ts +13 -0
  271. package/src/util/hoverDedupe.ts +41 -0
  272. package/src/util/isDomainSpecifiedByUser.ts +219 -0
  273. package/src/util/isWellBehavedNumber.ts +7 -0
  274. package/src/util/pathTotalLength.ts +25 -0
  275. package/src/util/payload/getUniqPayload.ts +28 -0
  276. package/src/util/propsAreEqual.ts +121 -0
  277. package/src/util/resolveDefaultProps.ts +161 -0
  278. package/src/util/round.ts +32 -0
  279. package/src/util/scale/CartesianScaleHelper.ts +72 -0
  280. package/src/util/scale/CustomScaleDefinition.ts +81 -0
  281. package/src/util/scale/RechartsScale.ts +130 -0
  282. package/src/util/scale/createCategoricalInverse.ts +72 -0
  283. package/src/util/scale/getNiceTickValues.ts +311 -0
  284. package/src/util/scale/index.ts +2 -0
  285. package/src/util/scale/util/arithmetic.ts +54 -0
  286. package/src/util/solid-1-compat.ts +310 -0
  287. package/src/util/solidJsxCamelAugment.d.ts +84 -0
  288. package/src/util/stacks/getStackSeriesIdentifier.ts +21 -0
  289. package/src/util/stacks/stackTypes.ts +60 -0
  290. package/src/util/structurallyEqual.ts +31 -0
  291. package/src/util/svgPropertiesAndEvents.ts +53 -0
  292. package/src/util/svgPropertiesNoEvents.ts +571 -0
  293. package/src/util/tooltip/translate.ts +171 -0
  294. package/src/util/typedDataKey.ts +48 -0
  295. package/src/util/types.ts +1560 -0
  296. package/src/util/useAnimationId.ts +31 -0
  297. package/src/util/useElementOffset.ts +110 -0
  298. package/src/util/useId.ts +8 -0
  299. package/src/util/usePrefersReducedMotion.ts +48 -0
  300. package/src/util/useReportScale.ts +24 -0
  301. package/src/util/useUniqueId.ts +30 -0
  302. package/src/zIndex/DefaultZIndexes.ts +84 -0
  303. package/src/zIndex/ZIndexLayer.tsx +121 -0
  304. package/src/zIndex/ZIndexPortal.tsx +79 -0
  305. package/src/zIndex/getZIndexFromUnknown.ts +14 -0
  306. package/src/zIndex/zIndexSelectors.ts +48 -0
@@ -0,0 +1,31 @@
1
+ /* eslint-disable import/no-cycle */
2
+ import { createMemo } from 'solid-js';
3
+ import { uniqueId } from "./DataUtils"
4
+ import { structurallyEqual } from "./structurallyEqual"
5
+
6
+ /* React `useAnimationId(input, prefix)` regenerates id when `input !== prev` by
7
+ reference. React renders hand fresh `props` objects per render, so refs flip
8
+ on parent updates. Solid props proxies stay stable across data updates — we
9
+ must compare CONTENT, not reference (see structurallyEqual below). */
10
+ /* Solid port (was: setAnimationId inside a memo that also read animationId()
11
+ formed a write-after-read cycle, OOM under fresh-each-call refs). Drop the
12
+ signal — keep previous input + current id in plain mutable state, recompute
13
+ synchronously when tracked input CONTENT changes. Reference equality alone
14
+ misfires under Solid because selectors return fresh arrays even when content
15
+ is unchanged. */
16
+ const UNINITIALIZED = Symbol("useAnimationId.uninitialized")
17
+
18
+ export function useAnimationId(input: () => unknown, prefix: string = "animation-"): () => string {
19
+ let prevInput: unknown = UNINITIALIZED
20
+ let currentId = uniqueId(prefix)
21
+
22
+ const animationId = createMemo(() => {
23
+ const currentInput = input()
24
+ if (prevInput !== UNINITIALIZED && !structurallyEqual(prevInput, currentInput)) {
25
+ currentId = uniqueId(prefix)
26
+ }
27
+ prevInput = currentInput
28
+ return currentId
29
+ })
30
+ return animationId
31
+ }
@@ -0,0 +1,110 @@
1
+ import { createSignal, untrack, createEffect } from 'solid-js';
2
+ const EPS = 1
3
+
4
+ /**
5
+ * Stores the `offsetHeight`, `offsetLeft`, `offsetTop`, and `offsetWidth` of a DOM element.
6
+ */
7
+ export type ElementOffset = {
8
+ /**
9
+ * Height of an element, including vertical padding and borders, as an integer.
10
+ *
11
+ * Typically, offsetHeight is a measurement in pixels of the element's CSS height, including any borders, padding, and horizontal scrollbars (if rendered). It does not include the height of pseudo-elements such as ::before or ::after
12
+ *
13
+ * https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetHeight
14
+ */
15
+ height: number
16
+ /**
17
+ * Number of pixels that the upper left corner of the current element is offset to the left within the HTMLElement.offsetParent node
18
+ *
19
+ * https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetLeft
20
+ */
21
+ left: number
22
+ /**
23
+ * Distance from the outer border of the current element (including its margin) to the top padding edge of the offsetParent, the closest positioned ancestor element.
24
+ *
25
+ * https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetTop
26
+ */
27
+ top: number
28
+ /**
29
+ * Layout width of an element as an integer.
30
+ *
31
+ * Typically, offsetWidth is a measurement in pixels of the element's CSS width, including any borders, padding, and vertical scrollbars (if rendered). It does not include the width of pseudo-elements such as ::before or ::after.
32
+ *
33
+ * https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetWidth
34
+ */
35
+ width: number
36
+ }
37
+
38
+ export type SetElementOffset = (node: HTMLElement | null) => void
39
+
40
+ /**
41
+ * Listen to element layout changes.
42
+ *
43
+ * Pass the returned setter as a ref callback: `<div ref={updateElementOffset}>`.
44
+ *
45
+ * @param extraDeps Accessor returning a list of values that should re-trigger a measurement.
46
+ * Equivalent to React's `useElementOffset(extraDependencies)` — useful when the
47
+ * element re-renders children (payload, label) but the layout box of the parent
48
+ * must be re-read to compute a transform.
49
+ */
50
+ export function useElementOffset(
51
+ extraDeps?: () => readonly unknown[],
52
+ ): [() => ElementOffset, SetElementOffset] {
53
+ const [lastBoundingBox, setLastBoundingBox] = createSignal<ElementOffset>({
54
+ height: 0,
55
+ left: 0,
56
+ top: 0,
57
+ width: 0,
58
+ })
59
+ const [node, setNode] = createSignal<HTMLElement | null>(null)
60
+
61
+ const measure = (target: HTMLElement) => {
62
+ const rect = target.getBoundingClientRect()
63
+ const current = untrack(lastBoundingBox)
64
+ if (
65
+ Math.abs(rect.height - current.height) > EPS ||
66
+ Math.abs(rect.left - current.left) > EPS ||
67
+ Math.abs(rect.top - current.top) > EPS ||
68
+ Math.abs(rect.width - current.width) > EPS
69
+ ) {
70
+ setLastBoundingBox({
71
+ height: rect.height,
72
+ left: rect.left,
73
+ top: rect.top,
74
+ width: rect.width,
75
+ })
76
+ }
77
+ }
78
+
79
+ /* Measure after the node attaches and whenever any tracked dep changes — mirrors
80
+ React's ref callback (called at commit, with children in place) and
81
+ useCallback([extraDependencies]), which forces a fresh ref callback. A Solid ref
82
+ fires before dynamic children are inserted, so the ref itself does not measure.
83
+ Without the deps the bounding box is read once at mount (often 0×0 for a hidden
84
+ tooltip) and never updates when payload/active flips. */
85
+ createEffect(
86
+ () => {
87
+ extraDeps?.()
88
+ return node()
89
+ },
90
+ (target) => {
91
+ if (target != null) measure(target)
92
+ },
93
+ )
94
+
95
+ /* ResizeObserver covers the case where children grow/shrink (formatter,
96
+ payload row count) without an explicit dep change. Guarded for SSR /
97
+ environments without RO support (e.g. very old jsdom). */
98
+ createEffect(node, (target) => {
99
+ if (target == null || typeof ResizeObserver === "undefined") return undefined
100
+ const ro = new ResizeObserver(() => measure(target))
101
+ ro.observe(target)
102
+ return () => ro.disconnect()
103
+ })
104
+
105
+ const updateBoundingBox: SetElementOffset = (next) => {
106
+ setNode(next)
107
+ }
108
+
109
+ return [lastBoundingBox, updateBoundingBox]
110
+ }
@@ -0,0 +1,8 @@
1
+ import { createUniqueId } from 'solid-js';
2
+ /**
3
+ * Generates a unique ID using Solid's createUniqueId.
4
+ * This is SSR-safe in Solid.
5
+ *
6
+ * @returns A unique ID that remains consistent across renders.
7
+ */
8
+ export const useId: () => string = createUniqueId
@@ -0,0 +1,48 @@
1
+ import { Global } from "./Global"
2
+
3
+ const REDUCED_MOTION_QUERY = "(prefers-reduced-motion: reduce)"
4
+
5
+ /* One live MediaQueryList for the page (re-queried only if `matchMedia` itself is replaced).
6
+ Every animated shape reads it on mount, so a query per instance shows up on chart switch. */
7
+ let queriedWith: typeof window.matchMedia | undefined
8
+ let mediaQuery: MediaQueryList | undefined
9
+
10
+ function readPrefersReducedMotion(): boolean {
11
+ if (Global.isSsr) {
12
+ return false
13
+ }
14
+ if (typeof window === "undefined" || typeof window.matchMedia !== "function") {
15
+ return false
16
+ }
17
+ if (mediaQuery === undefined || queriedWith !== window.matchMedia) {
18
+ queriedWith = window.matchMedia
19
+ mediaQuery = window.matchMedia(REDUCED_MOTION_QUERY)
20
+ }
21
+ return mediaQuery.matches
22
+ }
23
+
24
+ /**
25
+ * Reads the user's `prefers-reduced-motion` system preference.
26
+ * Returns `true` when the user prefers reduced motion, `false` otherwise.
27
+ * SSR-safe: always returns `false` during server-side rendering.
28
+ *
29
+ * Components run once in Solid, so the value is read at mount, as upstream's first render
30
+ * does. Upstream re-renders on a preference change; a snapshot here never would, so no
31
+ * change listener is kept per instance.
32
+ */
33
+ export function usePrefersReducedMotion(): boolean {
34
+ return readPrefersReducedMotion()
35
+ }
36
+
37
+ /**
38
+ * `'auto'` follows reduced-motion and is off during SSR; a boolean is returned as-is.
39
+ */
40
+ export function resolveIsAnimationActive(
41
+ isActive: boolean | "auto",
42
+ prefersReducedMotion: boolean,
43
+ ): boolean {
44
+ if (isActive === "auto") {
45
+ return Global.isSsr === false && prefersReducedMotion === false
46
+ }
47
+ return isActive
48
+ }
@@ -0,0 +1,24 @@
1
+ /* eslint-disable import/no-cycle */
2
+ import { createEffect, createSignal, untrack } from 'solid-js';
3
+ import { useChartStore } from "../state/RechartsStoreContext"
4
+ import { selectContainerScale } from "../state/selectors/containerSelectors"
5
+ import { isWellBehavedNumber } from "./isWellBehavedNumber"
6
+
7
+ export function useReportScale() {
8
+ const ctx = useChartStore()
9
+ const [ref, setRef] = createSignal<HTMLElement | null>(null)
10
+
11
+ createEffect(ref, (el) => {
12
+ if (el == null || ctx == null) {
13
+ return
14
+ }
15
+ const scale = untrack(() => selectContainerScale(ctx.store))
16
+ const rect = el.getBoundingClientRect()
17
+ const newScale = rect.width / el.offsetWidth
18
+ if (isWellBehavedNumber(newScale) && newScale !== scale) {
19
+ ctx.setStore("layout", "scale", newScale)
20
+ }
21
+ })
22
+
23
+ return setRef
24
+ }
@@ -0,0 +1,30 @@
1
+ import { useId } from "./useId"
2
+
3
+ /**
4
+ * Generates a unique ID. It uses Solid's createUniqueId() for SSR safety.
5
+ *
6
+ * The ID will stay the same across renders, and you can optionally provide a prefix.
7
+ *
8
+ * @param [prefix] - An optional prefix for the generated ID.
9
+ * @param [customId] - An optional custom ID to override the generated one.
10
+ * @returns The unique ID.
11
+ */
12
+ export function useUniqueId(prefix?: string, customId?: string): string {
13
+ const generatedId = useId()
14
+
15
+ if (customId) {
16
+ return customId
17
+ }
18
+
19
+ return prefix ? `${prefix}-${generatedId}` : generatedId
20
+ }
21
+
22
+ /**
23
+ * The useUniqueId hook returns a unique ID that is either reused from external props or generated internally.
24
+ * Either way the ID is now guaranteed to be present so no more nulls or undefined.
25
+ */
26
+ export type WithIdRequired<T> = T & {
27
+ id: string
28
+ }
29
+
30
+ export type WithoutId<T> = Omit<T, "id">
@@ -0,0 +1,84 @@
1
+ /* eslint-disable import/no-cycle, sort-keys */
2
+ /**
3
+ * A collection of all default zIndex values used by Recharts.
4
+ *
5
+ * You can reuse these, or you can define your own.
6
+ */
7
+ export const DefaultZIndexes = {
8
+ /**
9
+ * CartesianGrid and PolarGrid
10
+ */
11
+ grid: -100,
12
+ /**
13
+ * Background of Bar and RadialBar.
14
+ * This is not visible by default but can be enabled by setting background={true} on Bar or RadialBar.
15
+ */
16
+ barBackground: -50,
17
+
18
+ /*
19
+ * other chart elements or custom elements without specific zIndex
20
+ * render in here, at zIndex 0
21
+ */
22
+
23
+ /**
24
+ * Area, Pie, Radar, and ReferenceArea
25
+ */
26
+ area: 100,
27
+
28
+ /**
29
+ * Cursor is embedded inside Tooltip and controlled by it.
30
+ * The Tooltip itself has a separate portal and is not included in the zIndex system;
31
+ * Cursor is the decoration inside the chart area. CursorRectangle is a rectangle box.
32
+ * It renders below bar so that in a stacked bar chart the cursor rectangle does not hide the other bars.
33
+ */
34
+ cursorRectangle: 200,
35
+
36
+ /**
37
+ * Bar and RadialBar
38
+ */
39
+ bar: 300,
40
+
41
+ /**
42
+ * Line and ReferenceLine, and ErrorBor
43
+ */
44
+ line: 400,
45
+
46
+ /**
47
+ * XAxis and YAxis and PolarAngleAxis and PolarRadiusAxis ticks and lines and children
48
+ */
49
+ axis: 500,
50
+
51
+ /**
52
+ * Scatter and ReferenceDot,
53
+ * and Dots of Line and Area and Radar if they have dot=true
54
+ */
55
+ scatter: 600,
56
+
57
+ /**
58
+ * Hovering over a Bar or RadialBar renders a highlight rectangle
59
+ */
60
+ activeBar: 1000,
61
+
62
+ /**
63
+ * Cursor is embedded inside Tooltip and controlled by it.
64
+ * The Tooltip itself has a separate portal and is not included in the zIndex system;
65
+ * Cursor is the decoration inside the chart area, usually a cross or a box.
66
+ * CursorLine is a line cursor rendered in Line, Area, Scatter, Radar charts.
67
+ * It renders above the Line and Scatter so that it is always visible.
68
+ * It renders below active dot so that the dot is always visible and shows the current point.
69
+ * We're also assuming that the active dot is small enough that it does not fully cover the cursor line.
70
+ *
71
+ * This also applies to the radial cursor in RadialBarChart.
72
+ */
73
+ cursorLine: 1100,
74
+
75
+ /**
76
+ * Hovering over a Point in Line, Area, Scatter, Radar renders a highlight dot
77
+ */
78
+ activeDot: 1200,
79
+
80
+ /**
81
+ * LabelList and Label, including Axis labels
82
+ */
83
+ label: 2000,
84
+ } as const satisfies Record<string, number>
@@ -0,0 +1,121 @@
1
+ /* eslint-disable import/no-cycle */
2
+ import type { JSX } from '@solidjs/web';
3
+ import { createEffect, createMemo, Show, untrack } from 'solid-js';
4
+ import { Portal } from '@solidjs/web';
5
+ import { useChartStore } from "../state/RechartsStoreContext"
6
+ import { selectZIndexPortalElement } from "./zIndexSelectors"
7
+ import { useIsInChartContext } from "../context/chartLayoutContext"
8
+ import { useIsPanorama } from "../context/PanoramaContext"
9
+ import { teardownWrite } from "../state/teardownWrite"
10
+
11
+ /**
12
+ * @since 3.4
13
+ */
14
+ export interface ZIndexable {
15
+ /**
16
+ * Z-Index of this component and its children. The higher the value,
17
+ * the more on top it will be rendered.
18
+ * Components with higher zIndex will appear in front of components with lower zIndex.
19
+ * If undefined or 0, the content is rendered in the default layer without portals.
20
+ *
21
+ * @since 3.4
22
+ * @defaultValue 0
23
+ * @see {@link https://recharts.github.io/en-US/guide/zIndex/ Z-Index and layers guide}
24
+ */
25
+ zIndex?: number
26
+ }
27
+
28
+ type ZIndexLayerProps = {
29
+ /**
30
+ * Z-Index of this component and its children.
31
+ *
32
+ * The higher the value, the more on top it will be rendered.
33
+ * Components with higher zIndex will appear in front of components with lower zIndex.
34
+ *
35
+ * If `undefined` or `0`, the content is rendered in the default layer without portals.
36
+ */
37
+ zIndex: number | undefined
38
+ /**
39
+ * The content to render inside this zIndex layer.
40
+ * Undefined children are allowed and will render nothing and will still report the zIndex to the portal system.
41
+ */
42
+ children?: JSX.Element
43
+ }
44
+
45
+ /**
46
+ * A layer that renders its children into a portal corresponding to the given zIndex.
47
+ * We can't use regular CSS `z-index` because SVG does not support it.
48
+ * So instead, we create separate DOM nodes for each zIndex layer
49
+ * and render the children into the corresponding DOM node using portals.
50
+ *
51
+ * This component must be used inside a Chart component.
52
+ *
53
+ * @param zIndex numeric zIndex value, higher values are rendered on top of lower values
54
+ * @param children the content to render inside this zIndex layer
55
+ *
56
+ * @since 3.4
57
+ */
58
+ export function ZIndexLayer(props: ZIndexLayerProps) {
59
+ /*
60
+ * If we are outside of chart, then we can't rely on the zIndex portal state,
61
+ * so we just render normally.
62
+ */
63
+ const isInChartContext = createMemo(() => useIsInChartContext())
64
+ /*
65
+ * If zIndex is undefined then we render normally without portals.
66
+ * Also, if zIndex is 0, we render normally without portals,
67
+ * because 0 is the default layer that does not need a portal.
68
+ */
69
+ const shouldRenderInPortal = () =>
70
+ isInChartContext() && props.zIndex !== undefined && props.zIndex !== 0
71
+
72
+ const isPanorama = useIsPanorama()
73
+
74
+ const ctx = useChartStore()
75
+
76
+ /*
77
+ * Because zIndexes are dynamic (meaning, we're not working with a predefined set of layers,
78
+ * but we allow users to define any zIndex at any time), we need to register
79
+ * the requested zIndex in the global store. This way, the ZIndexPortals component
80
+ * can render the corresponding portals and only the requested ones.
81
+ */
82
+ createEffect(
83
+ () => (shouldRenderInPortal() ? (props.zIndex ?? 0) : null),
84
+ (z) => {
85
+ if (z == null || ctx == null) {
86
+ return undefined
87
+ }
88
+ if (untrack(() => ctx.store.zIndex.zIndexMap[z]) == null) {
89
+ ctx.setStore("zIndex", "zIndexMap", z, {
90
+ consumers: 0,
91
+ element: undefined,
92
+ panoramaElement: undefined,
93
+ })
94
+ }
95
+ ctx.setStore("zIndex", "zIndexMap", z, "consumers", (c: number) => c + 1)
96
+ return () => {
97
+ teardownWrite(() => {
98
+ ctx.setStore("zIndex", "zIndexMap", z, "consumers", (c: number) => Math.max(0, c - 1))
99
+ })
100
+ }
101
+ },
102
+ )
103
+
104
+ const portalElement = createMemo(() =>
105
+ ctx ? selectZIndexPortalElement(ctx.store, props.zIndex, isPanorama) : undefined,
106
+ )
107
+
108
+ return (
109
+ <Show when={shouldRenderInPortal()} fallback={props.children}>
110
+ <Show when={portalElement()}>
111
+ {/* mount is an SVG <g>; Solid 2's Portal inserts children between text
112
+ markers without a wrapper element, so SVG content stays valid. */}
113
+ {(mount) => (
114
+ <Portal mount={mount()}>
115
+ {props.children}
116
+ </Portal>
117
+ )}
118
+ </Show>
119
+ </Show>
120
+ )
121
+ }
@@ -0,0 +1,79 @@
1
+ import type { JSX } from '@solidjs/web';
2
+ import { createMemo, For, createEffect, untrack } from 'solid-js';
3
+ import { useChartStore } from "../state/RechartsStoreContext"
4
+ import { selectAllRegisteredZIndexes } from "./zIndexSelectors"
5
+ import { teardownWrite } from "../state/teardownWrite"
6
+
7
+ function ZIndexSvgPortal(props: { zIndex: number; isPanorama: boolean }) {
8
+ let ref: SVGGElement | undefined
9
+ const ctx = useChartStore()
10
+
11
+ createEffect(
12
+ () => ({ isPanorama: props.isPanorama, zIndex: props.zIndex }),
13
+ ({ isPanorama, zIndex }) => {
14
+ if (ref == null || ctx == null) {
15
+ return undefined
16
+ }
17
+ const key = isPanorama ? "panoramaElement" : "element"
18
+ const ensureEntry = () => {
19
+ if (untrack(() => ctx.store.zIndex.zIndexMap[zIndex]) == null) {
20
+ ctx.setStore("zIndex", "zIndexMap", zIndex, {
21
+ consumers: 0,
22
+ element: undefined,
23
+ panoramaElement: undefined,
24
+ })
25
+ }
26
+ }
27
+ ensureEntry()
28
+ ctx.setStore("zIndex", "zIndexMap", zIndex, key, ref)
29
+ return () => {
30
+ teardownWrite(() => {
31
+ ensureEntry()
32
+ ctx.setStore("zIndex", "zIndexMap", zIndex, key, undefined)
33
+ })
34
+ }
35
+ },
36
+ )
37
+
38
+ /* these g elements should not be tabbable */
39
+ return <g tabindex={-1} ref={ref} class={`recharts-zIndex-layer_${props.zIndex}`} />
40
+ }
41
+
42
+ export function AllZIndexPortals(props: { children?: JSX.Element; isPanorama: boolean }) {
43
+ const ctx = useChartStore()
44
+ const allRegisteredZIndexes = createMemo(() =>
45
+ ctx ? selectAllRegisteredZIndexes(ctx.store) : undefined,
46
+ )
47
+
48
+ const negativeZIndexes = createMemo(() => {
49
+ const all = allRegisteredZIndexes()
50
+ return all ? all.filter((zIndex) => zIndex < 0) : []
51
+ })
52
+ /* zero is the default layer and does not need a portal */
53
+ const positiveZIndexes = createMemo(() => {
54
+ const all = allRegisteredZIndexes()
55
+ return all ? all.filter((zIndex) => zIndex > 0) : []
56
+ })
57
+
58
+ /* `props.children` always lives in this same JSX position. The earlier
59
+ * `<Show when={hasAny()} fallback={props.children}>` shape re-mounted the
60
+ * subtree every time `hasAny()` flipped — and child mount/unmount fires
61
+ * `addZIndexLayer` / `removeZIndexLayer` from each `ZIndexLayer` createEffect,
62
+ * which flips `hasAny()` again. That feedback loop is the BarStack hang
63
+ * (Bar's `<ZIndexLayer zIndex={300}>` toggles `hasAny()` between false ↔ true
64
+ * on every cycle, re-mounting Bar, re-running registration, OOM). React's
65
+ * `if (!all || all.length === 0) return children` is a single, stable
66
+ * subtree — replicate that by always rendering children in one position
67
+ * and conditionally rendering the portal Fors around them. */
68
+ return (
69
+ <>
70
+ <For each={negativeZIndexes()}>
71
+ {(zIndex) => <ZIndexSvgPortal zIndex={zIndex} isPanorama={props.isPanorama} />}
72
+ </For>
73
+ {props.children}
74
+ <For each={positiveZIndexes()}>
75
+ {(zIndex) => <ZIndexSvgPortal zIndex={zIndex} isPanorama={props.isPanorama} />}
76
+ </For>
77
+ </>
78
+ )
79
+ }
@@ -0,0 +1,14 @@
1
+ import { isWellBehavedNumber } from "../util/isWellBehavedNumber"
2
+
3
+ export function getZIndexFromUnknown(input: unknown, defaultZIndex: number): number {
4
+ if (
5
+ input &&
6
+ typeof input === "object" &&
7
+ "zIndex" in input &&
8
+ typeof input.zIndex === "number" &&
9
+ isWellBehavedNumber(input.zIndex)
10
+ ) {
11
+ return input.zIndex
12
+ }
13
+ return defaultZIndex
14
+ }
@@ -0,0 +1,48 @@
1
+ import type { ChartState } from "../state/store"
2
+ import { DefaultZIndexes } from "./DefaultZIndexes"
3
+
4
+ /**
5
+ * Given a zIndex, returns the corresponding portal element reference.
6
+ * If no zIndex is provided or if the zIndex is not registered, returns undefined.
7
+ *
8
+ * It also returns undefined in case the z-index portal has not been rendered yet.
9
+ */
10
+ export function selectZIndexPortalElement(
11
+ state: ChartState,
12
+ zIndex: number | undefined,
13
+ isPanorama: boolean,
14
+ ): Element | undefined {
15
+ if (zIndex == null) {
16
+ return undefined
17
+ }
18
+ const entry = state.zIndex.zIndexMap[zIndex]
19
+ if (entry == null) {
20
+ return undefined
21
+ }
22
+ if (isPanorama) {
23
+ return entry.panoramaElement
24
+ }
25
+ return entry.element
26
+ }
27
+
28
+ /* Upstream memoizes with a result equality check: an equal list keeps its reference. */
29
+ const lastRegisteredZIndexes = new WeakMap<object, ReadonlyArray<number>>()
30
+
31
+ export function selectAllRegisteredZIndexes(state: ChartState): ReadonlyArray<number> {
32
+ const zIndexMap = state.zIndex.zIndexMap
33
+ const allNumbers = Object.keys(zIndexMap)
34
+ .map((zIndexStr) => parseInt(zIndexStr, 10))
35
+ .concat(Object.values(DefaultZIndexes))
36
+ const uniqueNumbers = Array.from(new Set(allNumbers)).sort((a, b) => a - b)
37
+ const key = state.zIndex as object
38
+ const previous = lastRegisteredZIndexes.get(key)
39
+ if (
40
+ previous != null &&
41
+ previous.length === uniqueNumbers.length &&
42
+ previous.every((value, index) => value === uniqueNumbers[index])
43
+ ) {
44
+ return previous
45
+ }
46
+ lastRegisteredZIndexes.set(key, uniqueNumbers)
47
+ return uniqueNumbers
48
+ }