@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,310 @@
1
+ /* eslint-disable import/no-cycle */
2
+ import type { JSX } from '@solidjs/web';
3
+ import type { ChartState } from "../store"
4
+ import {
5
+ type BaseAxisWithScale,
6
+ selectAxisWithScale,
7
+ selectCartesianAxisSize,
8
+ selectStackGroups,
9
+ selectTicksOfGraphicalItem,
10
+ selectUnfilteredCartesianItems,
11
+ } from "./axisSelectors"
12
+ import type { XAxisSettings, YAxisSettings } from "../cartesianAxisSlice"
13
+ import { isNullish } from "../../util/DataUtils"
14
+ import { type BarPositionPosition, getBandSizeOfAxis, type StackId } from "../../util/ChartUtils"
15
+ import type {
16
+ CartesianViewBoxRequired,
17
+ ChartOffsetInternal,
18
+ DataKey,
19
+ TickItem,
20
+ } from "../../util/types"
21
+ import { type BarRectangleItem, computeBarRectangles } from "../../cartesian/Bar"
22
+ import { selectChartLayout } from "../../context/chartLayoutContext"
23
+ import type { ChartData } from "../chartDataSlice"
24
+ import { selectChartDataWithIndexesIfNotInPanoramaPosition3 } from "./dataSelectors"
25
+ import { selectAxisViewBox, selectChartOffsetInternal } from "./selectChartOffsetInternal"
26
+ import {
27
+ selectBarCategoryGap,
28
+ selectBarGap,
29
+ selectRootBarSize,
30
+ selectRootMaxBarSize,
31
+ } from "./rootPropsSelectors"
32
+ import type { AllStackGroups, StackSeries } from "../../util/stacks/stackTypes"
33
+ import type { BarSettings } from "../types/BarSettings"
34
+
35
+ /** Optional overrides — bypass the axis-settings lookup on hot animation frames. */
36
+ export type BarAxisOverrides = {
37
+ xAxis?: XAxisSettings
38
+ yAxis?: YAxisSettings
39
+ barSettings?: BarSettings
40
+ }
41
+ import type { GraphicalItemId } from "../graphicalItemsSlice"
42
+ import { type BarCategory, combineBarSizeList } from "./combiners/combineBarSizeList"
43
+ import { combineAllBarPositions } from "./combiners/combineAllBarPositions"
44
+ import { combineStackedData } from "./combiners/combineStackedData"
45
+ import { chartSelector } from "./chartSelector"
46
+ import {
47
+ selectXAxisIdFromGraphicalItemId,
48
+ selectYAxisIdFromGraphicalItemId,
49
+ } from "./graphicalItemSelectors"
50
+ import { combineBarPosition } from "./combiners/combineBarPosition"
51
+
52
+ const selectSynchronisedBarSettings = chartSelector(function selectSynchronisedBarSettings(state: ChartState, id: GraphicalItemId): BarSettings | undefined {
53
+ const graphicalItems = selectUnfilteredCartesianItems(state)
54
+ return graphicalItems.filter((item) => item.type === "bar").find((item) => item.id === id) as
55
+ | BarSettings
56
+ | undefined
57
+ })
58
+
59
+ export const selectMaxBarSize = chartSelector(function selectMaxBarSize(_state: ChartState, id: GraphicalItemId): number | undefined {
60
+ const barSettings = selectSynchronisedBarSettings(_state, id)
61
+ return barSettings?.maxBarSize
62
+ })
63
+
64
+ export const selectAllVisibleBars = chartSelector(function selectAllVisibleBars(state: ChartState, id: GraphicalItemId, isPanorama: boolean): ReadonlyArray<BarSettings> {
65
+ const layout = selectChartLayout(state)
66
+ const allItems = selectUnfilteredCartesianItems(state)
67
+ const xAxisId = selectXAxisIdFromGraphicalItemId(state, id)
68
+ const yAxisId = selectYAxisIdFromGraphicalItemId(state, id)
69
+ return allItems
70
+ .filter((i) => {
71
+ if (layout === "horizontal") {
72
+ return i.xAxisId === xAxisId
73
+ }
74
+ return i.yAxisId === yAxisId
75
+ })
76
+ .filter((i) => i.isPanorama === isPanorama)
77
+ .filter((i) => i.hide === false)
78
+ .filter((i) => i.type === "bar") as ReadonlyArray<BarSettings>
79
+ })
80
+
81
+ export type SizeList = ReadonlyArray<BarCategory>
82
+
83
+ const selectBarStackGroups = chartSelector((
84
+ state: ChartState,
85
+ id: GraphicalItemId,
86
+ isPanorama: boolean,
87
+ ): AllStackGroups | undefined => {
88
+ const layout = selectChartLayout(state)
89
+ const xAxisId = selectXAxisIdFromGraphicalItemId(state, id)
90
+ const yAxisId = selectYAxisIdFromGraphicalItemId(state, id)
91
+ if (xAxisId == null || yAxisId == null) {
92
+ return undefined
93
+ }
94
+ if (layout === "horizontal") {
95
+ return selectStackGroups(state, "yAxis", yAxisId, isPanorama)
96
+ }
97
+ return selectStackGroups(state, "xAxis", xAxisId, isPanorama)
98
+ })
99
+
100
+ export const selectBarCartesianAxisSize = chartSelector((state: ChartState, id: GraphicalItemId) => {
101
+ const layout = selectChartLayout(state)
102
+ const xAxisId = selectXAxisIdFromGraphicalItemId(state, id)
103
+ const yAxisId = selectYAxisIdFromGraphicalItemId(state, id)
104
+ if (xAxisId == null || yAxisId == null) {
105
+ return undefined
106
+ }
107
+ if (layout === "horizontal") {
108
+ return selectCartesianAxisSize(state, "xAxis", xAxisId)
109
+ }
110
+ return selectCartesianAxisSize(state, "yAxis", yAxisId)
111
+ })
112
+
113
+ export const selectBarSizeList = chartSelector(function selectBarSizeList(state: ChartState, id: GraphicalItemId, isPanorama: boolean): SizeList {
114
+ return combineBarSizeList(
115
+ selectAllVisibleBars(state, id, isPanorama),
116
+ selectRootBarSize(state),
117
+ selectBarCartesianAxisSize(state, id),
118
+ )
119
+ })
120
+
121
+ export const selectBarBandSize = chartSelector(function selectBarBandSize(state: ChartState, id: GraphicalItemId, isPanorama: boolean): number {
122
+ const barSettings = selectSynchronisedBarSettings(state, id)
123
+ if (barSettings == null) {
124
+ return 0
125
+ }
126
+ const xAxisId = selectXAxisIdFromGraphicalItemId(state, id)
127
+ const yAxisId = selectYAxisIdFromGraphicalItemId(state, id)
128
+ if (xAxisId == null || yAxisId == null) {
129
+ return 0
130
+ }
131
+ const layout = selectChartLayout(state)
132
+ const globalMaxBarSize: number | undefined = selectRootMaxBarSize(state)
133
+ const { maxBarSize: childMaxBarSize } = barSettings
134
+ const maxBarSize: number | undefined = isNullish(childMaxBarSize)
135
+ ? globalMaxBarSize
136
+ : childMaxBarSize
137
+ let axis: BaseAxisWithScale | undefined
138
+ let ticks: ReadonlyArray<TickItem> | undefined
139
+ if (layout === "horizontal") {
140
+ axis = selectAxisWithScale(state, "xAxis", xAxisId, isPanorama)
141
+ ticks = selectTicksOfGraphicalItem(state, "xAxis", xAxisId, isPanorama)
142
+ } else {
143
+ axis = selectAxisWithScale(state, "yAxis", yAxisId, isPanorama)
144
+ ticks = selectTicksOfGraphicalItem(state, "yAxis", yAxisId, isPanorama)
145
+ }
146
+ return getBandSizeOfAxis(axis, ticks, true) ?? maxBarSize ?? 0
147
+ })
148
+
149
+ export const selectAxisBandSize = chartSelector(function selectAxisBandSize(state: ChartState, id: GraphicalItemId, isPanorama: boolean): number | undefined {
150
+ const layout = selectChartLayout(state)
151
+ const xAxisId = selectXAxisIdFromGraphicalItemId(state, id)
152
+ const yAxisId = selectYAxisIdFromGraphicalItemId(state, id)
153
+ if (xAxisId == null || yAxisId == null) {
154
+ return undefined
155
+ }
156
+ let axis: BaseAxisWithScale | undefined
157
+ let ticks: ReadonlyArray<TickItem> | undefined
158
+ if (layout === "horizontal") {
159
+ axis = selectAxisWithScale(state, "xAxis", xAxisId, isPanorama)
160
+ ticks = selectTicksOfGraphicalItem(state, "xAxis", xAxisId, isPanorama)
161
+ } else {
162
+ axis = selectAxisWithScale(state, "yAxis", yAxisId, isPanorama)
163
+ ticks = selectTicksOfGraphicalItem(state, "yAxis", yAxisId, isPanorama)
164
+ }
165
+ return getBandSizeOfAxis(axis, ticks)
166
+ })
167
+
168
+ export type BarWithPosition = {
169
+ stackId: StackId | undefined
170
+ /**
171
+ * List of dataKeys of items stacked at this position.
172
+ * All of these Bars are either sharing the same stackId,
173
+ * or this is an array with one Bar because it has no stackId defined.
174
+ *
175
+ * This structure limits us to having one dataKey only once per stack which I think is reasonable.
176
+ * People who want to have the same data twice can duplicate their data to have two distinct dataKeys.
177
+ */
178
+ dataKeys: ReadonlyArray<DataKey<unknown>>
179
+ /**
180
+ * Position of this stack in absolute pixels measured from the start of the chart
181
+ */
182
+ position: BarPositionPosition
183
+ }
184
+
185
+ export const selectAllBarPositions = chartSelector(function selectAllBarPositions(state: ChartState, id: GraphicalItemId, isPanorama: boolean): ReadonlyArray<BarWithPosition> | undefined {
186
+ return combineAllBarPositions(
187
+ selectBarSizeList(state, id, isPanorama),
188
+ selectRootMaxBarSize(state),
189
+ selectBarGap(state),
190
+ selectBarCategoryGap(state),
191
+ selectBarBandSize(state, id, isPanorama),
192
+ selectAxisBandSize(state, id, isPanorama),
193
+ selectMaxBarSize(state, id),
194
+ )
195
+ })
196
+
197
+ const selectXAxisWithScale = chartSelector((
198
+ state: ChartState,
199
+ id: GraphicalItemId,
200
+ isPanorama: boolean,
201
+ override?: XAxisSettings,
202
+ ) => {
203
+ const xAxisId = selectXAxisIdFromGraphicalItemId(state, id)
204
+ if (xAxisId == null) {
205
+ return undefined
206
+ }
207
+ return selectAxisWithScale(state, "xAxis", xAxisId, isPanorama, override)
208
+ })
209
+
210
+ const selectYAxisWithScale = chartSelector((
211
+ state: ChartState,
212
+ id: GraphicalItemId,
213
+ isPanorama: boolean,
214
+ override?: YAxisSettings,
215
+ ) => {
216
+ const yAxisId = selectYAxisIdFromGraphicalItemId(state, id)
217
+ if (yAxisId == null) {
218
+ return undefined
219
+ }
220
+ return selectAxisWithScale(state, "yAxis", yAxisId, isPanorama, override)
221
+ })
222
+
223
+ const selectXAxisTicks = chartSelector((state: ChartState, id: GraphicalItemId, isPanorama: boolean) => {
224
+ const xAxisId = selectXAxisIdFromGraphicalItemId(state, id)
225
+ if (xAxisId == null) {
226
+ return undefined
227
+ }
228
+ return selectTicksOfGraphicalItem(state, "xAxis", xAxisId, isPanorama)
229
+ })
230
+
231
+ const selectYAxisTicks = chartSelector((state: ChartState, id: GraphicalItemId, isPanorama: boolean) => {
232
+ const yAxisId = selectYAxisIdFromGraphicalItemId(state, id)
233
+ if (yAxisId == null) {
234
+ return undefined
235
+ }
236
+ return selectTicksOfGraphicalItem(state, "yAxis", yAxisId, isPanorama)
237
+ })
238
+
239
+ export const selectBarPosition = chartSelector(function selectBarPosition(state: ChartState, id: GraphicalItemId, isPanorama: boolean): BarPositionPosition | undefined {
240
+ return combineBarPosition(
241
+ selectAllBarPositions(state, id, isPanorama),
242
+ selectSynchronisedBarSettings(state, id),
243
+ )
244
+ })
245
+
246
+ export const selectStackedDataOfItem = chartSelector(function selectStackedDataOfItem(state: ChartState, id: GraphicalItemId, isPanorama: boolean): StackSeries | undefined {
247
+ return combineStackedData(
248
+ selectBarStackGroups(state, id, isPanorama),
249
+ selectSynchronisedBarSettings(state, id),
250
+ )
251
+ })
252
+
253
+ export const selectBarRectangles = chartSelector(function selectBarRectangles(state: ChartState, id: GraphicalItemId, isPanorama: boolean, cells: ReadonlyArray<JSX.Element> | undefined, xAxisOverride?: XAxisSettings, yAxisOverride?: YAxisSettings, barSettingsOverride?: BarSettings): ReadonlyArray<BarRectangleItem> | undefined {
254
+ const offset: ChartOffsetInternal = selectChartOffsetInternal(state)
255
+ const axisViewBox: CartesianViewBoxRequired = selectAxisViewBox(state)
256
+ const xAxis = selectXAxisWithScale(state, id, isPanorama, xAxisOverride)
257
+ const yAxis = selectYAxisWithScale(state, id, isPanorama, yAxisOverride)
258
+ const xAxisTicks = selectXAxisTicks(state, id, isPanorama)
259
+ const yAxisTicks = selectYAxisTicks(state, id, isPanorama)
260
+ const pos = selectBarPosition(state, id, isPanorama)
261
+ const layout = selectChartLayout(state)
262
+ const { chartData, dataStartIndex, dataEndIndex } =
263
+ selectChartDataWithIndexesIfNotInPanoramaPosition3(state, undefined, isPanorama)
264
+ const bandSize = selectAxisBandSize(state, id, isPanorama)
265
+ const stackedData = selectStackedDataOfItem(state, id, isPanorama)
266
+ const barSettings = barSettingsOverride ?? selectSynchronisedBarSettings(state, id)
267
+
268
+ if (
269
+ barSettings == null ||
270
+ pos == null ||
271
+ axisViewBox == null ||
272
+ (layout !== "horizontal" && layout !== "vertical") ||
273
+ xAxis == null ||
274
+ yAxis == null ||
275
+ xAxisTicks == null ||
276
+ yAxisTicks == null ||
277
+ bandSize == null
278
+ ) {
279
+ return undefined
280
+ }
281
+ const { data } = barSettings
282
+
283
+ let displayedData: ChartData | undefined
284
+ if (data != null && data.length > 0) {
285
+ displayedData = data
286
+ } else {
287
+ displayedData = chartData?.slice(dataStartIndex, dataEndIndex + 1)
288
+ }
289
+
290
+ if (displayedData == null) {
291
+ return undefined
292
+ }
293
+
294
+ return computeBarRectangles({
295
+ bandSize,
296
+ barSettings,
297
+ cells,
298
+ dataStartIndex,
299
+ displayedData,
300
+ layout,
301
+ offset,
302
+ parentViewBox: axisViewBox,
303
+ pos,
304
+ stackedData,
305
+ xAxis,
306
+ xAxisTicks,
307
+ yAxis,
308
+ yAxisTicks,
309
+ })
310
+ })
@@ -0,0 +1,77 @@
1
+ /* eslint-disable import/no-cycle */
2
+ import type { ChartState } from "../store"
3
+ import type { NormalizedStackId } from "../../util/ChartUtils"
4
+ import type { BarSettings } from "../types/BarSettings"
5
+ import { selectUnfilteredCartesianItems } from "./axisSelectors"
6
+ import type { CartesianGraphicalItemSettings } from "../graphicalItemsSlice"
7
+ import { chartSelector } from "./chartSelector"
8
+ import { selectBarRectangles } from "./barSelectors"
9
+
10
+ export const selectAllBarsInStack = chartSelector(function selectAllBarsInStack(state: ChartState, stackId: NormalizedStackId, isPanorama: boolean): ReadonlyArray<BarSettings> {
11
+ const allItems: ReadonlyArray<CartesianGraphicalItemSettings> =
12
+ selectUnfilteredCartesianItems(state)
13
+ return allItems
14
+ .filter((i) => i.type === "bar")
15
+ .filter((i) => i.stackId === stackId)
16
+ .filter((i) => i.isPanorama === isPanorama)
17
+ .filter((i) => !i.hide) as ReadonlyArray<BarSettings>
18
+ })
19
+
20
+ const selectAllBarIdsInStack = chartSelector(function selectAllBarIdsInStack(state: ChartState, stackId: NormalizedStackId, isPanorama: boolean) {
21
+ return selectAllBarsInStack(state, stackId, isPanorama).map((bar) => bar.id)
22
+ })
23
+
24
+ export type BarStackItem = {
25
+ x: number
26
+ y: number
27
+ width: number
28
+ height: number
29
+ }
30
+
31
+ /**
32
+ * Takes two rectangles and returns a new rectangle that encompasses both.
33
+ * It takes the minimum x and y, and the maximum width and height.
34
+ * It handles overlapping rectangles, and rectangles with a gap between them.
35
+ * @param rect1
36
+ * @param rect2
37
+ */
38
+ export const expandRectangle = (
39
+ rect1: BarStackItem | undefined,
40
+ rect2: BarStackItem | undefined,
41
+ ): BarStackItem | undefined => {
42
+ if (!rect1) {
43
+ return rect2
44
+ }
45
+ if (!rect2) {
46
+ return rect1
47
+ }
48
+ const x = Math.min(rect1.x, rect1.x + rect1.width, rect2.x, rect2.x + rect2.width)
49
+ const y = Math.min(rect1.y, rect1.y + rect1.height, rect2.y, rect2.y + rect2.height)
50
+ const maxX = Math.max(rect1.x, rect1.x + rect1.width, rect2.x, rect2.x + rect2.width)
51
+ const maxY = Math.max(rect1.y, rect1.y + rect1.height, rect2.y, rect2.y + rect2.height)
52
+ const width = maxX - x
53
+ const height = maxY - y
54
+ return { height, width, x, y }
55
+ }
56
+
57
+ function combineStackRects(
58
+ state: ChartState,
59
+ stackId: NormalizedStackId,
60
+ isPanorama: boolean,
61
+ ): ReadonlyArray<BarStackItem | undefined> {
62
+ const allBarIds = selectAllBarIdsInStack(state, stackId, isPanorama)
63
+ const stackRects: Array<BarStackItem | undefined> = []
64
+ allBarIds.forEach((barId) => {
65
+ const rectangles = selectBarRectangles(state, barId, isPanorama, undefined)
66
+ rectangles?.forEach((rect) => {
67
+ /* Rectangles are filtered (zero dimension), so index by the original data position. */
68
+ const rectIndex = rect.originalDataIndex
69
+ stackRects[rectIndex] = expandRectangle(stackRects[rectIndex], rect)
70
+ })
71
+ })
72
+ return stackRects
73
+ }
74
+
75
+ export const selectStackRects = chartSelector(function selectStackRects(state: ChartState, stackId: NormalizedStackId, isPanorama: boolean): ReadonlyArray<BarStackItem | undefined> {
76
+ return combineStackRects(state, stackId, isPanorama)
77
+ })
@@ -0,0 +1,33 @@
1
+ /* eslint-disable import/no-cycle */
2
+ import type { ChartState } from "../store"
3
+ import { readChartState } from "../chartState"
4
+ import { selectChartOffsetInternal } from "./selectChartOffsetInternal"
5
+ import { selectMargin } from "./containerSelectors"
6
+ import { isNumber } from "../../util/DataUtils"
7
+ import { chartSelector } from "./chartSelector"
8
+ import type { BrushSettings } from "../brushSlice"
9
+
10
+ export const selectBrushSettings = (state: ChartState): BrushSettings => {
11
+ return readChartState(state).brush
12
+ }
13
+
14
+ export type BrushDimensions = {
15
+ x: number
16
+ y: number
17
+ width: number
18
+ height: number
19
+ }
20
+
21
+ export const selectBrushDimensions = chartSelector(function selectBrushDimensions(state: ChartState): BrushDimensions {
22
+ const brushSettings = selectBrushSettings(state)
23
+ const offset = selectChartOffsetInternal(state)
24
+ const margin = selectMargin(state)
25
+ return {
26
+ height: brushSettings.height,
27
+ width: isNumber(brushSettings.width) ? brushSettings.width : offset.width,
28
+ x: isNumber(brushSettings.x) ? brushSettings.x : offset.left,
29
+ y: isNumber(brushSettings.y)
30
+ ? brushSettings.y
31
+ : offset.top + offset.height + offset.brushBottom - (margin?.bottom || 0),
32
+ }
33
+ })
@@ -0,0 +1,185 @@
1
+ import { $PROXY, createMemo, onCleanup, runWithOwner } from "solid-js"
2
+ import type { Accessor, Owner } from "solid-js"
3
+ import type { ChartState } from "../chartState"
4
+
5
+ /*
6
+ * Per-chart memoized selector graph — the Solid stand-in for upstream's reselect `createSelector`.
7
+ *
8
+ * A wrapped selector called with a chart store resolves to one memo per (selector, argument tuple),
9
+ * owned by the chart provider and shared by every consumer. Each memo tracks only the store reads
10
+ * and selector reads of its own body, so an upstream memo that did not change (by `equals`) stops
11
+ * propagation exactly like a reselect cache hit.
12
+ *
13
+ * Stores without a registered owner (unit tests building a bare store, code outside a provider)
14
+ * call the raw function, so behavior is identical either way.
15
+ */
16
+
17
+ type Selector<A extends unknown[], R> = (state: ChartState, ...args: A) => R
18
+
19
+ type ArgNode = {
20
+ memo: Accessor<unknown> | undefined
21
+ children: Map<unknown, ArgNode> | undefined
22
+ }
23
+
24
+ type ChartCache = { owner: Owner; roots: WeakMap<object, ArgNode> }
25
+
26
+ const chartCaches = new WeakMap<ChartState, ChartCache>()
27
+
28
+ const newNode = (): ArgNode => ({ children: undefined, memo: undefined })
29
+
30
+ const isObjectArg = (value: unknown): boolean =>
31
+ (typeof value === "object" && value !== null) || typeof value === "function"
32
+
33
+ /* Map keys use SameValueZero, so undefined and NaN are valid keys without a sentinel. */
34
+ function childNode(node: ArgNode, key: unknown): ArgNode {
35
+ node.children ??= new Map()
36
+ let next = node.children.get(key)
37
+ if (next === undefined) {
38
+ next = newNode()
39
+ node.children.set(key, next)
40
+ }
41
+ return next
42
+ }
43
+
44
+ const isStoreNode = (value: object): boolean => (value as { [$PROXY]?: unknown })[$PROXY] !== undefined
45
+
46
+ const isPlainObject = (value: unknown): value is Record<string, unknown> => {
47
+ if (typeof value !== "object" || value === null) {
48
+ return false
49
+ }
50
+ const proto = Object.getPrototypeOf(value)
51
+ return proto === Object.prototype || proto === null
52
+ }
53
+
54
+ /**
55
+ * Default output equality: `===`, then element-wise `===` for arrays, then own-key shallow `===`
56
+ * for plain non-store objects. Never deep — data arrays are compared by element identity only.
57
+ */
58
+ export function defaultSelectorEquals(a: unknown, b: unknown): boolean {
59
+ if (a === b) {
60
+ return true
61
+ }
62
+ if (Array.isArray(a)) {
63
+ if (!Array.isArray(b) || a.length !== b.length) {
64
+ return false
65
+ }
66
+ for (let i = 0; i < a.length; i++) {
67
+ if (a[i] !== b[i]) {
68
+ return false
69
+ }
70
+ }
71
+ return true
72
+ }
73
+ /* Distinct store nodes are never equal: keeping the old node would leave readers tracking
74
+ a different live object than the one the selector now resolves to. */
75
+ if (!isPlainObject(a) || !isPlainObject(b) || isStoreNode(a) || isStoreNode(b)) {
76
+ return false
77
+ }
78
+ const aKeys = Object.keys(a)
79
+ if (aKeys.length !== Object.keys(b).length) {
80
+ return false
81
+ }
82
+ for (const key of aKeys) {
83
+ if (a[key] !== b[key] || !(key in b)) {
84
+ return false
85
+ }
86
+ }
87
+ return true
88
+ }
89
+
90
+ /**
91
+ * Binds a chart store to the owner its selector memos live under. Called once per chart provider;
92
+ * the cache is dropped when that owner is disposed.
93
+ */
94
+ export function registerChartOwner(state: ChartState, owner: Owner | null): void {
95
+ if (owner == null) {
96
+ return
97
+ }
98
+ chartCaches.set(state, { owner, roots: new WeakMap() })
99
+ onCleanup(() => {
100
+ chartCaches.delete(state)
101
+ })
102
+ }
103
+
104
+ /** The owner registered for a chart store, if any. */
105
+ export function ownerFor(state: ChartState): Owner | undefined {
106
+ return chartCaches.get(state)?.owner
107
+ }
108
+
109
+ /*
110
+ * A memo keyed by stale arguments (an old settings node) can recompute in the same flush that its
111
+ * consumer will use to switch to new arguments. Errors are therefore captured and rethrown only to
112
+ * a reader, so a discarded stale computation never halts the reactive system.
113
+ */
114
+ class SelectorError {
115
+ constructor(readonly error: unknown) {}
116
+ }
117
+
118
+ const withErrorBox = (equals: (prev: unknown, next: unknown) => boolean) => (prev: unknown, next: unknown) =>
119
+ !(prev instanceof SelectorError) && !(next instanceof SelectorError) && equals(prev, next)
120
+
121
+ export type ChartSelectorOptions<R> = {
122
+ equals?: (prev: R, next: R) => boolean
123
+ }
124
+
125
+ /**
126
+ * Wraps a selector so calls on a provider-owned chart store share one memo per argument tuple.
127
+ * Same signature as `fn`.
128
+ *
129
+ * Only all-primitive tuples are memoized. A call carrying an object argument (settings node,
130
+ * cells, overrides) runs the raw function: a memo closed over a settings node that was later
131
+ * replaced would keep recomputing against new data until its consumer let go, running stale
132
+ * user callbacks such as a previous `dataKey` (recharts#4935).
133
+ *
134
+ * Do not wrap selectors whose arguments span an unbounded primitive space (pointer coordinates):
135
+ * every distinct tuple keeps a trie entry for the chart's lifetime.
136
+ *
137
+ * Memos are lazy: an unobserved memo goes dormant (detached from its sources and the owner)
138
+ * instead of recomputing on every write, and a later read reawakens it, so untracked readers such
139
+ * as event middleware cost no more than the raw function.
140
+ */
141
+ export function chartSelector<A extends unknown[], R>(
142
+ fn: Selector<A, R>,
143
+ options?: ChartSelectorOptions<R>,
144
+ ): Selector<A, R> {
145
+ const equals = withErrorBox((options?.equals ?? defaultSelectorEquals) as (prev: unknown, next: unknown) => boolean)
146
+ const selector = (state: ChartState, ...args: A): R => {
147
+ const cache = chartCaches.get(state)
148
+ if (cache === undefined) {
149
+ return fn(state, ...args)
150
+ }
151
+ let node = cache.roots.get(fn)
152
+ if (node === undefined) {
153
+ node = newNode()
154
+ cache.roots.set(fn, node)
155
+ }
156
+ for (const arg of args) {
157
+ if (isObjectArg(arg)) {
158
+ return fn(state, ...args)
159
+ }
160
+ node = childNode(node, arg)
161
+ }
162
+ let memo = node.memo
163
+ if (memo === undefined) {
164
+ const compute = (): unknown => {
165
+ try {
166
+ return fn(state, ...args)
167
+ } catch (error) {
168
+ return new SelectorError(error)
169
+ }
170
+ }
171
+ memo = runWithOwner(cache.owner, () =>
172
+ createMemo<unknown>(compute, { equals, lazy: true, sync: true, transparent: true }),
173
+ )
174
+ node.memo = memo
175
+ }
176
+ const value = memo()
177
+ if (value instanceof SelectorError) {
178
+ throw value.error
179
+ }
180
+ return value as R
181
+ }
182
+ /* Keep the arity of the wrapped function; hook-compat checks read `selector.length`. */
183
+ Object.defineProperty(selector, "length", { value: fn.length })
184
+ return selector
185
+ }
@@ -0,0 +1,16 @@
1
+ /* eslint-disable import/no-cycle */
2
+ import { TickItem } from "../../../util/types"
3
+ import { TooltipIndex } from "../../tooltipSlice"
4
+ import { isNan } from "../../../util/DataUtils"
5
+ import { ActiveLabel } from "../../../synchronisation/types"
6
+
7
+ export const combineActiveLabel = (
8
+ tooltipTicks: ReadonlyArray<TickItem> | undefined,
9
+ activeIndex: TooltipIndex,
10
+ ): ActiveLabel => {
11
+ const n = Number(activeIndex)
12
+ if (isNan(n) || activeIndex == null) {
13
+ return undefined
14
+ }
15
+ return n >= 0 ? tooltipTicks?.[n]?.value : undefined
16
+ }