@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,86 @@
1
+ /* eslint-disable import/no-cycle */
2
+ import {
3
+ noInteraction,
4
+ TooltipIndex,
5
+ TooltipInteractionState,
6
+ TooltipState,
7
+ } from "../../tooltipSlice"
8
+ import { TooltipEventType } from "../../../util/types"
9
+ import { TooltipTrigger } from "../../../chart/types"
10
+
11
+ function chooseAppropriateMouseInteraction(
12
+ tooltipState: TooltipState,
13
+ tooltipEventType: TooltipEventType,
14
+ trigger: TooltipTrigger,
15
+ ): TooltipInteractionState | undefined {
16
+ if (tooltipEventType === "axis") {
17
+ if (trigger === "click") {
18
+ return tooltipState.axisInteraction.click
19
+ }
20
+ return tooltipState.axisInteraction.hover
21
+ }
22
+ if (trigger === "click") {
23
+ return tooltipState.itemInteraction.click
24
+ }
25
+ return tooltipState.itemInteraction.hover
26
+ }
27
+
28
+ function hasBeenActivePreviously(tooltipInteractionState: TooltipInteractionState): boolean {
29
+ return tooltipInteractionState.index != null
30
+ }
31
+
32
+ export const combineTooltipInteractionState = (
33
+ tooltipState: TooltipState,
34
+ tooltipEventType: TooltipEventType | undefined,
35
+ trigger: TooltipTrigger,
36
+ defaultIndex: TooltipIndex | undefined,
37
+ ): TooltipInteractionState => {
38
+ if (tooltipEventType == null) {
39
+ return noInteraction
40
+ }
41
+ const appropriateMouseInteraction = chooseAppropriateMouseInteraction(
42
+ tooltipState,
43
+ tooltipEventType,
44
+ trigger,
45
+ )
46
+
47
+ if (appropriateMouseInteraction == null) {
48
+ return noInteraction
49
+ }
50
+
51
+ if (appropriateMouseInteraction.active) {
52
+ return appropriateMouseInteraction
53
+ }
54
+
55
+ if (tooltipState.keyboardInteraction.active) {
56
+ return tooltipState.keyboardInteraction
57
+ }
58
+
59
+ if (tooltipState.syncInteraction.active && tooltipState.syncInteraction.index != null) {
60
+ return tooltipState.syncInteraction
61
+ }
62
+
63
+ const activeFromProps = tooltipState.settings.active === true
64
+
65
+ if (hasBeenActivePreviously(appropriateMouseInteraction)) {
66
+ if (activeFromProps) {
67
+ return {
68
+ ...appropriateMouseInteraction,
69
+ active: true,
70
+ }
71
+ }
72
+ } else if (defaultIndex != null) {
73
+ return {
74
+ active: true,
75
+ coordinate: undefined,
76
+ dataKey: undefined,
77
+ graphicalItemId: undefined,
78
+ index: defaultIndex,
79
+ }
80
+ }
81
+
82
+ return {
83
+ ...noInteraction,
84
+ coordinate: appropriateMouseInteraction.coordinate,
85
+ }
86
+ }
@@ -0,0 +1,205 @@
1
+ /* eslint-disable import/no-cycle */
2
+ import {
3
+ TooltipEntrySettings,
4
+ TooltipIndex,
5
+ TooltipPayload,
6
+ TooltipPayloadConfiguration,
7
+ TooltipPayloadEntry,
8
+ TooltipPayloadSearcher,
9
+ } from "../../tooltipSlice"
10
+ import { ChartData, ChartDataState } from "../../chartDataSlice"
11
+ import { DataKey, TooltipEventType } from "../../../util/types"
12
+ import { findEntryInArray } from "../../../util/DataUtils"
13
+ import { getTooltipEntry, getValueByDataKey } from "../../../util/ChartUtils"
14
+ import { getSliced } from "../../../util/getSliced"
15
+ import { ActiveLabel } from "../../../synchronisation/types"
16
+
17
+ type TooltipPayloadItemLike = {
18
+ name: TooltipEntrySettings["name"]
19
+ unit: TooltipEntrySettings["unit"]
20
+ dataKey: DataKey<unknown> | undefined
21
+ payload: unknown
22
+ color: string | undefined
23
+ fill: string | undefined
24
+ }
25
+
26
+ function parseName(value: unknown): TooltipEntrySettings["name"] {
27
+ if (typeof value === "string" || typeof value === "number") {
28
+ return value
29
+ }
30
+ return undefined
31
+ }
32
+
33
+ function parseUnit(value: unknown): TooltipEntrySettings["unit"] {
34
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
35
+ return value
36
+ }
37
+ return undefined
38
+ }
39
+
40
+ function parseDataKey(value: unknown): DataKey<unknown> | undefined {
41
+ if (typeof value === "string" || typeof value === "number") {
42
+ return value
43
+ }
44
+ if (typeof value === "function") {
45
+ return (obj: unknown) => value(obj)
46
+ }
47
+ return undefined
48
+ }
49
+
50
+ function parseColor(value: unknown): string | undefined {
51
+ if (typeof value === "string") {
52
+ return value
53
+ }
54
+ return undefined
55
+ }
56
+
57
+ function parseTooltipPayloadItem(item: unknown): TooltipPayloadItemLike | undefined {
58
+ if (item == null || typeof item !== "object") {
59
+ return undefined
60
+ }
61
+
62
+ const name = "name" in item ? parseName(item.name) : undefined
63
+ const unit = "unit" in item ? parseUnit(item.unit) : undefined
64
+ const dataKey = "dataKey" in item ? parseDataKey(item.dataKey) : undefined
65
+ const payload = "payload" in item ? item.payload : undefined
66
+ const color = "color" in item ? parseColor(item.color) : undefined
67
+ const fill = "fill" in item ? parseColor(item.fill) : undefined
68
+
69
+ return {
70
+ color,
71
+ dataKey,
72
+ fill,
73
+ name,
74
+ payload,
75
+ unit,
76
+ }
77
+ }
78
+
79
+ function selectFinalData(
80
+ dataDefinedOnItem: unknown,
81
+ dataDefinedOnChart: ChartData | undefined,
82
+ ): unknown {
83
+ /*
84
+ * If a payload has data specified directly from the graphical item, prefer that.
85
+ * Otherwise, fill in data from the chart level, using the same index.
86
+ */
87
+ if (dataDefinedOnItem != null) {
88
+ return dataDefinedOnItem
89
+ }
90
+ return dataDefinedOnChart
91
+ }
92
+
93
+ export const combineTooltipPayload = (
94
+ tooltipPayloadConfigurations: ReadonlyArray<TooltipPayloadConfiguration>,
95
+ activeIndex: TooltipIndex,
96
+ chartDataState: ChartDataState,
97
+ tooltipAxisDataKey: DataKey<unknown> | undefined,
98
+ activeLabel: ActiveLabel,
99
+ tooltipPayloadSearcher: TooltipPayloadSearcher | undefined,
100
+ tooltipEventType: TooltipEventType | undefined,
101
+ ): TooltipPayload | undefined => {
102
+ if (activeIndex == null || tooltipPayloadSearcher == null) {
103
+ return undefined
104
+ }
105
+ const { chartData, computedData, dataStartIndex, dataEndIndex } = chartDataState
106
+
107
+ const init: Array<TooltipPayloadEntry> = []
108
+
109
+ return tooltipPayloadConfigurations.reduce(
110
+ (agg, { dataDefinedOnItem, settings }): Array<TooltipPayloadEntry> => {
111
+ const finalData = selectFinalData(dataDefinedOnItem, chartData)
112
+
113
+ const sliced = Array.isArray(finalData)
114
+ ? getSliced(finalData, dataStartIndex, dataEndIndex)
115
+ : finalData
116
+
117
+ const finalDataKey: DataKey<unknown> | undefined = settings?.dataKey ?? tooltipAxisDataKey
118
+ const finalNameKey: DataKey<unknown> | undefined = settings?.nameKey
119
+ let tooltipPayload: unknown
120
+ if (
121
+ tooltipAxisDataKey &&
122
+ Array.isArray(sliced) &&
123
+ /*
124
+ * findEntryInArray won't work for Scatter because Scatter provides an array of arrays
125
+ * as tooltip payloads and findEntryInArray is not prepared to handle that.
126
+ * Sad but also ScatterChart only allows 'item' tooltipEventType
127
+ * and also this is only a problem if there are multiple Scatters and each has its own data array
128
+ * so let's fix that some other time.
129
+ */
130
+ !Array.isArray(sliced[0]) &&
131
+ /*
132
+ * If the tooltipEventType is 'axis', we should search for the dataKey in the sliced data
133
+ * because thanks to allowDuplicatedCategory=false, the order of elements in the array
134
+ * no longer matches the order of elements in the original data
135
+ * and so we need to search by the active dataKey + label rather than by index.
136
+ *
137
+ * The same happens if multiple graphical items are present in the chart
138
+ * and each of them has its own data array. Those arrays get concatenated
139
+ * and again the tooltip index no longer matches the original data.
140
+ *
141
+ * On the other hand the tooltipEventType 'item' should always search by index
142
+ * because we get the index from interacting over the individual elements
143
+ * which is always accurate, irrespective of the allowDuplicatedCategory setting.
144
+ */
145
+ tooltipEventType === "axis"
146
+ ) {
147
+ tooltipPayload = findEntryInArray(sliced, tooltipAxisDataKey, activeLabel)
148
+ if (tooltipPayload == null) {
149
+ tooltipPayload = tooltipPayloadSearcher(
150
+ sliced,
151
+ activeIndex,
152
+ computedData,
153
+ finalNameKey,
154
+ )
155
+ }
156
+ } else {
157
+ /*
158
+ * This is a problem because it assumes that the index is pointing to the displayed data
159
+ * which it isn't because the index is pointing to the tooltip ticks array.
160
+ * The above approach (with findEntryInArray) is the correct one, but it only works
161
+ * if the axis dataKey is defined explicitly, and if the data is an array of objects.
162
+ */
163
+ tooltipPayload = tooltipPayloadSearcher(sliced, activeIndex, computedData, finalNameKey)
164
+ }
165
+
166
+ if (Array.isArray(tooltipPayload)) {
167
+ tooltipPayload.forEach((item) => {
168
+ const parsedItem = parseTooltipPayloadItem(item)
169
+ const itemName = parsedItem?.name
170
+ const itemDataKey = parsedItem?.dataKey
171
+ const itemPayload = parsedItem?.payload
172
+ const newSettings: TooltipEntrySettings = {
173
+ ...settings,
174
+ /* Preserve item-level color/fill from graphical items. */
175
+ color: parsedItem?.color ?? settings?.color,
176
+ fill: parsedItem?.fill ?? settings?.fill,
177
+ name: itemName,
178
+ unit: parsedItem?.unit,
179
+ }
180
+ agg.push(
181
+ getTooltipEntry({
182
+ dataKey: itemDataKey,
183
+ name: itemName == null ? undefined : String(itemName),
184
+ payload: itemPayload,
185
+ tooltipEntrySettings: newSettings,
186
+ value: getValueByDataKey(itemPayload, itemDataKey),
187
+ }),
188
+ )
189
+ })
190
+ } else {
191
+ agg.push(
192
+ getTooltipEntry({
193
+ dataKey: finalDataKey,
194
+ name: getValueByDataKey(tooltipPayload, finalNameKey) ?? settings?.name,
195
+ payload: tooltipPayload,
196
+ tooltipEntrySettings: settings,
197
+ value: getValueByDataKey(tooltipPayload, finalDataKey),
198
+ }),
199
+ )
200
+ }
201
+ return agg
202
+ },
203
+ init,
204
+ )
205
+ }
@@ -0,0 +1,58 @@
1
+ /* eslint-disable import/no-cycle */
2
+ import { TooltipIndex, TooltipPayloadConfiguration, TooltipState } from "../../tooltipSlice"
3
+ import { TooltipEventType } from "../../../util/types"
4
+ import { TooltipTrigger } from "../../../chart/types"
5
+ import { GraphicalItemId } from "../../graphicalItemsSlice"
6
+
7
+ export const combineTooltipPayloadConfigurations = (
8
+ tooltipState: TooltipState,
9
+ tooltipEventType: TooltipEventType | undefined,
10
+ trigger: TooltipTrigger,
11
+ defaultIndex: TooltipIndex | undefined,
12
+ ): ReadonlyArray<TooltipPayloadConfiguration> => {
13
+ /* if tooltip reacts to axis interaction, then we display all items at the same time. */
14
+ if (tooltipEventType === "axis") {
15
+ return tooltipState.tooltipItemPayloads
16
+ }
17
+ /*
18
+ * By now we already know that tooltipEventType is 'item', so we can only search in itemInteractions.
19
+ * item means that only the hovered or clicked item will be present in the tooltip.
20
+ */
21
+ if (tooltipState.tooltipItemPayloads.length === 0) {
22
+ /* No point filtering if the payload is empty */
23
+ return []
24
+ }
25
+ let filterByGraphicalItemId: GraphicalItemId | undefined
26
+ if (trigger === "hover") {
27
+ filterByGraphicalItemId = tooltipState.itemInteraction.hover.graphicalItemId
28
+ } else {
29
+ filterByGraphicalItemId = tooltipState.itemInteraction.click.graphicalItemId
30
+ }
31
+ if (tooltipState.syncInteraction.active && filterByGraphicalItemId == null) {
32
+ /*
33
+ * When a tooltip is synchronised from another chart, the local itemInteraction
34
+ * has no graphicalItemId because the user hasn't hovered over this chart.
35
+ * In that case we show all tooltip items so the receiving chart can display
36
+ * its own data at the synced index — matching the behaviour of axis-type tooltips.
37
+ */
38
+ return tooltipState.tooltipItemPayloads
39
+ }
40
+ if (
41
+ filterByGraphicalItemId == null &&
42
+ (defaultIndex != null || tooltipState.keyboardInteraction.active)
43
+ ) {
44
+ /*
45
+ * So when we use `defaultIndex` - we don't have a dataKey to filter by because user did not hover over anything yet.
46
+ * In that case let's display the first item in the tooltip; after all, this is `item` interaction case,
47
+ * so we should display only one item at a time instead of all.
48
+ */
49
+ const firstItemPayload = tooltipState.tooltipItemPayloads[0]
50
+ if (firstItemPayload != null) {
51
+ return [firstItemPayload]
52
+ }
53
+ return []
54
+ }
55
+ return tooltipState.tooltipItemPayloads.filter(
56
+ (tpc) => tpc.settings?.graphicalItemId === filterByGraphicalItemId,
57
+ )
58
+ }
@@ -0,0 +1,12 @@
1
+ /* eslint-disable import/no-cycle */
2
+ import { ChartState } from "../store"
3
+ import { Margin } from "../../util/types"
4
+
5
+ export const selectChartWidth = (state: ChartState): number => state.layout.width
6
+
7
+ export const selectChartHeight = (state: ChartState): number => state.layout.height
8
+
9
+ export const selectContainerScale: (state: ChartState) => number = (state) =>
10
+ state.layout.scale
11
+
12
+ export const selectMargin = (state: ChartState): Margin => state.layout.margin
@@ -0,0 +1,88 @@
1
+ /* eslint-disable import/no-cycle */
2
+ import { ChartState } from "../store"
3
+ import { chartSelector } from "./chartSelector"
4
+ import { ChartData, ChartDataState } from "../chartDataSlice"
5
+
6
+ /**
7
+ * This selector always returns the data with the indexes set by a Brush.
8
+ * Trouble is, that might or might not be what you want.
9
+ *
10
+ * In charts with Brush, you will sometimes want to select the full range of data, and sometimes the one decided by the Brush
11
+ * - even if the Brush is active, the panorama inside the Brush should show the full range of data.
12
+ *
13
+ * So instead of this selector, consider using either selectChartDataAndAlwaysIgnoreIndexes or selectChartDataWithIndexesIfNotInPanorama
14
+ *
15
+ * @param state ChartState
16
+ * @returns data defined on the chart root element, such as BarChart or ScatterChart
17
+ */
18
+ export const selectChartDataWithIndexes = (state: ChartState): ChartDataState =>
19
+ state.chartData
20
+
21
+ /**
22
+ * This selector will always return the full range of data, ignoring the indexes set by a Brush.
23
+ * Useful for when you want to render the full range of data, even if a Brush is active.
24
+ * For example: in the Brush panorama, in Legend, in Tooltip.
25
+ */
26
+ export const selectChartDataAndAlwaysIgnoreIndexes = chartSelector(function selectChartDataAndAlwaysIgnoreIndexes(state: ChartState): ChartDataState {
27
+ const dataState = selectChartDataWithIndexes(state)
28
+ const dataEndIndex = dataState.chartData != null ? dataState.chartData.length - 1 : 0
29
+ return {
30
+ chartData: dataState.chartData,
31
+ computedData: dataState.computedData,
32
+ dataEndIndex,
33
+ dataStartIndex: 0,
34
+ }
35
+ })
36
+
37
+ export const selectChartDataWithIndexesIfNotInPanoramaPosition4 = chartSelector((
38
+ state: ChartState,
39
+ _unused1: unknown,
40
+ _unused2: unknown,
41
+ isPanorama: boolean,
42
+ ): ChartDataState => {
43
+ if (isPanorama) {
44
+ return selectChartDataAndAlwaysIgnoreIndexes(state)
45
+ }
46
+ return selectChartDataWithIndexes(state)
47
+ })
48
+
49
+ /**
50
+ * Returns the chart-level data sliced by the Brush indexes (full range in the panorama).
51
+ */
52
+ export const selectChartDataSliceIfNotInPanorama = chartSelector((
53
+ state: ChartState,
54
+ _unused1: unknown,
55
+ _unused2: unknown,
56
+ isPanorama: boolean,
57
+ ): ChartData => {
58
+ const { chartData, dataStartIndex, dataEndIndex } = selectChartDataWithIndexesIfNotInPanoramaPosition4(
59
+ state,
60
+ _unused1,
61
+ _unused2,
62
+ isPanorama,
63
+ )
64
+ return chartData != null ? chartData.slice(dataStartIndex, dataEndIndex + 1) : []
65
+ })
66
+
67
+ export const selectChartDataWithIndexesIfNotInPanoramaPosition3 = chartSelector((
68
+ state: ChartState,
69
+ _unused1: unknown,
70
+ isPanorama: boolean,
71
+ ): ChartDataState => {
72
+ if (isPanorama) {
73
+ return selectChartDataAndAlwaysIgnoreIndexes(state)
74
+ }
75
+ return selectChartDataWithIndexes(state)
76
+ })
77
+
78
+ /** Chart-level data slice ignoring Brush indexes (polar charts always use the full range). */
79
+ export const selectChartDataSliceIgnoringIndexes = chartSelector(function selectChartDataSliceIgnoringIndexes(state: ChartState): ChartData {
80
+ const { chartData, dataStartIndex, dataEndIndex } = selectChartDataAndAlwaysIgnoreIndexes(state)
81
+ return chartData != null ? chartData.slice(dataStartIndex, dataEndIndex + 1) : []
82
+ })
83
+
84
+ /** Chart-level data slice honoring Brush indexes (tooltip never renders in the panorama). */
85
+ export const selectChartDataSliceWithIndexes = chartSelector(function selectChartDataSliceWithIndexes(state: ChartState): ChartData {
86
+ const { chartData, dataStartIndex, dataEndIndex } = selectChartDataWithIndexes(state)
87
+ return chartData != null ? chartData.slice(dataStartIndex, dataEndIndex + 1) : []
88
+ })
@@ -0,0 +1,75 @@
1
+ /* eslint-disable import/no-cycle */
2
+ import { computeFunnelTrapezoids, type FunnelTrapezoidItem } from "../../cartesian/Funnel"
3
+ import type { ChartData } from "../chartDataSlice"
4
+ import type { ChartState } from "../store"
5
+ import { selectChartOffsetInternal } from "./selectChartOffsetInternal"
6
+ import { selectChartDataAndAlwaysIgnoreIndexes } from "./dataSelectors"
7
+ import type { ChartOffsetInternal, DataKey, TooltipType } from "../../util/types"
8
+ import { chartSelector } from "./chartSelector"
9
+ import type { GraphicalItemId } from "../graphicalItemsSlice"
10
+
11
+ export type ResolvedFunnelSettings = {
12
+ dataKey: DataKey<unknown>
13
+ data: ChartData | undefined
14
+ nameKey: DataKey<unknown>
15
+ tooltipType?: TooltipType
16
+ lastShapeType?: "triangle" | "rectangle"
17
+ reversed?: boolean
18
+ customWidth?: string | number
19
+ cells: ReadonlyArray<Record<string, unknown>>
20
+ presentationProps: Record<string, unknown> | null
21
+ id: GraphicalItemId
22
+ }
23
+
24
+ export const selectFunnelTrapezoids = chartSelector(function selectFunnelTrapezoids(state: ChartState, funnelSettings: ResolvedFunnelSettings): ReadonlyArray<FunnelTrapezoidItem> {
25
+ const offset: ChartOffsetInternal = selectChartOffsetInternal(state)
26
+ const { chartData } = selectChartDataAndAlwaysIgnoreIndexes(state)
27
+ const {
28
+ data,
29
+ dataKey,
30
+ nameKey,
31
+ tooltipType,
32
+ lastShapeType,
33
+ reversed,
34
+ customWidth,
35
+ cells,
36
+ presentationProps,
37
+ id: graphicalItemId,
38
+ } = funnelSettings
39
+
40
+ let displayedData: ChartData | undefined
41
+ if (data != null && data.length > 0) {
42
+ displayedData = data
43
+ } else if (chartData != null && chartData.length > 0) {
44
+ displayedData = chartData
45
+ }
46
+
47
+ if (displayedData && displayedData.length) {
48
+ displayedData = displayedData.map((entry: unknown, index: number) =>
49
+ Object.assign(
50
+ { payload: entry },
51
+ presentationProps,
52
+ entry as Record<string, unknown>,
53
+ cells && cells[index] ? cells[index] : undefined,
54
+ ),
55
+ )
56
+ } else if (cells && cells.length) {
57
+ displayedData = cells.map((cell: Record<string, unknown>) =>
58
+ Object.assign({}, presentationProps, cell),
59
+ )
60
+ } else {
61
+ return []
62
+ }
63
+
64
+ return computeFunnelTrapezoids({
65
+ customWidth,
66
+ dataKey,
67
+ displayedData,
68
+ graphicalItemId,
69
+ lastShapeType,
70
+ nameKey,
71
+ offset,
72
+ reversed,
73
+ tooltipType,
74
+ })
75
+ })
@@ -0,0 +1,30 @@
1
+ /* eslint-disable import/no-cycle */
2
+ import type { ChartState } from "../store"
3
+ import type { GraphicalItemId } from "../graphicalItemsSlice"
4
+ import { AxisId, defaultAxisId } from "../cartesianAxisSlice"
5
+ import type { CartesianItemState } from "../chartState"
6
+ import { chartSelector } from "./chartSelector"
7
+ import { readChartState } from "../chartState"
8
+
9
+ function isCartesianItem(item: { type: string }): item is CartesianItemState {
10
+ return (
11
+ item.type === "line" ||
12
+ item.type === "area" ||
13
+ item.type === "bar" ||
14
+ item.type === "scatter"
15
+ )
16
+ }
17
+
18
+ export const selectXAxisIdFromGraphicalItemId = chartSelector(function selectXAxisIdFromGraphicalItemId(state: ChartState, id: GraphicalItemId): AxisId {
19
+ const graphicalItems = readChartState(state).graphicalItems
20
+ const entry = graphicalItems?.[id]
21
+ if (entry == null || !isCartesianItem(entry)) return defaultAxisId
22
+ return entry.settings.xAxisId ?? defaultAxisId
23
+ })
24
+
25
+ export const selectYAxisIdFromGraphicalItemId = chartSelector(function selectYAxisIdFromGraphicalItemId(state: ChartState, id: GraphicalItemId): AxisId {
26
+ const graphicalItems = readChartState(state).graphicalItems
27
+ const entry = graphicalItems?.[id]
28
+ if (entry == null || !isCartesianItem(entry)) return defaultAxisId
29
+ return entry.settings.yAxisId ?? defaultAxisId
30
+ })
@@ -0,0 +1,29 @@
1
+ /* eslint-disable import/no-cycle */
2
+ import sortBy from "es-toolkit/compat/sortBy"
3
+ import type { ChartState } from "../store"
4
+ import type { LegendSettings } from "../legendSlice"
5
+ import type { LegendPayload } from "../../component/DefaultLegendContent"
6
+ import type { Size } from "../../util/types"
7
+ import { chartSelector } from "./chartSelector"
8
+ import { readChartState } from "../chartState"
9
+
10
+ export const selectLegendSettings = (state: ChartState): LegendSettings => {
11
+ return readChartState(state).legend.settings
12
+ }
13
+
14
+ export const selectLegendSize = (state: ChartState): Size => {
15
+ return readChartState(state).legend.size
16
+ }
17
+
18
+ const selectAllLegendPayload2DArray = (
19
+ state: ChartState,
20
+ ): ReadonlyArray<ReadonlyArray<LegendPayload>> => {
21
+ return readChartState(state).legend.payload
22
+ }
23
+
24
+ export const selectLegendPayload = chartSelector(function selectLegendPayload(state: ChartState): ReadonlyArray<LegendPayload> {
25
+ const payloads = selectAllLegendPayload2DArray(state)
26
+ const { itemSorter } = selectLegendSettings(state)
27
+ const flat = payloads.flat(1)
28
+ return itemSorter ? sortBy(flat, itemSorter) : flat
29
+ })