@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,95 @@
1
+ /* eslint-disable import/no-cycle */
2
+ import { TooltipIndex, TooltipInteractionState } from "../../tooltipSlice"
3
+ import { ChartData } from "../../chartDataSlice"
4
+ import { isWellBehavedNumber } from "../../../util/isWellBehavedNumber"
5
+ import { DataKey, CategoricalDomain, NumberDomain } from "../../../util/types"
6
+ import { getValueByDataKey } from "../../../util/ChartUtils"
7
+ import { isWellFormedNumberDomain } from "../../../util/isDomainSpecifiedByUser"
8
+
9
+ function toFiniteNumber(value: unknown): number | undefined {
10
+ if (typeof value === "number") {
11
+ return Number.isFinite(value) ? value : undefined
12
+ }
13
+ if (value instanceof Date) {
14
+ const numericValue = value.valueOf()
15
+ return Number.isFinite(numericValue) ? numericValue : undefined
16
+ }
17
+ const parsed = Number(value)
18
+ return Number.isFinite(parsed) ? parsed : undefined
19
+ }
20
+
21
+ function isValueWithinNumberDomain(value: unknown, domain: NumberDomain): boolean {
22
+ const numericValue = toFiniteNumber(value)
23
+ const lowerBound = domain[0]
24
+ const upperBound = domain[1]
25
+
26
+ if (numericValue === undefined) {
27
+ return false
28
+ }
29
+
30
+ const min = Math.min(lowerBound, upperBound)
31
+ const max = Math.max(lowerBound, upperBound)
32
+ return numericValue >= min && numericValue <= max
33
+ }
34
+
35
+ function isValueWithinDomain(
36
+ entry: unknown,
37
+ axisDataKey: DataKey<unknown> | undefined,
38
+ domain: NumberDomain | CategoricalDomain | undefined,
39
+ ): boolean {
40
+ if (domain == null || axisDataKey == null) {
41
+ return true
42
+ }
43
+
44
+ const value = getValueByDataKey(entry, axisDataKey)
45
+ if (value == null) {
46
+ return true
47
+ }
48
+
49
+ if (!isWellFormedNumberDomain(domain)) {
50
+ return true
51
+ }
52
+
53
+ return isValueWithinNumberDomain(value, domain)
54
+ }
55
+
56
+ export const combineActiveTooltipIndex = (
57
+ tooltipInteraction: TooltipInteractionState | undefined,
58
+ chartData: ChartData,
59
+ axisDataKey?: DataKey<unknown>,
60
+ domain?: NumberDomain | CategoricalDomain,
61
+ ): TooltipIndex | null => {
62
+ const desiredIndex: TooltipIndex | undefined = tooltipInteraction?.index
63
+ if (desiredIndex == null) {
64
+ return null
65
+ }
66
+
67
+ const indexAsNumber = Number(desiredIndex)
68
+ if (!isWellBehavedNumber(indexAsNumber)) {
69
+ return desiredIndex
70
+ }
71
+
72
+ /*
73
+ * Zero is a trivial limit for single-dimensional charts like Line and Area,
74
+ * but this also needs a support for multidimensional charts like Sankey and Treemap! TODO
75
+ */
76
+ const lowerLimit = 0
77
+ let upperLimit: number = +Infinity
78
+
79
+ if (chartData.length > 0) {
80
+ upperLimit = chartData.length - 1
81
+ }
82
+
83
+ const clampedIndex = Math.max(lowerLimit, Math.min(indexAsNumber, upperLimit))
84
+ const entry = chartData[clampedIndex]
85
+
86
+ if (entry == null) {
87
+ return String(clampedIndex)
88
+ }
89
+
90
+ if (!isValueWithinDomain(entry, axisDataKey, domain)) {
91
+ return null
92
+ }
93
+
94
+ return String(clampedIndex)
95
+ }
@@ -0,0 +1,122 @@
1
+ /* eslint-disable import/no-cycle */
2
+ import { getPercentValue, isNullish } from "../../../util/DataUtils"
3
+ import { BarWithPosition, SizeList } from "../barSelectors"
4
+ import { isWellBehavedNumber } from "../../../util/isWellBehavedNumber"
5
+ import { BarPositionPosition } from "../../../util/ChartUtils"
6
+ import { BarCategory } from "./combineBarSizeList"
7
+
8
+ function getBarPositions(
9
+ barGap: string | number,
10
+ barCategoryGap: string | number,
11
+ bandSize: number,
12
+ sizeList: SizeList,
13
+ maxBarSize: number | undefined,
14
+ ): ReadonlyArray<BarWithPosition> | undefined {
15
+ const len = sizeList.length
16
+ if (len < 1) {
17
+ return undefined
18
+ }
19
+
20
+ let realBarGap = getPercentValue(barGap, bandSize, 0, true)
21
+
22
+ let result: ReadonlyArray<BarWithPosition>
23
+ const initialValue: ReadonlyArray<BarWithPosition> = []
24
+
25
+ // whether is barSize set by user
26
+ // Okay but why does it check only for the first element? What if the first element is set but others are not?
27
+ if (isWellBehavedNumber(sizeList[0]?.barSize)) {
28
+ let useFull = false
29
+ let fullBarSize: number = bandSize / len
30
+ let sum = sizeList.reduce((res, entry) => res + (entry.barSize || 0), 0)
31
+ sum += (len - 1) * realBarGap
32
+
33
+ if (sum >= bandSize) {
34
+ sum -= (len - 1) * realBarGap
35
+ realBarGap = 0
36
+ }
37
+ if (sum >= bandSize && fullBarSize > 0) {
38
+ useFull = true
39
+ fullBarSize *= 0.9
40
+ sum = len * fullBarSize
41
+ }
42
+
43
+ const offset = Math.round((bandSize - sum) / 2)
44
+ let prev: BarPositionPosition = { offset: offset - realBarGap, size: 0 }
45
+
46
+ result = sizeList.reduce(
47
+ (res: ReadonlyArray<BarWithPosition>, entry: BarCategory): ReadonlyArray<BarWithPosition> => {
48
+ const newPosition: BarWithPosition = {
49
+ stackId: entry.stackId,
50
+ dataKeys: entry.dataKeys,
51
+ position: {
52
+ offset: prev.offset + prev.size + realBarGap,
53
+ size: useFull ? fullBarSize : (entry.barSize ?? 0),
54
+ },
55
+ }
56
+ const newRes: Array<BarWithPosition> = [...res, newPosition]
57
+
58
+ prev = newPosition.position
59
+
60
+ return newRes
61
+ },
62
+ initialValue,
63
+ )
64
+ } else {
65
+ const offset = getPercentValue(barCategoryGap, bandSize, 0, true)
66
+
67
+ if (bandSize - 2 * offset - (len - 1) * realBarGap <= 0) {
68
+ realBarGap = 0
69
+ }
70
+
71
+ let originalSize = (bandSize - 2 * offset - (len - 1) * realBarGap) / len
72
+ if (originalSize > 1) {
73
+ originalSize = Math.round(originalSize)
74
+ }
75
+ const size = isWellBehavedNumber(maxBarSize) ? Math.min(originalSize, maxBarSize) : originalSize
76
+ result = sizeList.reduce(
77
+ (res: ReadonlyArray<BarWithPosition>, entry: BarCategory, i): ReadonlyArray<BarWithPosition> => [
78
+ ...res,
79
+ {
80
+ stackId: entry.stackId,
81
+ dataKeys: entry.dataKeys,
82
+ position: {
83
+ offset: offset + (len * (originalSize - size)) / 2 + (size + realBarGap) * i,
84
+ size,
85
+ },
86
+ },
87
+ ],
88
+ initialValue,
89
+ )
90
+ }
91
+
92
+ return result
93
+ }
94
+
95
+ export const combineAllBarPositions = (
96
+ sizeList: SizeList,
97
+ globalMaxBarSize: number | undefined,
98
+ barGap: string | number,
99
+ barCategoryGap: string | number,
100
+ barBandSize: number,
101
+ bandSize: number | undefined,
102
+ childMaxBarSize: number | undefined,
103
+ ): ReadonlyArray<BarWithPosition> | undefined => {
104
+ const maxBarSize: number | undefined = isNullish(childMaxBarSize) ? globalMaxBarSize : childMaxBarSize
105
+
106
+ let allBarPositions: ReadonlyArray<BarWithPosition> | undefined = getBarPositions(
107
+ barGap,
108
+ barCategoryGap,
109
+ barBandSize !== bandSize ? barBandSize : bandSize,
110
+ sizeList,
111
+ maxBarSize,
112
+ )
113
+
114
+ if (barBandSize !== bandSize && allBarPositions != null) {
115
+ allBarPositions = allBarPositions.map(pos => ({
116
+ ...pos,
117
+ position: { ...pos.position, offset: pos.position.offset - barBandSize / 2 },
118
+ }))
119
+ }
120
+
121
+ return allBarPositions
122
+ }
@@ -0,0 +1,16 @@
1
+ /* eslint-disable import/no-cycle */
2
+ import { BaseCartesianAxis } from "../../cartesianAxisSlice"
3
+ import { AxisRange } from "../axisSelectors"
4
+
5
+ export const combineAxisRangeWithReverse = (
6
+ axisSettings: BaseCartesianAxis | undefined,
7
+ axisRange: AxisRange | undefined,
8
+ ): AxisRange | undefined => {
9
+ if (!axisSettings || !axisRange) {
10
+ return undefined
11
+ }
12
+ if (axisSettings?.reversed) {
13
+ return [axisRange[1], axisRange[0]]
14
+ }
15
+ return axisRange
16
+ }
@@ -0,0 +1,23 @@
1
+ /* eslint-disable import/no-cycle */
2
+ import { MaybeStackedGraphicalItem } from "../../types/StackedGraphicalItem"
3
+ import { BarPositionPosition } from "../../../util/ChartUtils"
4
+ import { BarWithPosition } from "../barSelectors"
5
+
6
+ export const combineBarPosition = (
7
+ allBarPositions: ReadonlyArray<BarWithPosition> | undefined,
8
+ barSettings: MaybeStackedGraphicalItem | undefined,
9
+ ): BarPositionPosition | undefined => {
10
+ if (allBarPositions == null || barSettings == null) {
11
+ return undefined
12
+ }
13
+ const position = allBarPositions.find(
14
+ (p: BarWithPosition) =>
15
+ p.stackId === barSettings.stackId &&
16
+ barSettings.dataKey != null &&
17
+ p.dataKeys.includes(barSettings.dataKey),
18
+ )
19
+ if (position == null) {
20
+ return undefined
21
+ }
22
+ return position.position
23
+ }
@@ -0,0 +1,80 @@
1
+ /* eslint-disable import/no-cycle */
2
+ import {
3
+ DefinitelyStackedGraphicalItem,
4
+ isStacked,
5
+ MaybeStackedGraphicalItem,
6
+ } from "../../types/StackedGraphicalItem"
7
+ import { StackId } from "../../../util/ChartUtils"
8
+ import { SizeList } from "../barSelectors"
9
+ import { getPercentValue, isNullish } from "../../../util/DataUtils"
10
+ import { DataKey } from "../../../util/types"
11
+
12
+ const getBarSize = (
13
+ globalSize: string | number | undefined,
14
+ totalSize: number | undefined,
15
+ selfSize: number | string | undefined,
16
+ ): number | undefined => {
17
+ const barSize: string | number | undefined = selfSize ?? globalSize
18
+
19
+ if (isNullish(barSize)) {
20
+ return undefined
21
+ }
22
+ return getPercentValue(barSize, totalSize, 0)
23
+ }
24
+
25
+ export const combineBarSizeList = (
26
+ allBars: ReadonlyArray<MaybeStackedGraphicalItem>,
27
+ globalSize: string | number | undefined,
28
+ totalSize: number | undefined,
29
+ ): SizeList => {
30
+ const initialValue: Record<StackId, Array<DefinitelyStackedGraphicalItem>> = {}
31
+
32
+ const stackedBars: ReadonlyArray<DefinitelyStackedGraphicalItem> = allBars.filter(isStacked)
33
+ const unstackedBars = allBars.filter((b) => b.stackId == null)
34
+
35
+ const groupByStack: Record<StackId, Array<DefinitelyStackedGraphicalItem>> = stackedBars.reduce(
36
+ (acc, bar) => {
37
+ let s = acc[bar.stackId]
38
+ if (s == null) {
39
+ s = []
40
+ }
41
+ s.push(bar)
42
+ acc[bar.stackId] = s
43
+ return acc
44
+ },
45
+ initialValue,
46
+ )
47
+
48
+ const stackedSizeList: SizeList = Object.entries(groupByStack).map(
49
+ ([stackId, bars]): BarCategory => {
50
+ const dataKeys = bars.map((b) => b.dataKey)
51
+ const barSize: number | undefined = getBarSize(globalSize, totalSize, bars[0]?.barSize)
52
+ return { barSize, dataKeys, stackId }
53
+ },
54
+ )
55
+
56
+ const unstackedSizeList: SizeList = unstackedBars.map((b): BarCategory => {
57
+ const dataKeys = [b.dataKey].filter((dk) => dk != null)
58
+ const barSize: number | undefined = getBarSize(globalSize, totalSize, b.barSize)
59
+ return { barSize, dataKeys, stackId: undefined }
60
+ })
61
+
62
+ return [...stackedSizeList, ...unstackedSizeList]
63
+ }
64
+
65
+ export type BarCategory = {
66
+ stackId: StackId | undefined
67
+ /**
68
+ * List of dataKeys of items stacked at this position.
69
+ * All of these Bars are either sharing the same stackId,
70
+ * or this is an array with one Bar because it has no stackId defined.
71
+ *
72
+ * This structure limits us to having one dataKey only once per stack which I think is reasonable.
73
+ * People who want to have the same data twice can duplicate their data to have two distinct dataKeys.
74
+ */
75
+ dataKeys: ReadonlyArray<DataKey<unknown>>
76
+ /**
77
+ * Width (in horizontal chart) or height (in vertical chart) of this stack of items
78
+ */
79
+ barSize: number | undefined
80
+ }
@@ -0,0 +1,48 @@
1
+ /* eslint-disable import/no-cycle */
2
+ import { CategoricalDomain, NumberDomain } from "../../../util/types"
3
+ import { isWellFormedNumberDomain } from "../../../util/isDomainSpecifiedByUser"
4
+ import { isWellBehavedNumber } from "../../../util/isWellBehavedNumber"
5
+
6
+ /**
7
+ * This function validates and transforms the axis domain so that it is safe to use in the provided scale.
8
+ */
9
+ export const combineCheckedDomain = (
10
+ realScaleType: string | undefined,
11
+ axisDomain: NumberDomain | CategoricalDomain | undefined,
12
+ ): NumberDomain | CategoricalDomain | undefined => {
13
+ if (axisDomain == null) {
14
+ return undefined
15
+ }
16
+ switch (realScaleType) {
17
+ case "linear": {
18
+ /*
19
+ * linear scale only reads the first two numbers in the domain, and ignores everything else.
20
+ * So if it happens that someone somehow gave us a bigger domain,
21
+ * let's pick the min and max from it.
22
+ */
23
+ if (!isWellFormedNumberDomain(axisDomain)) {
24
+ let min: number | undefined
25
+ let max: number | undefined
26
+ for (let i = 0; i < axisDomain.length; i++) {
27
+ const value = axisDomain[i]
28
+ if (!isWellBehavedNumber(value)) {
29
+ continue
30
+ }
31
+ if (min === undefined || value < min) {
32
+ min = value
33
+ }
34
+ if (max === undefined || value > max) {
35
+ max = value
36
+ }
37
+ }
38
+ if (min !== undefined && max !== undefined) {
39
+ return [min, max]
40
+ }
41
+ return undefined
42
+ }
43
+ return axisDomain
44
+ }
45
+ default:
46
+ return axisDomain
47
+ }
48
+ }
@@ -0,0 +1,111 @@
1
+ /* eslint-disable import/no-cycle */
2
+ import * as d3Scales from "victory-vendor/d3-scale"
3
+ import { BaseCartesianAxis } from "../../cartesianAxisSlice"
4
+ import {
5
+ CategoricalDomain,
6
+ CategoricalDomainItem,
7
+ D3ScaleType,
8
+ NumberDomain,
9
+ } from "../../../util/types"
10
+ import { CustomScaleDefinition } from "../../../util/scale/CustomScaleDefinition"
11
+ import { AxisRange } from "../axisSelectors"
12
+ import { upperFirst } from "../../../util/DataUtils"
13
+
14
+ function lookupScale<Domain extends CategoricalDomainItem>(
15
+ key: string,
16
+ ): (() => CustomScaleDefinition<Domain>) | undefined {
17
+ if (key in d3Scales) {
18
+ const val: unknown = (d3Scales as Record<string, unknown>)[key]
19
+ if (typeof val === "function") {
20
+ return val as () => CustomScaleDefinition<Domain>
21
+ }
22
+ }
23
+ return undefined
24
+ }
25
+
26
+ function getD3ScaleFromType<Domain extends CategoricalDomainItem = CategoricalDomainItem>(
27
+ realScaleType: D3ScaleType,
28
+ ): CustomScaleDefinition<Domain> | undefined {
29
+ const direct = lookupScale<Domain>(realScaleType)
30
+ if (direct != null) {
31
+ return direct()
32
+ }
33
+ const prefixed = lookupScale<Domain>(`scale${upperFirst(realScaleType)}`)
34
+ if (prefixed != null) {
35
+ return prefixed()
36
+ }
37
+ return undefined
38
+ }
39
+
40
+ /**
41
+ * Converts external scale definition into internal RechartsScale definition.
42
+ * @param scale custom function scale - if you have the `string` from outside, use `combineRealScaleType` first which will validate it and return D3ScaleType or undefined
43
+ * @param axisDomain
44
+ * @param axisRange
45
+ */
46
+ export function combineConfiguredScaleInternal(
47
+ scale:
48
+ | CustomScaleDefinition
49
+ | CustomScaleDefinition<string>
50
+ | CustomScaleDefinition<number>
51
+ | CustomScaleDefinition<Date>,
52
+ axisDomain: ReadonlyArray<CategoricalDomainItem>,
53
+ axisRange: AxisRange,
54
+ ): CustomScaleDefinition
55
+ export function combineConfiguredScaleInternal(
56
+ scale: D3ScaleType,
57
+ axisDomain: ReadonlyArray<CategoricalDomainItem>,
58
+ axisRange: AxisRange,
59
+ ): CustomScaleDefinition
60
+ export function combineConfiguredScaleInternal(
61
+ scale: D3ScaleType | undefined,
62
+ axisDomain: ReadonlyArray<CategoricalDomainItem>,
63
+ axisRange: AxisRange,
64
+ ): CustomScaleDefinition | undefined
65
+ export function combineConfiguredScaleInternal(
66
+ scale: undefined,
67
+ axisDomain: ReadonlyArray<CategoricalDomainItem>,
68
+ axisRange: AxisRange,
69
+ ): undefined
70
+ export function combineConfiguredScaleInternal<
71
+ Domain extends CategoricalDomainItem = CategoricalDomainItem,
72
+ >(
73
+ scale: D3ScaleType | CustomScaleDefinition<Domain> | undefined,
74
+ axisDomain: ReadonlyArray<Domain>,
75
+ axisRange: AxisRange,
76
+ ): CustomScaleDefinition<Domain> | undefined
77
+ export function combineConfiguredScaleInternal<
78
+ Domain extends CategoricalDomainItem = CategoricalDomainItem,
79
+ >(
80
+ scale: D3ScaleType | CustomScaleDefinition<Domain> | undefined,
81
+ axisDomain: ReadonlyArray<Domain>,
82
+ axisRange: AxisRange,
83
+ ): CustomScaleDefinition<Domain> | undefined {
84
+ if (typeof scale === "function") {
85
+ return scale.copy().domain(axisDomain).range(axisRange)
86
+ }
87
+ if (scale == null) {
88
+ return undefined
89
+ }
90
+ const d3ScaleFunction: CustomScaleDefinition<Domain> | undefined = getD3ScaleFromType(scale)
91
+ if (d3ScaleFunction == null) {
92
+ return undefined
93
+ }
94
+ d3ScaleFunction.domain(axisDomain).range(axisRange)
95
+ return d3ScaleFunction
96
+ }
97
+
98
+ export function combineConfiguredScale(
99
+ axis: BaseCartesianAxis,
100
+ realScaleType: D3ScaleType | undefined,
101
+ axisDomain: NumberDomain | CategoricalDomain | undefined,
102
+ axisRange: AxisRange | undefined,
103
+ ): CustomScaleDefinition | undefined {
104
+ if (axisDomain == null || axisRange == null) {
105
+ return undefined
106
+ }
107
+ if (typeof axis.scale === "function") {
108
+ return combineConfiguredScaleInternal(axis.scale, axisDomain, axisRange)
109
+ }
110
+ return combineConfiguredScaleInternal(realScaleType, axisDomain, axisRange)
111
+ }
@@ -0,0 +1,45 @@
1
+ /* eslint-disable import/no-cycle */
2
+ import { ChartOffsetInternal, Coordinate, LayoutType, TickItem } from "../../../util/types"
3
+ import { TooltipIndex, TooltipPayloadConfiguration } from "../../tooltipSlice"
4
+
5
+ export const combineCoordinateForDefaultIndex = (
6
+ width: number,
7
+ height: number,
8
+ layout: LayoutType,
9
+ offset: ChartOffsetInternal,
10
+ tooltipTicks: ReadonlyArray<TickItem> | undefined,
11
+ defaultIndex: TooltipIndex | undefined,
12
+ tooltipConfigurations: ReadonlyArray<TooltipPayloadConfiguration>,
13
+ ): Coordinate | undefined => {
14
+ if (defaultIndex == null) {
15
+ return undefined
16
+ }
17
+ /*
18
+ * With defaultIndex alone, we don't have enough information to decide _which_ of the multiple tooltips to display.
19
+ * Maybe one day we could add new prop `activeGraphicalItemId` to the chart to help with that.
20
+ * Until then, we choose the first one.
21
+ */
22
+ const firstConfiguration = tooltipConfigurations[0]
23
+ const maybePosition: Coordinate | undefined = firstConfiguration?.getPosition(defaultIndex)
24
+ if (maybePosition != null) {
25
+ return maybePosition
26
+ }
27
+ const tick = tooltipTicks?.[Number(defaultIndex)]
28
+ if (!tick) {
29
+ return undefined
30
+ }
31
+ switch (layout) {
32
+ case "horizontal": {
33
+ return {
34
+ x: tick.coordinate,
35
+ y: (offset.top + height) / 2,
36
+ }
37
+ }
38
+ default: {
39
+ return {
40
+ x: (offset.left + width) / 2,
41
+ y: tick.coordinate,
42
+ }
43
+ }
44
+ }
45
+ }
@@ -0,0 +1,50 @@
1
+ /* eslint-disable import/no-cycle */
2
+ import { ChartDataState } from "../../chartDataSlice"
3
+ import { BaseCartesianAxis } from "../../cartesianAxisSlice"
4
+ import { getStackSeriesIdentifier } from "../../../util/stacks/getStackSeriesIdentifier"
5
+ import { getValueByDataKey } from "../../../util/ChartUtils"
6
+ import { StackSeriesIdentifier } from "../../../util/stacks/stackTypes"
7
+ import { DefinitelyStackedGraphicalItem } from "../../types/StackedGraphicalItem"
8
+
9
+ /**
10
+ * In a stacked chart, each graphical item has its own data. That data could be either:
11
+ * - defined on the chart root, in which case the item gets a unique dataKey
12
+ * - or defined on the item itself, in which case multiple items can share the same dataKey
13
+ *
14
+ * That means we cannot use the dataKey as a unique identifier for the item.
15
+ *
16
+ * This type represents a single data point in a stacked chart, where each key is a series identifier
17
+ * and the value is the numeric value for that series using the numerical axis dataKey.
18
+ */
19
+ export type DisplayedStackedDataPoint = Record<StackSeriesIdentifier, number>
20
+
21
+ export type DisplayedStackedData = ReadonlyArray<DisplayedStackedDataPoint>
22
+
23
+ export function combineDisplayedStackedData(
24
+ stackedGraphicalItems: ReadonlyArray<DefinitelyStackedGraphicalItem>,
25
+ { chartData = [] }: ChartDataState,
26
+ tooltipAxisSettings: BaseCartesianAxis,
27
+ ): DisplayedStackedData {
28
+ const { allowDuplicatedCategory, dataKey: tooltipDataKey } = tooltipAxisSettings
29
+
30
+ const knownItemsByDataKey = new Map<string | number, DisplayedStackedDataPoint>()
31
+
32
+ stackedGraphicalItems.forEach((item) => {
33
+ const resolvedData = item.data ?? chartData
34
+ if (resolvedData == null || resolvedData.length === 0) {
35
+ return
36
+ }
37
+ const stackIdentifier = getStackSeriesIdentifier(item)
38
+ resolvedData.forEach((entry, index) => {
39
+ const tooltipValue =
40
+ tooltipDataKey == null || allowDuplicatedCategory
41
+ ? index
42
+ : String(getValueByDataKey(entry, tooltipDataKey, null))
43
+ const numericValue = getValueByDataKey(entry, item.dataKey, 0)
44
+ const curr = knownItemsByDataKey.get(tooltipValue) ?? {}
45
+ Object.assign(curr, { [stackIdentifier]: numericValue })
46
+ knownItemsByDataKey.set(tooltipValue, curr as DisplayedStackedDataPoint)
47
+ })
48
+ })
49
+ return Array.from(knownItemsByDataKey.values())
50
+ }
@@ -0,0 +1,16 @@
1
+ /* eslint-disable import/no-cycle */
2
+ import { InverseScaleFunction } from "../../../hooks"
3
+ import { createCategoricalInverse } from "../../../util/scale/createCategoricalInverse"
4
+ import { CustomScaleDefinition } from "../../../util/scale/CustomScaleDefinition"
5
+
6
+ export function combineInverseScaleFunction(
7
+ configuredScale: CustomScaleDefinition | undefined,
8
+ ): InverseScaleFunction | undefined {
9
+ if (configuredScale == null) {
10
+ return undefined
11
+ }
12
+ if ("invert" in configuredScale && typeof configuredScale.invert === "function") {
13
+ return configuredScale.invert.bind(configuredScale)
14
+ }
15
+ return createCategoricalInverse(configuredScale, undefined)
16
+ }
@@ -0,0 +1,44 @@
1
+ /* eslint-disable import/no-cycle */
2
+ import * as d3Scales from "victory-vendor/d3-scale"
3
+ import type { RechartsScaleType } from "../../../util/types"
4
+ import { BaseCartesianAxis } from "../../cartesianAxisSlice"
5
+ import { upperFirst } from "../../../util/DataUtils"
6
+
7
+ function getD3ScaleName(name: string): string {
8
+ return `scale${upperFirst(name)}`
9
+ }
10
+
11
+ function isSupportedScaleName(name: string): name is RechartsScaleType {
12
+ return getD3ScaleName(name) in d3Scales
13
+ }
14
+
15
+ export const combineRealScaleType = (
16
+ axisConfig: BaseCartesianAxis | undefined,
17
+ hasBar: boolean,
18
+ chartType: string,
19
+ ): RechartsScaleType | undefined => {
20
+ if (axisConfig == null) {
21
+ return undefined
22
+ }
23
+ const { scale, type } = axisConfig
24
+ if (scale === "auto") {
25
+ if (
26
+ type === "category" &&
27
+ chartType &&
28
+ (chartType.indexOf("LineChart") >= 0 ||
29
+ chartType.indexOf("AreaChart") >= 0 ||
30
+ (chartType.indexOf("ComposedChart") >= 0 && !hasBar))
31
+ ) {
32
+ return "point"
33
+ }
34
+ if (type === "category") {
35
+ return "band"
36
+ }
37
+
38
+ return "linear"
39
+ }
40
+ if (typeof scale === "string") {
41
+ return isSupportedScaleName(scale) ? scale : "point"
42
+ }
43
+ return undefined
44
+ }
@@ -0,0 +1,27 @@
1
+ /* eslint-disable import/no-cycle */
2
+ import { AllStackGroups, StackGroup, StackSeries } from "../../../util/stacks/stackTypes"
3
+ import { MaybeStackedGraphicalItem } from "../../types/StackedGraphicalItem"
4
+ import { getStackSeriesIdentifier } from "../../../util/stacks/getStackSeriesIdentifier"
5
+
6
+ export const combineStackedData = (
7
+ stackGroups: AllStackGroups | undefined,
8
+ barSettings: MaybeStackedGraphicalItem | undefined,
9
+ ): StackSeries | undefined => {
10
+ const stackSeriesIdentifier = getStackSeriesIdentifier(barSettings)
11
+ if (!stackGroups || stackSeriesIdentifier == null || barSettings == null) {
12
+ return undefined
13
+ }
14
+ const { stackId } = barSettings
15
+ if (stackId == null) {
16
+ return undefined
17
+ }
18
+ const stackGroup: StackGroup | undefined = stackGroups[stackId]
19
+ if (!stackGroup) {
20
+ return undefined
21
+ }
22
+ const { stackedData }: StackGroup = stackGroup
23
+ if (!stackedData) {
24
+ return undefined
25
+ }
26
+ return stackedData.find((sd) => sd.key === stackSeriesIdentifier)
27
+ }