@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,255 @@
1
+ /* eslint-disable import/no-cycle */
2
+ import { flush } from "solid-js"
3
+ import type { ChartState } from "./chartState"
4
+ import type { CategoricalChartFunc } from "../chart/types"
5
+ import type { MouseHandlerDataParam } from "../synchronisation/types"
6
+ import {
7
+ selectActiveLabel,
8
+ selectActiveTooltipCoordinate,
9
+ selectActiveTooltipDataKey,
10
+ selectActiveTooltipIndex,
11
+ selectIsTooltipActive,
12
+ } from "./selectors/tooltipSelectors"
13
+ import { createEventProxy } from "../util/createEventProxy"
14
+
15
+ import { type SetStoreFunction } from '../util/solid-1-compat';
16
+ type ExternalEventActionPayload<E = Event> = {
17
+ event: E
18
+ handler: CategoricalChartFunc<E> | undefined
19
+ }
20
+
21
+ export type ExternalEventHandlers = {
22
+ handleExternalEvent: <E extends Event>(
23
+ event: E,
24
+ handler: CategoricalChartFunc<E> | undefined,
25
+ ) => void
26
+ }
27
+
28
+ /**
29
+ * Creates external event handler functions that read from the Solid store and call user-provided callbacks.
30
+ * Replaces the Redux createListenerMiddleware pattern for external events.
31
+ *
32
+ * Unlike mouse/touch middleware which handle one event type, this handles MULTIPLE different event types
33
+ * (click, mouseenter, mouseleave, mousedown, mouseup, contextmenu, dblclick, touchstart, touchmove, touchend)
34
+ * from the same DOM element. Different event types should NOT cancel each other's animation frames.
35
+ */
36
+ export function createExternalEventHandlers(
37
+ store: ChartState,
38
+ _setStore: SetStoreFunction<ChartState>,
39
+ ): ExternalEventHandlers {
40
+ /*
41
+ * We need a Map keyed by event type because this handler handles MULTIPLE different event types
42
+ * from the same DOM element. Different event types should NOT cancel each other's animation frames.
43
+ * For example, a click event and a mousemove event can happen in quick succession and both should be processed.
44
+ * This is different from mouseEventsMiddleware which only handles one event type and uses a single rafId.
45
+ */
46
+ const rafIdMap = new Map<string, number>()
47
+ const timeoutIdMap = new Map<string, ReturnType<typeof setTimeout>>()
48
+ const latestEventMap = new Map<string, ExternalEventActionPayload>()
49
+
50
+ function handleExternalEvent<E extends Event>(
51
+ event: E,
52
+ handler: CategoricalChartFunc<E> | undefined,
53
+ ): void {
54
+ if (handler == null) {
55
+ return
56
+ }
57
+
58
+ const eventType = event.type
59
+ const eventProxy = createEventProxy(event)
60
+
61
+ latestEventMap.set(eventType, {
62
+ event: eventProxy,
63
+ handler: handler as CategoricalChartFunc<Event>,
64
+ })
65
+
66
+ /* Cancel any pending execution for this event type */
67
+ const existingRafId = rafIdMap.get(eventType)
68
+ if (existingRafId !== undefined) {
69
+ cancelAnimationFrame(existingRafId)
70
+ rafIdMap.delete(eventType)
71
+ }
72
+
73
+ const { throttleDelay, throttledEvents } = store.eventSettings
74
+
75
+ /*
76
+ * event.type gives us the event type as a string, e.g., "click", "mousemove", etc.
77
+ * which is the same as the names used in throttledEvents array
78
+ * but that array is strictly typed as ReadonlyArray<keyof GlobalEventHandlersEventMap> | "all" | undefined
79
+ * so that we can have relevant autocomplete and type checking elsewhere.
80
+ * To satisfy TypeScript, we widen throttledEvents here.
81
+ */
82
+ const eventListAsString: "all" | ReadonlyArray<string> | undefined = throttledEvents
83
+
84
+ /* Check if this event type should be throttled */
85
+ const isThrottled = eventListAsString === "all" || eventListAsString?.includes(eventType)
86
+
87
+ const existingTimeoutId = timeoutIdMap.get(eventType)
88
+ if (existingTimeoutId !== undefined && (typeof throttleDelay !== "number" || !isThrottled)) {
89
+ clearTimeout(existingTimeoutId)
90
+ timeoutIdMap.delete(eventType)
91
+ }
92
+
93
+ const callback = () => {
94
+ const latestAction = latestEventMap.get(eventType)
95
+
96
+ try {
97
+ if (latestAction == null) {
98
+ /* This happens if the event was consumed by the leading edge and no new event came in */
99
+ return
100
+ }
101
+
102
+ const { handler: latestHandler, event: latestEvent } = latestAction
103
+ /* Commit the triggering event's state writes before reading them (Solid 2 batches writes). */
104
+ flush()
105
+ const nextState: MouseHandlerDataParam = {
106
+ activeCoordinate: selectActiveTooltipCoordinate(store),
107
+ activeDataKey: selectActiveTooltipDataKey(store),
108
+ activeIndex: selectActiveTooltipIndex(store),
109
+ activeLabel: selectActiveLabel(store),
110
+ activeTooltipIndex: selectActiveTooltipIndex(store),
111
+ isTooltipActive: selectIsTooltipActive(store),
112
+ }
113
+
114
+ if (latestHandler) {
115
+ latestHandler(nextState, latestEvent)
116
+ }
117
+ } finally {
118
+ rafIdMap.delete(eventType)
119
+ timeoutIdMap.delete(eventType)
120
+ latestEventMap.delete(eventType)
121
+ }
122
+ }
123
+
124
+ if (!isThrottled) {
125
+ /* Execute immediately */
126
+ callback()
127
+ return
128
+ }
129
+
130
+ if (throttleDelay === "raf") {
131
+ const newRafId = requestAnimationFrame(callback)
132
+ rafIdMap.set(eventType, newRafId)
133
+ } else if (typeof throttleDelay === "number") {
134
+ if (!timeoutIdMap.has(eventType)) {
135
+ /*
136
+ * Leading edge execution - execute immediately on the first event
137
+ * and then start the cooldown period to throttle subsequent events.
138
+ */
139
+ callback()
140
+
141
+ /* Start cooldown */
142
+ const newTimeoutId = setTimeout(callback, throttleDelay)
143
+ timeoutIdMap.set(eventType, newTimeoutId)
144
+ }
145
+ } else {
146
+ /* Should not happen based on type, but fallback to immediate */
147
+ callback()
148
+ }
149
+ }
150
+
151
+ return { handleExternalEvent }
152
+ }
153
+
154
+ /* Module-level maps mirror upstream Redux middleware behavior — single shared
155
+ set of pending rAF/timeout handles per event type across all stores. Different
156
+ event types must NOT cancel each other's frames. */
157
+ const actionRafIdMap = new Map<string, number>()
158
+ const actionTimeoutIdMap = new Map<string, ReturnType<typeof setTimeout>>()
159
+ const actionLatestEventMap = new Map<
160
+ string,
161
+ { handler: CategoricalChartFunc<Event>; reactEvent: Event }
162
+ >()
163
+
164
+ type ExternalEventActionInput<E extends Event> = {
165
+ handler: CategoricalChartFunc<E> | undefined
166
+ reactEvent: E
167
+ }
168
+
169
+ /**
170
+ * Action thunk wrapper for external events, used with the dispatch pattern.
171
+ * 1:1 port of upstream `externalEventsMiddleware` raf-throttled scheduler —
172
+ * pending callbacks per event type, latest payload wins on cancel.
173
+ */
174
+ export const externalEventAction =
175
+ <E extends Event>(payload: ExternalEventActionInput<E>) =>
176
+ (_setStore: SetStoreFunction<ChartState>, store: ChartState) => {
177
+ const { handler, reactEvent } = payload
178
+ if (handler == null) {
179
+ return
180
+ }
181
+
182
+ /* React 16 compatibility — pooled SyntheticEvent stays alive for async use. */
183
+ ;(reactEvent as Event & { persist?: () => void }).persist?.()
184
+
185
+ const eventType = reactEvent.type
186
+ const eventProxy = createEventProxy(reactEvent)
187
+
188
+ actionLatestEventMap.set(eventType, {
189
+ handler: handler as CategoricalChartFunc<Event>,
190
+ reactEvent: eventProxy,
191
+ })
192
+
193
+ const existingRafId = actionRafIdMap.get(eventType)
194
+ if (existingRafId !== undefined) {
195
+ cancelAnimationFrame(existingRafId)
196
+ actionRafIdMap.delete(eventType)
197
+ }
198
+
199
+ const { throttleDelay, throttledEvents } = store.eventSettings
200
+ const eventListAsString: "all" | ReadonlyArray<string> | undefined = throttledEvents
201
+ const isThrottled =
202
+ eventListAsString === "all" || eventListAsString?.includes(eventType)
203
+
204
+ const existingTimeoutId = actionTimeoutIdMap.get(eventType)
205
+ if (
206
+ existingTimeoutId !== undefined &&
207
+ (typeof throttleDelay !== "number" || !isThrottled)
208
+ ) {
209
+ clearTimeout(existingTimeoutId)
210
+ actionTimeoutIdMap.delete(eventType)
211
+ }
212
+
213
+ const callback = () => {
214
+ const latestAction = actionLatestEventMap.get(eventType)
215
+ try {
216
+ if (latestAction == null) {
217
+ return
218
+ }
219
+ const { handler: latestHandler, reactEvent: latestEvent } = latestAction
220
+ /* Commit the triggering event's state writes before reading them (Solid 2 batches writes). */
221
+ flush()
222
+ const nextState: MouseHandlerDataParam = {
223
+ activeCoordinate: selectActiveTooltipCoordinate(store),
224
+ activeDataKey: selectActiveTooltipDataKey(store),
225
+ activeIndex: selectActiveTooltipIndex(store),
226
+ activeLabel: selectActiveLabel(store),
227
+ activeTooltipIndex: selectActiveTooltipIndex(store),
228
+ isTooltipActive: selectIsTooltipActive(store),
229
+ }
230
+ latestHandler(nextState, latestEvent)
231
+ } finally {
232
+ actionRafIdMap.delete(eventType)
233
+ actionTimeoutIdMap.delete(eventType)
234
+ actionLatestEventMap.delete(eventType)
235
+ }
236
+ }
237
+
238
+ if (!isThrottled) {
239
+ callback()
240
+ return
241
+ }
242
+
243
+ if (throttleDelay === "raf") {
244
+ const rafId = requestAnimationFrame(callback)
245
+ actionRafIdMap.set(eventType, rafId)
246
+ } else if (typeof throttleDelay === "number") {
247
+ if (!actionTimeoutIdMap.has(eventType)) {
248
+ callback()
249
+ const timeoutId = setTimeout(callback, throttleDelay)
250
+ actionTimeoutIdMap.set(eventType, timeoutId)
251
+ }
252
+ } else {
253
+ callback()
254
+ }
255
+ }
@@ -0,0 +1,74 @@
1
+ /* eslint-disable import/no-cycle */
2
+ import type { ChartData } from "./chartDataSlice"
3
+ import type { AxisId } from "./cartesianAxisSlice"
4
+ import type { DataKey } from "../util/types"
5
+ import type { LineSettings } from "./types/LineSettings"
6
+ import type { ScatterSettings } from "./types/ScatterSettings"
7
+ import type { AreaSettings } from "./types/AreaSettings"
8
+ import type { BarSettings } from "./types/BarSettings"
9
+ import type { RadialBarSettings } from "./types/RadialBarSettings"
10
+ import type { PieSettings } from "./types/PieSettings"
11
+ import type { RadarSettings } from "./types/RadarSettings"
12
+
13
+ /**
14
+ * Unique ID of the graphical item.
15
+ * This is used to identify the graphical item in the state and in the React tree.
16
+ * This is required for every graphical item - it's either provided by the user or generated automatically.
17
+ */
18
+ export type GraphicalItemId = string
19
+
20
+ export interface GraphicalItemSettings {
21
+ /**
22
+ * Unique ID of the graphical item.
23
+ * This is used to identify the graphical item in the state and in the React tree.
24
+ * This is required for every graphical item - it's either provided by the user or generated automatically.
25
+ */
26
+ id: GraphicalItemId
27
+ /**
28
+ * If the given graphical item has its own data array, it will appear here.
29
+ * If this is undefined, the data will be taken from the chart root prop.
30
+ */
31
+ data: ChartData | undefined
32
+ dataKey: DataKey<unknown> | undefined
33
+ /**
34
+ * Why not just stop pushing the graphical items to state when they are hidden?
35
+ * Well some components decide to continue showing them anyway.
36
+ * Legend for example will keep showing a record for hidden graphical items.
37
+ * Stacks for example will ignore them.
38
+ */
39
+ hide: boolean
40
+ }
41
+
42
+ export interface BaseCartesianGraphicalItemSettings extends GraphicalItemSettings {
43
+ /**
44
+ * Each of the graphical items explicitly says which axis it uses;
45
+ * this property is optional for users but every graphical item must have a default,
46
+ * and it is required here.
47
+ */
48
+ xAxisId: AxisId
49
+ yAxisId: AxisId
50
+ zAxisId: AxisId
51
+ /**
52
+ * Graphical items that are inside Brush panorama should not interact with the main area graphical items
53
+ * and vice versa.
54
+ */
55
+ isPanorama: boolean
56
+ }
57
+
58
+ export type CartesianGraphicalItemSettings =
59
+ | AreaSettings
60
+ | BarSettings
61
+ | LineSettings
62
+ | ScatterSettings
63
+
64
+ export interface BasePolarGraphicalItemSettings extends GraphicalItemSettings {
65
+ angleAxisId: AxisId
66
+ radiusAxisId: AxisId
67
+ }
68
+
69
+ export type PolarGraphicalItemSettings = PieSettings | RadarSettings | RadialBarSettings
70
+
71
+ export type ReplacePayload<T> = {
72
+ prev: T
73
+ next: T
74
+ }
@@ -0,0 +1,45 @@
1
+ /* eslint-disable import/no-cycle */
2
+ import type { CartesianViewBoxRequired, ChartOffsetInternal } from "../../util/types"
3
+ import type { XAxisSettings, YAxisSettings } from "../cartesianAxisSlice"
4
+ import {
5
+ selectChartOffsetInternal,
6
+ selectChartViewBox,
7
+ selectAxisViewBox,
8
+ } from "../selectors/selectChartOffsetInternal"
9
+ import { selectAllXAxes, selectAllYAxes } from "../selectors/selectAllAxes"
10
+ import { useChartStore } from "../RechartsStoreContext"
11
+
12
+ /*
13
+ * Chart-level selector hooks. The selectors are chartSelector memos, so every consumer of a chart
14
+ * shares one computation per selector; outside a chart the hooks return undefined.
15
+ */
16
+
17
+ /** Returns the current chart offset. */
18
+ export const useChartOffsetInternal = (): ChartOffsetInternal | undefined => {
19
+ const ctx = useChartStore()
20
+ return ctx ? selectChartOffsetInternal(ctx.store) : undefined
21
+ }
22
+
23
+ /** Returns all registered X axes. */
24
+ export const useAllXAxes = (): ReadonlyArray<XAxisSettings> | undefined => {
25
+ const ctx = useChartStore()
26
+ return ctx ? selectAllXAxes(ctx.store) : undefined
27
+ }
28
+
29
+ /** Returns all registered Y axes. */
30
+ export const useAllYAxes = (): ReadonlyArray<YAxisSettings> | undefined => {
31
+ const ctx = useChartStore()
32
+ return ctx ? selectAllYAxes(ctx.store) : undefined
33
+ }
34
+
35
+ /** Returns the axis viewBox. */
36
+ export const useAxisViewBox = (): CartesianViewBoxRequired | undefined => {
37
+ const ctx = useChartStore()
38
+ return ctx ? selectAxisViewBox(ctx.store) : undefined
39
+ }
40
+
41
+ /** Returns the chart viewBox. */
42
+ export const useChartViewBox = (): CartesianViewBoxRequired | undefined => {
43
+ const ctx = useChartStore()
44
+ return ctx ? selectChartViewBox(ctx.store) : undefined
45
+ }
@@ -0,0 +1,228 @@
1
+ /* eslint-disable import/no-cycle */
2
+ import type { ChartState } from "./chartState"
3
+ import { readChartState } from "./chartState"
4
+ import type { TooltipIndex, TooltipInteractionState } from "./tooltipSlice"
5
+ import type { Coordinate } from "../util/types"
6
+ import {
7
+ selectTooltipAxisDomain,
8
+ selectTooltipAxisTicks,
9
+ selectTooltipDisplayedData,
10
+ } from "./selectors/tooltipSelectors"
11
+ import { selectCoordinateForDefaultIndex } from "./selectors/selectors"
12
+ import { selectChartDirection, selectTooltipAxisDataKey } from "./selectors/axisSelectors"
13
+ import { combineActiveTooltipIndex } from "./selectors/combiners/combineActiveTooltipIndex"
14
+ import { selectTooltipEventType } from "./selectors/selectTooltipEventType"
15
+
16
+ import { type SetStoreFunction } from '../util/solid-1-compat';
17
+ export type KeyboardEventHandlers = {
18
+ handleKeyDown: (key: KeyboardEvent["key"]) => void
19
+ handleFocus: () => void
20
+ handleBlur: () => void
21
+ }
22
+
23
+ /* Mirrors upstream's setKeyboardInteraction reducer: only active/index/coordinate change. */
24
+ function setKeyboardInteraction(
25
+ setStore: SetStoreFunction<ChartState>,
26
+ active: boolean,
27
+ index: TooltipIndex | undefined,
28
+ coordinate: Coordinate | undefined,
29
+ ): void {
30
+ setStore("tooltip", "keyboardInteraction", "active", active)
31
+ setStore("tooltip", "keyboardInteraction", "index", index)
32
+ setStore("tooltip", "keyboardInteraction", "coordinate", coordinate)
33
+ }
34
+
35
+ function coordinateForIndex(store: ChartState, index: TooltipIndex | undefined): Coordinate | undefined {
36
+ const tooltipEventType = selectTooltipEventType(store, store.tooltip.settings.shared)
37
+ return selectCoordinateForDefaultIndex(store, tooltipEventType, "hover", String(index))
38
+ }
39
+
40
+ /* Builds a minimal TooltipInteractionState for the candidate-index check. */
41
+ function candidateInteraction(i: number): TooltipInteractionState {
42
+ return {
43
+ active: false,
44
+ coordinate: undefined,
45
+ dataKey: undefined,
46
+ graphicalItemId: undefined,
47
+ index: String(i),
48
+ }
49
+ }
50
+
51
+ function applyKeyDown(
52
+ store: ChartState,
53
+ setStore: SetStoreFunction<ChartState>,
54
+ key: KeyboardEvent["key"] | null,
55
+ ): void {
56
+ const accessibilityLayerIsActive = store.rootProps.accessibilityLayer !== false
57
+ if (!accessibilityLayerIsActive) {
58
+ return
59
+ }
60
+ const keyboardInteraction = readChartState(store).tooltip.keyboardInteraction
61
+ if (key !== "ArrowRight" && key !== "ArrowLeft" && key !== "Enter") {
62
+ return
63
+ }
64
+
65
+ /* TODO this is lacking index for charts that do not support numeric indexes */
66
+ const displayedData = selectTooltipDisplayedData(store)
67
+ const axisDataKey = selectTooltipAxisDataKey(store)
68
+ const domain = selectTooltipAxisDomain(store)
69
+ const resolvedIndex = combineActiveTooltipIndex(keyboardInteraction, displayedData, axisDataKey, domain)
70
+ const currentIndex = resolvedIndex == null ? -1 : Number(resolvedIndex)
71
+ const isOutsideDomain = !Number.isFinite(currentIndex) || currentIndex < 0
72
+ if (key === "Enter") {
73
+ if (isOutsideDomain) {
74
+ return
75
+ }
76
+ setKeyboardInteraction(
77
+ setStore,
78
+ !keyboardInteraction.active,
79
+ keyboardInteraction.index,
80
+ coordinateForIndex(store, keyboardInteraction.index),
81
+ )
82
+ return
83
+ }
84
+
85
+ const directionMultiplier = selectChartDirection(store) === "left-to-right" ? 1 : -1
86
+ const movement = key === "ArrowRight" ? 1 : -1
87
+ let nextIndex: number
88
+ if (isOutsideDomain) {
89
+ /* Snap back to the first/last index that is visible in the current domain. */
90
+ const isVisible = (i: number) =>
91
+ combineActiveTooltipIndex(candidateInteraction(i), displayedData, axisDataKey, domain) != null
92
+ nextIndex = -1
93
+ if (movement * directionMultiplier > 0) {
94
+ for (let i = 0; i < displayedData.length; i++) {
95
+ if (isVisible(i)) {
96
+ nextIndex = i
97
+ break
98
+ }
99
+ }
100
+ } else {
101
+ for (let i = displayedData.length - 1; i >= 0; i--) {
102
+ if (isVisible(i)) {
103
+ nextIndex = i
104
+ break
105
+ }
106
+ }
107
+ }
108
+ if (nextIndex < 0) {
109
+ return
110
+ }
111
+ } else {
112
+ nextIndex = currentIndex + movement * directionMultiplier
113
+ const dataLength = selectTooltipAxisTicks(store)?.length || displayedData.length
114
+ if (dataLength === 0 || nextIndex >= dataLength || nextIndex < 0) {
115
+ return
116
+ }
117
+ }
118
+ const index = nextIndex.toString()
119
+ setKeyboardInteraction(setStore, true, index, coordinateForIndex(store, index))
120
+ }
121
+
122
+ function applyFocus(store: ChartState, setStore: SetStoreFunction<ChartState>): void {
123
+ const accessibilityLayerIsActive = store.rootProps.accessibilityLayer !== false
124
+ if (!accessibilityLayerIsActive) {
125
+ return
126
+ }
127
+ const keyboardInteraction = readChartState(store).tooltip.keyboardInteraction
128
+ if (keyboardInteraction.active) {
129
+ return
130
+ }
131
+ if (keyboardInteraction.index == null) {
132
+ const nextIndex = "0"
133
+ setKeyboardInteraction(setStore, true, nextIndex, coordinateForIndex(store, nextIndex))
134
+ }
135
+ }
136
+
137
+ function applyBlur(store: ChartState, setStore: SetStoreFunction<ChartState>): void {
138
+ const accessibilityLayerIsActive = store.rootProps.accessibilityLayer !== false
139
+ if (!accessibilityLayerIsActive) {
140
+ return
141
+ }
142
+ const keyboardInteraction = readChartState(store).tooltip.keyboardInteraction
143
+ if (keyboardInteraction.active) {
144
+ setKeyboardInteraction(setStore, false, keyboardInteraction.index, keyboardInteraction.coordinate)
145
+ }
146
+ }
147
+
148
+ /**
149
+ * Creates keyboard event handler functions that read from the Solid store and update it directly.
150
+ * Replaces the Redux createListenerMiddleware pattern for keyboard navigation.
151
+ */
152
+ export function createKeyboardEventHandlers(
153
+ store: ChartState,
154
+ setStore: SetStoreFunction<ChartState>,
155
+ ): KeyboardEventHandlers {
156
+ let rafId: number | null = null
157
+ let timeoutId: ReturnType<typeof setTimeout> | null = null
158
+ let latestKeyboardActionPayload: KeyboardEvent["key"] | null = null
159
+
160
+ function handleKeyDown(key: KeyboardEvent["key"]): void {
161
+ latestKeyboardActionPayload = key
162
+
163
+ if (rafId !== null) {
164
+ cancelAnimationFrame(rafId)
165
+ rafId = null
166
+ }
167
+
168
+ const { throttleDelay, throttledEvents } = store.eventSettings
169
+ const isThrottled = throttledEvents === "all" || throttledEvents.includes("keydown")
170
+
171
+ if (timeoutId !== null && (typeof throttleDelay !== "number" || !isThrottled)) {
172
+ clearTimeout(timeoutId)
173
+ timeoutId = null
174
+ }
175
+
176
+ const callback = () => {
177
+ try {
178
+ applyKeyDown(store, setStore, latestKeyboardActionPayload)
179
+ } finally {
180
+ rafId = null
181
+ timeoutId = null
182
+ }
183
+ }
184
+
185
+ if (!isThrottled) {
186
+ callback()
187
+ return
188
+ }
189
+
190
+ if (throttleDelay === "raf") {
191
+ rafId = requestAnimationFrame(callback)
192
+ } else if (typeof throttleDelay === "number") {
193
+ if (timeoutId === null) {
194
+ callback()
195
+ latestKeyboardActionPayload = null
196
+
197
+ timeoutId = setTimeout(() => {
198
+ if (latestKeyboardActionPayload) {
199
+ callback()
200
+ } else {
201
+ timeoutId = null
202
+ rafId = null
203
+ }
204
+ }, throttleDelay)
205
+ }
206
+ }
207
+ }
208
+
209
+ return {
210
+ handleBlur: () => applyBlur(store, setStore),
211
+ handleFocus: () => applyFocus(store, setStore),
212
+ handleKeyDown,
213
+ }
214
+ }
215
+
216
+ /**
217
+ * Action thunk wrappers for keyboard events, used with the dispatch pattern.
218
+ * Note: these are simplified versions without throttling. For full throttling, use createKeyboardEventHandlers.
219
+ */
220
+ export const focusAction = () => (setStore: SetStoreFunction<ChartState>, store: ChartState) =>
221
+ applyFocus(store, setStore)
222
+
223
+ export const blurAction = () => (setStore: SetStoreFunction<ChartState>, store: ChartState) =>
224
+ applyBlur(store, setStore)
225
+
226
+ export const keyDownAction =
227
+ (key: string) => (setStore: SetStoreFunction<ChartState>, store: ChartState) =>
228
+ applyKeyDown(store, setStore, key)
@@ -0,0 +1,21 @@
1
+ import type { LayoutType, Margin } from "../util/types"
2
+
3
+ export type ChartLayoutState = {
4
+ layoutType: LayoutType
5
+ width: number
6
+ height: number
7
+ margin: Margin
8
+ /**
9
+ * How much is the chart zoomed in.
10
+ * Used for scaling the mouse coordinates to the chart coordinates.
11
+ */
12
+ scale: number
13
+ }
14
+
15
+ export const initialLayoutState: ChartLayoutState = {
16
+ height: 0,
17
+ layoutType: "horizontal",
18
+ margin: { bottom: 5, left: 5, right: 5, top: 5 },
19
+ scale: 1,
20
+ width: 0,
21
+ }
@@ -0,0 +1,57 @@
1
+ import type { LayoutType, Size } from "../util/types"
2
+ import type {
3
+ HorizontalAlignmentType,
4
+ LegendPayload,
5
+ VerticalAlignmentType,
6
+ } from "../component/DefaultLegendContent"
7
+ import type { LegendItemSorter } from "../component/Legend"
8
+
9
+ /** Keyword or coordinate position; same vocabulary as Label. Avoids importing CartesianLabelPosition (cycle). */
10
+ export type LegendPosition =
11
+ | "top"
12
+ | "left"
13
+ | "right"
14
+ | "bottom"
15
+ | "inside"
16
+ | "outside"
17
+ | "insideLeft"
18
+ | "insideRight"
19
+ | "insideTop"
20
+ | "insideBottom"
21
+ | "insideTopLeft"
22
+ | "insideBottomLeft"
23
+ | "insideTopRight"
24
+ | "insideBottomRight"
25
+ | "insideStart"
26
+ | "insideEnd"
27
+ | "end"
28
+ | "center"
29
+ | "centerTop"
30
+ | "centerBottom"
31
+ | "middle"
32
+ | {
33
+ x?: number | string
34
+ y?: number | string
35
+ }
36
+
37
+ export type LegendSettings = {
38
+ align: HorizontalAlignmentType
39
+ itemSorter: LegendItemSorter | null
40
+ layout: LayoutType
41
+ verticalAlign: VerticalAlignmentType
42
+ position?: LegendPosition
43
+ offset?: number
44
+ }
45
+
46
+ /**
47
+ * The properties inside this state update independently of each other and quite often.
48
+ * When selecting, never select the whole state because you are going to get
49
+ * unnecessary re-renders. Select only the properties you need.
50
+ *
51
+ * This is why this state type is not exported - don't use it directly.
52
+ */
53
+ export type LegendState = {
54
+ payload: ReadonlyArray<ReadonlyArray<LegendPayload>>
55
+ settings: LegendSettings
56
+ size: Size
57
+ }