@coinbase/cds-mobile-visualization 3.3.0 → 3.4.0-beta.10

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 (265) hide show
  1. package/CHANGELOG.md +80 -0
  2. package/dts/chart/CartesianChart.d.ts +125 -0
  3. package/dts/chart/CartesianChart.d.ts.map +1 -0
  4. package/dts/chart/ChartContextBridge.d.ts +28 -0
  5. package/dts/chart/ChartContextBridge.d.ts.map +1 -0
  6. package/dts/chart/ChartProvider.d.ts +6 -0
  7. package/dts/chart/ChartProvider.d.ts.map +1 -0
  8. package/dts/chart/Path.d.ts +91 -0
  9. package/dts/chart/Path.d.ts.map +1 -0
  10. package/dts/chart/PeriodSelector.d.ts +85 -0
  11. package/dts/chart/PeriodSelector.d.ts.map +1 -0
  12. package/dts/chart/area/Area.d.ts +77 -0
  13. package/dts/chart/area/Area.d.ts.map +1 -0
  14. package/dts/chart/area/AreaChart.d.ts +131 -0
  15. package/dts/chart/area/AreaChart.d.ts.map +1 -0
  16. package/dts/chart/area/DottedArea.d.ts +46 -0
  17. package/dts/chart/area/DottedArea.d.ts.map +1 -0
  18. package/dts/chart/area/GradientArea.d.ts +36 -0
  19. package/dts/chart/area/GradientArea.d.ts.map +1 -0
  20. package/dts/chart/area/SolidArea.d.ts +23 -0
  21. package/dts/chart/area/SolidArea.d.ts.map +1 -0
  22. package/dts/chart/area/index.d.ts +6 -0
  23. package/dts/chart/area/index.d.ts.map +1 -0
  24. package/dts/chart/axis/Axis.d.ts +194 -0
  25. package/dts/chart/axis/Axis.d.ts.map +1 -0
  26. package/dts/chart/axis/DefaultAxisTickLabel.d.ts +8 -0
  27. package/dts/chart/axis/DefaultAxisTickLabel.d.ts.map +1 -0
  28. package/dts/chart/axis/XAxis.d.ts +16 -0
  29. package/dts/chart/axis/XAxis.d.ts.map +1 -0
  30. package/dts/chart/axis/YAxis.d.ts +21 -0
  31. package/dts/chart/axis/YAxis.d.ts.map +1 -0
  32. package/dts/chart/axis/index.d.ts +5 -0
  33. package/dts/chart/axis/index.d.ts.map +1 -0
  34. package/dts/chart/bar/Bar.d.ts +92 -0
  35. package/dts/chart/bar/Bar.d.ts.map +1 -0
  36. package/dts/chart/bar/BarChart.d.ts +113 -0
  37. package/dts/chart/bar/BarChart.d.ts.map +1 -0
  38. package/dts/chart/bar/BarPlot.d.ts +30 -0
  39. package/dts/chart/bar/BarPlot.d.ts.map +1 -0
  40. package/dts/chart/bar/BarStack.d.ts +102 -0
  41. package/dts/chart/bar/BarStack.d.ts.map +1 -0
  42. package/dts/chart/bar/BarStackGroup.d.ts +36 -0
  43. package/dts/chart/bar/BarStackGroup.d.ts.map +1 -0
  44. package/dts/chart/bar/DefaultBar.d.ts +7 -0
  45. package/dts/chart/bar/DefaultBar.d.ts.map +1 -0
  46. package/dts/chart/bar/DefaultBarStack.d.ts +7 -0
  47. package/dts/chart/bar/DefaultBarStack.d.ts.map +1 -0
  48. package/dts/chart/bar/index.d.ts +8 -0
  49. package/dts/chart/bar/index.d.ts.map +1 -0
  50. package/dts/chart/gradient/Gradient.d.ts +25 -0
  51. package/dts/chart/gradient/Gradient.d.ts.map +1 -0
  52. package/dts/chart/gradient/index.d.ts +2 -0
  53. package/dts/chart/gradient/index.d.ts.map +1 -0
  54. package/dts/chart/index.d.ts +15 -0
  55. package/dts/chart/index.d.ts.map +1 -0
  56. package/dts/chart/line/DefaultReferenceLineLabel.d.ts +9 -0
  57. package/dts/chart/line/DefaultReferenceLineLabel.d.ts.map +1 -0
  58. package/dts/chart/line/DottedLine.d.ts +20 -0
  59. package/dts/chart/line/DottedLine.d.ts.map +1 -0
  60. package/dts/chart/line/Line.d.ts +115 -0
  61. package/dts/chart/line/Line.d.ts.map +1 -0
  62. package/dts/chart/line/LineChart.d.ts +118 -0
  63. package/dts/chart/line/LineChart.d.ts.map +1 -0
  64. package/dts/chart/line/ReferenceLine.d.ts +139 -0
  65. package/dts/chart/line/ReferenceLine.d.ts.map +1 -0
  66. package/dts/chart/line/SolidLine.d.ts +15 -0
  67. package/dts/chart/line/SolidLine.d.ts.map +1 -0
  68. package/dts/chart/line/index.d.ts +7 -0
  69. package/dts/chart/line/index.d.ts.map +1 -0
  70. package/dts/chart/point/DefaultPointLabel.d.ts +10 -0
  71. package/dts/chart/point/DefaultPointLabel.d.ts.map +1 -0
  72. package/dts/chart/point/Point.d.ts +120 -0
  73. package/dts/chart/point/Point.d.ts.map +1 -0
  74. package/dts/chart/point/index.d.ts +3 -0
  75. package/dts/chart/point/index.d.ts.map +1 -0
  76. package/dts/chart/scrubber/DefaultScrubberBeacon.d.ts +8 -0
  77. package/dts/chart/scrubber/DefaultScrubberBeacon.d.ts.map +1 -0
  78. package/dts/chart/scrubber/DefaultScrubberBeaconLabel.d.ts +12 -0
  79. package/dts/chart/scrubber/DefaultScrubberBeaconLabel.d.ts.map +1 -0
  80. package/dts/chart/scrubber/DefaultScrubberLabel.d.ts +11 -0
  81. package/dts/chart/scrubber/DefaultScrubberLabel.d.ts.map +1 -0
  82. package/dts/chart/scrubber/Scrubber.d.ts +233 -0
  83. package/dts/chart/scrubber/Scrubber.d.ts.map +1 -0
  84. package/dts/chart/scrubber/ScrubberBeaconGroup.d.ts +44 -0
  85. package/dts/chart/scrubber/ScrubberBeaconGroup.d.ts.map +1 -0
  86. package/dts/chart/scrubber/ScrubberBeaconLabelGroup.d.ts +31 -0
  87. package/dts/chart/scrubber/ScrubberBeaconLabelGroup.d.ts.map +1 -0
  88. package/dts/chart/scrubber/ScrubberProvider.d.ts +20 -0
  89. package/dts/chart/scrubber/ScrubberProvider.d.ts.map +1 -0
  90. package/dts/chart/scrubber/index.d.ts +5 -0
  91. package/dts/chart/scrubber/index.d.ts.map +1 -0
  92. package/dts/chart/text/ChartText.d.ts +164 -0
  93. package/dts/chart/text/ChartText.d.ts.map +1 -0
  94. package/dts/chart/text/ChartTextGroup.d.ts +61 -0
  95. package/dts/chart/text/ChartTextGroup.d.ts.map +1 -0
  96. package/dts/chart/text/index.d.ts +3 -0
  97. package/dts/chart/text/index.d.ts.map +1 -0
  98. package/dts/chart/utils/axis.d.ts +342 -0
  99. package/dts/chart/utils/axis.d.ts.map +1 -0
  100. package/dts/chart/utils/bar.d.ts +20 -0
  101. package/dts/chart/utils/bar.d.ts.map +1 -0
  102. package/dts/chart/utils/chart.d.ts +124 -0
  103. package/dts/chart/utils/chart.d.ts.map +1 -0
  104. package/dts/chart/utils/context.d.ts +116 -0
  105. package/dts/chart/utils/context.d.ts.map +1 -0
  106. package/dts/chart/utils/gradient.d.ts +117 -0
  107. package/dts/chart/utils/gradient.d.ts.map +1 -0
  108. package/dts/chart/utils/index.d.ts +11 -0
  109. package/dts/chart/utils/index.d.ts.map +1 -0
  110. package/dts/chart/utils/path.d.ts +160 -0
  111. package/dts/chart/utils/path.d.ts.map +1 -0
  112. package/dts/chart/utils/point.d.ts +134 -0
  113. package/dts/chart/utils/point.d.ts.map +1 -0
  114. package/dts/chart/utils/scale.d.ts +134 -0
  115. package/dts/chart/utils/scale.d.ts.map +1 -0
  116. package/dts/chart/utils/scrubber.d.ts +39 -0
  117. package/dts/chart/utils/scrubber.d.ts.map +1 -0
  118. package/dts/chart/utils/transition.d.ts +140 -0
  119. package/dts/chart/utils/transition.d.ts.map +1 -0
  120. package/dts/index.d.ts +2 -1
  121. package/dts/index.d.ts.map +1 -1
  122. package/dts/sparkline/Counter.d.ts +7 -2
  123. package/dts/sparkline/Sparkline.d.ts +67 -16
  124. package/dts/sparkline/Sparkline.d.ts.map +1 -1
  125. package/dts/sparkline/SparklineArea.d.ts +10 -4
  126. package/dts/sparkline/SparklineArea.d.ts.map +1 -1
  127. package/dts/sparkline/SparklineAreaPattern.d.ts +12 -4
  128. package/dts/sparkline/SparklineAreaPattern.d.ts.map +1 -1
  129. package/dts/sparkline/SparklineGradient.d.ts +21 -10
  130. package/dts/sparkline/SparklineGradient.d.ts.map +1 -1
  131. package/dts/sparkline/__figma__/Sparkline.figma.d.ts +1 -1
  132. package/dts/sparkline/generateSparklineWithId.d.ts +8 -2
  133. package/dts/sparkline/generateSparklineWithId.d.ts.map +1 -1
  134. package/dts/sparkline/index.d.ts +1 -1
  135. package/dts/sparkline/sparkline-interactive/SparklineAccessibleView.d.ts +8 -3
  136. package/dts/sparkline/sparkline-interactive/SparklineInteractive.d.ts +132 -110
  137. package/dts/sparkline/sparkline-interactive/SparklineInteractive.d.ts.map +1 -1
  138. package/dts/sparkline/sparkline-interactive/SparklineInteractiveAnimatedPath.d.ts +22 -9
  139. package/dts/sparkline/sparkline-interactive/SparklineInteractiveAnimatedPath.d.ts.map +1 -1
  140. package/dts/sparkline/sparkline-interactive/SparklineInteractiveHoverDate.d.ts +18 -7
  141. package/dts/sparkline/sparkline-interactive/SparklineInteractiveLineVertical.d.ts +9 -4
  142. package/dts/sparkline/sparkline-interactive/SparklineInteractiveMarkerDates.d.ts +11 -6
  143. package/dts/sparkline/sparkline-interactive/SparklineInteractiveMinMax.d.ts +7 -5
  144. package/dts/sparkline/sparkline-interactive/SparklineInteractivePanGestureHandler.d.ts +22 -10
  145. package/dts/sparkline/sparkline-interactive/SparklineInteractivePaths.d.ts +21 -7
  146. package/dts/sparkline/sparkline-interactive/SparklineInteractivePaths.d.ts.map +1 -1
  147. package/dts/sparkline/sparkline-interactive/SparklineInteractivePeriodSelector.d.ts +21 -16
  148. package/dts/sparkline/sparkline-interactive/SparklineInteractiveProvider.d.ts +29 -23
  149. package/dts/sparkline/sparkline-interactive/SparklineInteractiveTimeseriesPaths.d.ts +22 -14
  150. package/dts/sparkline/sparkline-interactive/__figma__/SparklineInteractive.figma.d.ts +1 -1
  151. package/dts/sparkline/sparkline-interactive/useInterruptiblePathAnimation.d.ts +9 -5
  152. package/dts/sparkline/sparkline-interactive/useMinMaxTransform.d.ts +11 -6
  153. package/dts/sparkline/sparkline-interactive/useOpacityAnimation.d.ts +5 -2
  154. package/dts/sparkline/sparkline-interactive/useSparklineInteractiveConstants.d.ts +17 -17
  155. package/dts/sparkline/sparkline-interactive/useSparklineInteractiveLineStyles.d.ts +16 -13
  156. package/dts/sparkline/sparkline-interactive-header/SparklineInteractiveHeader.d.ts +106 -98
  157. package/dts/sparkline/sparkline-interactive-header/__figma__/SparklineInteractiveHeader.figma.d.ts +1 -1
  158. package/dts/sparkline/sparkline-interactive-header/useSparklineInteractiveHeaderStyles.d.ts +22 -19
  159. package/esm/chart/CartesianChart.js +335 -0
  160. package/esm/chart/ChartContextBridge.js +148 -0
  161. package/esm/chart/ChartProvider.js +10 -0
  162. package/esm/chart/Path.js +218 -0
  163. package/esm/chart/PeriodSelector.js +136 -0
  164. package/esm/chart/__stories__/CartesianChart.stories.js +723 -0
  165. package/esm/chart/__stories__/Chart.stories.js +77 -0
  166. package/esm/chart/__stories__/PeriodSelector.stories.js +322 -0
  167. package/esm/chart/area/Area.js +75 -0
  168. package/esm/chart/area/AreaChart.js +151 -0
  169. package/esm/chart/area/DottedArea.js +80 -0
  170. package/esm/chart/area/GradientArea.js +54 -0
  171. package/esm/chart/area/SolidArea.js +38 -0
  172. package/esm/chart/area/__stories__/AreaChart.stories.js +100 -0
  173. package/esm/chart/area/index.js +7 -0
  174. package/esm/chart/axis/Axis.js +45 -0
  175. package/esm/chart/axis/DefaultAxisTickLabel.js +11 -0
  176. package/esm/chart/axis/XAxis.js +188 -0
  177. package/esm/chart/axis/YAxis.js +177 -0
  178. package/esm/chart/axis/__stories__/Axis.stories.js +276 -0
  179. package/esm/chart/axis/index.js +6 -0
  180. package/esm/chart/bar/Bar.js +69 -0
  181. package/esm/chart/bar/BarChart.js +125 -0
  182. package/esm/chart/bar/BarPlot.js +102 -0
  183. package/esm/chart/bar/BarStack.js +551 -0
  184. package/esm/chart/bar/BarStackGroup.js +79 -0
  185. package/esm/chart/bar/DefaultBar.js +56 -0
  186. package/esm/chart/bar/DefaultBarStack.js +47 -0
  187. package/esm/chart/bar/__stories__/BarChart.stories.js +668 -0
  188. package/esm/chart/bar/index.js +9 -0
  189. package/esm/chart/gradient/Gradient.js +53 -0
  190. package/esm/chart/gradient/index.js +1 -0
  191. package/esm/chart/index.js +16 -0
  192. package/esm/chart/line/DefaultReferenceLineLabel.js +66 -0
  193. package/esm/chart/line/DottedLine.js +50 -0
  194. package/esm/chart/line/Line.js +178 -0
  195. package/esm/chart/line/LineChart.js +121 -0
  196. package/esm/chart/line/ReferenceLine.js +132 -0
  197. package/esm/chart/line/SolidLine.js +46 -0
  198. package/esm/chart/line/__stories__/LineChart.stories.js +2372 -0
  199. package/esm/chart/line/__stories__/ReferenceLine.stories.js +132 -0
  200. package/esm/chart/line/index.js +8 -0
  201. package/esm/chart/point/DefaultPointLabel.js +39 -0
  202. package/esm/chart/point/Point.js +188 -0
  203. package/esm/chart/point/index.js +2 -0
  204. package/esm/chart/scrubber/DefaultScrubberBeacon.js +179 -0
  205. package/esm/chart/scrubber/DefaultScrubberBeaconLabel.js +43 -0
  206. package/esm/chart/scrubber/DefaultScrubberLabel.js +28 -0
  207. package/esm/chart/scrubber/Scrubber.js +166 -0
  208. package/esm/chart/scrubber/ScrubberBeaconGroup.js +161 -0
  209. package/esm/chart/scrubber/ScrubberBeaconLabelGroup.js +185 -0
  210. package/esm/chart/scrubber/ScrubberProvider.js +135 -0
  211. package/esm/chart/scrubber/index.js +4 -0
  212. package/esm/chart/text/ChartText.js +305 -0
  213. package/esm/chart/text/ChartTextGroup.js +211 -0
  214. package/esm/chart/text/index.js +4 -0
  215. package/esm/chart/utils/axis.js +592 -0
  216. package/esm/chart/utils/bar.js +24 -0
  217. package/esm/chart/utils/chart.js +270 -0
  218. package/esm/chart/utils/context.js +15 -0
  219. package/esm/chart/utils/gradient.js +305 -0
  220. package/esm/chart/utils/index.js +12 -0
  221. package/esm/chart/utils/path.js +274 -0
  222. package/esm/chart/utils/point.js +229 -0
  223. package/esm/chart/utils/scale.js +277 -0
  224. package/esm/chart/utils/scrubber.js +139 -0
  225. package/esm/chart/utils/transition.js +185 -0
  226. package/esm/index.js +4 -1
  227. package/esm/sparkline/Sparkline.js +129 -16
  228. package/esm/sparkline/SparklineArea.js +7 -2
  229. package/esm/sparkline/SparklineAreaPattern.js +4 -2
  230. package/esm/sparkline/SparklineGradient.js +4 -0
  231. package/esm/sparkline/__stories__/Sparkline.stories.js +11 -7
  232. package/esm/sparkline/__stories__/SparklineGradient.stories.js +7 -4
  233. package/esm/sparkline/generateSparklineWithId.js +3 -2
  234. package/esm/sparkline/sparkline-interactive/SparklineInteractive.js +5 -1
  235. package/esm/sparkline/sparkline-interactive/SparklineInteractiveAnimatedPath.js +5 -2
  236. package/esm/sparkline/sparkline-interactive/SparklineInteractivePaths.js +4 -0
  237. package/esm/sparkline/sparkline-interactive/__stories__/SparklineInteractive.stories.js +76 -24
  238. package/esm/sparkline/sparkline-interactive-header/__stories__/SparklineInteractiveHeader.stories.js +17 -9
  239. package/package.json +17 -11
  240. package/dts/sparkline/__stories__/Sparkline.stories.d.ts +0 -3
  241. package/dts/sparkline/__stories__/Sparkline.stories.d.ts.map +0 -1
  242. package/dts/sparkline/__stories__/SparklineGradient.stories.d.ts +0 -3
  243. package/dts/sparkline/__stories__/SparklineGradient.stories.d.ts.map +0 -1
  244. package/dts/sparkline/sparkline-interactive/__stories__/SparklineInteractive.stories.d.ts +0 -3
  245. package/dts/sparkline/sparkline-interactive/__stories__/SparklineInteractive.stories.d.ts.map +0 -1
  246. package/dts/sparkline/sparkline-interactive/__tests__/SparklineInteractive.test.d.ts +0 -2
  247. package/dts/sparkline/sparkline-interactive/__tests__/SparklineInteractive.test.d.ts.map +0 -1
  248. package/dts/sparkline/sparkline-interactive/__tests__/SparklineInteractiveHoverDate.test.d.ts +0 -2
  249. package/dts/sparkline/sparkline-interactive/__tests__/SparklineInteractiveHoverDate.test.d.ts.map +0 -1
  250. package/dts/sparkline/sparkline-interactive/__tests__/SparklineInteractivePanGestureHandler.test.d.ts +0 -2
  251. package/dts/sparkline/sparkline-interactive/__tests__/SparklineInteractivePanGestureHandler.test.d.ts.map +0 -1
  252. package/dts/sparkline/sparkline-interactive/__tests__/SparklineInteractivePeriodSelector.test.d.ts +0 -2
  253. package/dts/sparkline/sparkline-interactive/__tests__/SparklineInteractivePeriodSelector.test.d.ts.map +0 -1
  254. package/dts/sparkline/sparkline-interactive/__tests__/SparklineInteractiveTimeseriesPaths.test.d.ts +0 -2
  255. package/dts/sparkline/sparkline-interactive/__tests__/SparklineInteractiveTimeseriesPaths.test.d.ts.map +0 -1
  256. package/dts/sparkline/sparkline-interactive/__tests__/useMinMaxTransform.test.d.ts +0 -2
  257. package/dts/sparkline/sparkline-interactive/__tests__/useMinMaxTransform.test.d.ts.map +0 -1
  258. package/dts/sparkline/sparkline-interactive/useInterruptiblePathAnimation.test.disable.d.ts +0 -2
  259. package/dts/sparkline/sparkline-interactive/useInterruptiblePathAnimation.test.disable.d.ts.map +0 -1
  260. package/dts/sparkline/sparkline-interactive-header/__stories__/SparklineInteractiveHeader.stories.d.ts +0 -4
  261. package/dts/sparkline/sparkline-interactive-header/__stories__/SparklineInteractiveHeader.stories.d.ts.map +0 -1
  262. package/dts/sparkline/sparkline-interactive-header/__tests__/SparklineInteractiveHeader.test.d.ts +0 -2
  263. package/dts/sparkline/sparkline-interactive-header/__tests__/SparklineInteractiveHeader.test.d.ts.map +0 -1
  264. package/dts/sparkline/sparkline-interactive-header/__tests__/useSparklineInteractiveHeaderStyles.test.d.ts +0 -2
  265. package/dts/sparkline/sparkline-interactive-header/__tests__/useSparklineInteractiveHeaderStyles.test.d.ts.map +0 -1
@@ -0,0 +1,102 @@
1
+ import { memo, useId, useMemo } from 'react';
2
+ import { Group, Skia } from '@shopify/react-native-skia';
3
+ import { useCartesianChartContext } from '../ChartProvider';
4
+ import { defaultAxisId } from '../utils';
5
+ import { BarStackGroup } from './BarStackGroup';
6
+ import { jsx as _jsx } from "react/jsx-runtime";
7
+ /**
8
+ * BarPlot component that handles multiple series with proper stacking coordination.
9
+ * Groups series by stack ID + y-axis ID combination and renders BarStackGroup for each group.
10
+ * This allows series with different y-axes to be rendered side by side while preventing
11
+ * cross-axis stacking (e.g., comparing $1M vs $1B companies on different scales).
12
+ */
13
+ export const BarPlot = /*#__PURE__*/memo(_ref => {
14
+ let {
15
+ seriesIds,
16
+ barPadding = 0.1,
17
+ BarComponent: defaultBarComponent,
18
+ fillOpacity: defaultFillOpacity,
19
+ stroke: defaultStroke,
20
+ strokeWidth: defaultStrokeWidth,
21
+ borderRadius: defaultBorderRadius,
22
+ roundBaseline,
23
+ BarStackComponent,
24
+ stackGap,
25
+ barMinSize,
26
+ stackMinSize,
27
+ transition
28
+ } = _ref;
29
+ const {
30
+ series: allSeries,
31
+ drawingArea
32
+ } = useCartesianChartContext();
33
+ const clipPathId = useId();
34
+ const targetSeries = useMemo(() => {
35
+ // Then filter by seriesIds if provided
36
+ if (seriesIds !== undefined) {
37
+ return allSeries.filter(s => seriesIds.includes(s.id));
38
+ }
39
+ return allSeries;
40
+ }, [allSeries, seriesIds]);
41
+ const stackGroups = useMemo(() => {
42
+ const groups = new Map();
43
+
44
+ // Group series into stacks based on stackId + yAxisId combination
45
+ targetSeries.forEach(series => {
46
+ var _series$yAxisId;
47
+ const yAxisId = (_series$yAxisId = series.yAxisId) != null ? _series$yAxisId : defaultAxisId;
48
+ const stackId = series.stackId || "individual-" + series.id;
49
+ const stackKey = stackId + ":" + yAxisId;
50
+ if (!groups.has(stackKey)) {
51
+ groups.set(stackKey, {
52
+ stackId: stackKey,
53
+ series: [],
54
+ yAxisId: series.yAxisId
55
+ });
56
+ }
57
+ const group = groups.get(stackKey);
58
+ group.series.push(series);
59
+ });
60
+ return Array.from(groups.values());
61
+ }, [targetSeries]);
62
+
63
+ // Create clip path for the entire chart area (shared by all bars)
64
+ const clipPath = useMemo(() => {
65
+ if (!drawingArea) return null;
66
+ const clip = Skia.Path.Make();
67
+ clip.addRect({
68
+ x: drawingArea.x,
69
+ y: drawingArea.y,
70
+ width: drawingArea.width,
71
+ height: drawingArea.height
72
+ });
73
+ return clip;
74
+ }, [drawingArea]);
75
+ if (!clipPath) {
76
+ return null;
77
+ }
78
+
79
+ // Note: Clipping is now handled here at the BarPlot level (one clip path for all bars!)
80
+ // This is much more efficient than creating a clip path for each individual bar
81
+ return /*#__PURE__*/_jsx(Group, {
82
+ clip: clipPath,
83
+ children: stackGroups.map((group, stackIndex) => /*#__PURE__*/_jsx(BarStackGroup, {
84
+ BarComponent: defaultBarComponent,
85
+ BarStackComponent: BarStackComponent,
86
+ barMinSize: barMinSize,
87
+ barPadding: barPadding,
88
+ borderRadius: defaultBorderRadius,
89
+ fillOpacity: defaultFillOpacity,
90
+ roundBaseline: roundBaseline,
91
+ series: group.series,
92
+ stackGap: stackGap,
93
+ stackIndex: stackIndex,
94
+ stackMinSize: stackMinSize,
95
+ stroke: defaultStroke,
96
+ strokeWidth: defaultStrokeWidth,
97
+ totalStacks: stackGroups.length,
98
+ transition: transition,
99
+ yAxisId: group.yAxisId
100
+ }, group.stackId))
101
+ });
102
+ });
@@ -0,0 +1,551 @@
1
+ function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
2
+ import React, { memo, useMemo } from 'react';
3
+ import { useTheme } from '@coinbase/cds-mobile/hooks/useTheme';
4
+ import { useCartesianChartContext } from '../ChartProvider';
5
+ import { evaluateGradientAtValue, getGradientStops } from '../utils/gradient';
6
+ import { convertToSerializableScale } from '../utils/scale';
7
+ import { Bar } from './Bar';
8
+ import { DefaultBarStack } from './DefaultBarStack';
9
+ import { jsx as _jsx } from "react/jsx-runtime";
10
+ const EPSILON = 1e-4;
11
+ /**
12
+ * BarStack component that renders a single stack of bars at a specific category index.
13
+ * Handles the stacking logic for bars within a single category.
14
+ */
15
+ export const BarStack = /*#__PURE__*/memo(_ref => {
16
+ let {
17
+ series,
18
+ categoryIndex,
19
+ x,
20
+ width,
21
+ yScale,
22
+ rect,
23
+ BarComponent: defaultBarComponent,
24
+ fillOpacity: defaultFillOpacity,
25
+ stroke: defaultStroke,
26
+ strokeWidth: defaultStrokeWidth,
27
+ borderRadius = 4,
28
+ BarStackComponent = DefaultBarStack,
29
+ stackGap,
30
+ barMinSize,
31
+ stackMinSize,
32
+ roundBaseline,
33
+ transition
34
+ } = _ref;
35
+ const theme = useTheme();
36
+ const {
37
+ getSeriesData,
38
+ getXAxis,
39
+ getXScale
40
+ } = useCartesianChartContext();
41
+ const xAxis = getXAxis();
42
+ const xScale = getXScale();
43
+ const baseline = useMemo(() => {
44
+ var _yScale;
45
+ const domain = yScale.domain();
46
+ const [domainMin, domainMax] = domain;
47
+ const baselineValue = domainMin >= 0 ? domainMin : domainMax <= 0 ? domainMax : 0;
48
+ const baseline = (_yScale = yScale(baselineValue)) != null ? _yScale : rect.y + rect.height;
49
+ return Math.max(rect.y, Math.min(baseline, rect.y + rect.height));
50
+ }, [rect.height, rect.y, yScale]);
51
+ const seriesGradients = useMemo(() => {
52
+ return series.map(s => {
53
+ if (!s.gradient || !xScale || !yScale) return;
54
+ const gradientScale = s.gradient.axis === 'x' ? xScale : yScale;
55
+ const serializableScale = convertToSerializableScale(gradientScale);
56
+ if (!serializableScale) return;
57
+ const domain = {
58
+ min: serializableScale.domain[0],
59
+ max: serializableScale.domain[1]
60
+ };
61
+ const stops = getGradientStops(s.gradient.stops, domain);
62
+ return {
63
+ seriesId: s.id,
64
+ gradient: s.gradient,
65
+ scale: serializableScale,
66
+ stops
67
+ };
68
+ });
69
+ }, [series, xScale, yScale]);
70
+
71
+ // Calculate bars for this specific category
72
+ const {
73
+ bars,
74
+ stackRect
75
+ } = useMemo(() => {
76
+ let allBars = [];
77
+
78
+ // Track how many bars we've stacked in each direction for gap calculation
79
+ let positiveBarCount = 0;
80
+ let negativeBarCount = 0;
81
+
82
+ // Track stack bounds for clipping
83
+ let minY = Infinity;
84
+ let maxY = -Infinity;
85
+
86
+ // Process each series in the stack
87
+ series.forEach(s => {
88
+ var _yScale2, _yScale3;
89
+ const data = getSeriesData(s.id);
90
+ if (!data) return;
91
+ const value = data[categoryIndex];
92
+ if (value === null || value === undefined) return;
93
+ const originalData = s.data;
94
+ const originalValue = originalData == null ? void 0 : originalData[categoryIndex];
95
+ // Only apply gap logic if the original data wasn't tuple format
96
+ const shouldApplyGap = !Array.isArray(originalValue);
97
+
98
+ // Sort to be in ascending order
99
+ const [bottom, top] = value.sort((a, b) => a - b);
100
+ const isAboveBaseline = bottom >= 0 && top !== bottom;
101
+ const isBelowBaseline = bottom <= 0 && bottom !== top;
102
+ const barBottom = (_yScale2 = yScale(bottom)) != null ? _yScale2 : baseline;
103
+ const barTop = (_yScale3 = yScale(top)) != null ? _yScale3 : baseline;
104
+
105
+ // Track bar counts for later gap calculations
106
+ if (shouldApplyGap) {
107
+ if (isAboveBaseline) {
108
+ positiveBarCount++;
109
+ } else if (isBelowBaseline) {
110
+ negativeBarCount++;
111
+ }
112
+ }
113
+
114
+ // Calculate height (remember SVG y coordinates are inverted)
115
+ const height = Math.abs(barBottom - barTop);
116
+ const y = Math.min(barBottom, barTop);
117
+
118
+ // Skip bars that would have zero or negative height
119
+ if (height <= 0) {
120
+ return;
121
+ }
122
+
123
+ // Update stack bounds
124
+ minY = Math.min(minY, y);
125
+ maxY = Math.max(maxY, y + height);
126
+
127
+ // Determine fill color, respecting gradient if present
128
+ let barFill = s.color || theme.color.fgPrimary;
129
+
130
+ // Evaluate gradient if provided (using precomputed stops)
131
+ const seriesGradientConfig = seriesGradients.find(g => (g == null ? void 0 : g.seriesId) === s.id);
132
+ if (seriesGradientConfig) {
133
+ var _seriesGradientConfig;
134
+ const axis = (_seriesGradientConfig = seriesGradientConfig.gradient.axis) != null ? _seriesGradientConfig : 'y';
135
+ // For x-axis gradient, use the categoryIndex
136
+ // For y-axis gradient, use the actual data value
137
+ const dataValue = axis === 'x' ? categoryIndex : top;
138
+ const evaluatedColor = evaluateGradientAtValue(seriesGradientConfig.stops, dataValue, seriesGradientConfig.scale);
139
+ if (evaluatedColor) {
140
+ // Only apply gradient color if fill is not explicitly set
141
+ barFill = evaluatedColor;
142
+ }
143
+ }
144
+ allBars.push({
145
+ seriesId: s.id,
146
+ x,
147
+ y,
148
+ width,
149
+ height,
150
+ dataY: value,
151
+ // Store the actual data value
152
+ fill: barFill,
153
+ // Check if the bar should be rounded based on the baseline, with an epsilon to handle floating-point rounding
154
+ roundTop: roundBaseline || Math.abs(barTop - baseline) >= EPSILON,
155
+ roundBottom: roundBaseline || Math.abs(barBottom - baseline) >= EPSILON,
156
+ shouldApplyGap
157
+ });
158
+ });
159
+
160
+ // Apply proportional gap distribution to maintain total stack height
161
+ if (stackGap && allBars.length > 1) {
162
+ // Separate bars by baseline side
163
+ const barsAboveBaseline = allBars.filter(bar => {
164
+ const [bottom, top] = bar.dataY.sort((a, b) => a - b);
165
+ return bottom >= 0 && top !== bottom && bar.shouldApplyGap;
166
+ });
167
+ const barsBelowBaseline = allBars.filter(bar => {
168
+ const [bottom, top] = bar.dataY.sort((a, b) => a - b);
169
+ return bottom <= 0 && bottom !== top && bar.shouldApplyGap;
170
+ });
171
+
172
+ // Apply proportional gaps to bars above baseline
173
+ if (barsAboveBaseline.length > 1) {
174
+ const totalGapSpace = stackGap * (barsAboveBaseline.length - 1);
175
+ const totalDataHeight = barsAboveBaseline.reduce((sum, bar) => sum + bar.height, 0);
176
+ const heightReduction = totalGapSpace / totalDataHeight;
177
+
178
+ // Sort bars by position (from baseline upward)
179
+ const sortedBars = barsAboveBaseline.sort((a, b) => b.y - a.y);
180
+ let currentY = baseline;
181
+ sortedBars.forEach((bar, index) => {
182
+ // Reduce bar height proportionally
183
+ const newHeight = bar.height * (1 - heightReduction);
184
+ const newY = currentY - newHeight;
185
+
186
+ // Update the bar in allBars array
187
+ const barIndex = allBars.findIndex(b => b.seriesId === bar.seriesId);
188
+ if (barIndex !== -1) {
189
+ allBars[barIndex] = _extends({}, allBars[barIndex], {
190
+ height: newHeight,
191
+ y: newY
192
+ });
193
+ }
194
+
195
+ // Move to next position (include gap for next bar)
196
+ currentY = newY - (index < sortedBars.length - 1 ? stackGap : 0);
197
+ });
198
+ }
199
+
200
+ // Apply proportional gaps to bars below baseline
201
+ if (barsBelowBaseline.length > 1) {
202
+ const totalGapSpace = stackGap * (barsBelowBaseline.length - 1);
203
+ const totalDataHeight = barsBelowBaseline.reduce((sum, bar) => sum + bar.height, 0);
204
+ const heightReduction = totalGapSpace / totalDataHeight;
205
+
206
+ // Sort bars by position (from baseline downward)
207
+ const sortedBars = barsBelowBaseline.sort((a, b) => a.y - b.y);
208
+ let currentY = baseline;
209
+ sortedBars.forEach((bar, index) => {
210
+ // Reduce bar height proportionally
211
+ const newHeight = bar.height * (1 - heightReduction);
212
+
213
+ // Update the bar in allBars array
214
+ const barIndex = allBars.findIndex(b => b.seriesId === bar.seriesId);
215
+ if (barIndex !== -1) {
216
+ allBars[barIndex] = _extends({}, allBars[barIndex], {
217
+ height: newHeight,
218
+ y: currentY
219
+ });
220
+ }
221
+
222
+ // Move to next position (include gap for next bar)
223
+ currentY = currentY + newHeight + (index < sortedBars.length - 1 ? stackGap : 0);
224
+ });
225
+ }
226
+
227
+ // Recalculate stack bounds after gap adjustments
228
+ if (allBars.length > 0) {
229
+ minY = Math.min(...allBars.map(bar => bar.y));
230
+ maxY = Math.max(...allBars.map(bar => bar.y + bar.height));
231
+ }
232
+ }
233
+
234
+ // Apply barMinSize constraints
235
+ if (barMinSize) {
236
+ // First, expand bars that need it and track the expansion
237
+ const expandedBars = allBars.map((bar, index) => {
238
+ if (bar.height < barMinSize) {
239
+ var _yScale4, _yScale5, _yScale6, _yScale7;
240
+ const heightIncrease = barMinSize - bar.height;
241
+ const [bottom, top] = bar.dataY.sort((a, b) => a - b);
242
+
243
+ // Determine how to expand the bar
244
+ let newBottom = bottom;
245
+ let newTop = top;
246
+ const scaleUnit = Math.abs(((_yScale4 = yScale(1)) != null ? _yScale4 : 0) - ((_yScale5 = yScale(0)) != null ? _yScale5 : 0));
247
+ if (bottom === 0) {
248
+ // Expand away from baseline (upward for positive)
249
+ newTop = top + heightIncrease / scaleUnit;
250
+ } else if (top === 0) {
251
+ // Expand away from baseline (downward for negative)
252
+ newBottom = bottom - heightIncrease / scaleUnit;
253
+ } else {
254
+ // Expand in both directions
255
+ const halfIncrease = heightIncrease / scaleUnit / 2;
256
+ newBottom = bottom - halfIncrease;
257
+ newTop = top + halfIncrease;
258
+ }
259
+
260
+ // Recalculate bar position with new data values
261
+ const newBarBottom = (_yScale6 = yScale(newBottom)) != null ? _yScale6 : baseline;
262
+ const newBarTop = (_yScale7 = yScale(newTop)) != null ? _yScale7 : baseline;
263
+ const newHeight = Math.abs(newBarBottom - newBarTop);
264
+ const newY = Math.min(newBarBottom, newBarTop);
265
+ return _extends({}, bar, {
266
+ height: newHeight,
267
+ y: newY,
268
+ wasExpanded: true
269
+ });
270
+ }
271
+ return _extends({}, bar, {
272
+ wasExpanded: false
273
+ });
274
+ });
275
+
276
+ // Now reposition all bars to avoid overlaps, similar to stackMinSize logic
277
+
278
+ // Sort bars by position to maintain order
279
+ const sortedExpandedBars = [...expandedBars].sort((a, b) => a.y - b.y);
280
+
281
+ // Determine if we have bars above and below baseline
282
+ const barsAboveBaseline = sortedExpandedBars.filter(bar => bar.y + bar.height <= baseline);
283
+ const barsBelowBaseline = sortedExpandedBars.filter(bar => bar.y >= baseline);
284
+
285
+ // Create a map of new positions
286
+ const newPositions = new Map();
287
+
288
+ // Start positioning from the baseline and work outward
289
+ let currentYAbove = baseline; // Start at baseline, work upward (decreasing Y)
290
+ let currentYBelow = baseline; // Start at baseline, work downward (increasing Y)
291
+
292
+ // Position bars above baseline (positive values, decreasing Y)
293
+ for (let i = barsAboveBaseline.length - 1; i >= 0; i--) {
294
+ const bar = barsAboveBaseline[i];
295
+ const newY = currentYAbove - bar.height;
296
+ newPositions.set(bar.seriesId, {
297
+ y: newY,
298
+ height: bar.height
299
+ });
300
+
301
+ // Update currentYAbove for next bar (preserve gaps)
302
+ if (i > 0) {
303
+ const currentBar = barsAboveBaseline[i];
304
+ const nextBar = barsAboveBaseline[i - 1];
305
+ // Find original bars to get original gap
306
+ const originalCurrent = allBars.find(b => b.seriesId === currentBar.seriesId);
307
+ const originalNext = allBars.find(b => b.seriesId === nextBar.seriesId);
308
+ const originalGap = originalCurrent.y - (originalNext.y + originalNext.height);
309
+ currentYAbove = newY - originalGap;
310
+ }
311
+ }
312
+
313
+ // Position bars below baseline (negative values, increasing Y)
314
+ for (let i = 0; i < barsBelowBaseline.length; i++) {
315
+ const bar = barsBelowBaseline[i];
316
+ const newY = currentYBelow;
317
+ newPositions.set(bar.seriesId, {
318
+ y: newY,
319
+ height: bar.height
320
+ });
321
+
322
+ // Update currentYBelow for next bar (preserve gaps)
323
+ if (i < barsBelowBaseline.length - 1) {
324
+ const currentBar = barsBelowBaseline[i];
325
+ const nextBar = barsBelowBaseline[i + 1];
326
+ // Find original bars to get original gap
327
+ const originalCurrent = allBars.find(b => b.seriesId === currentBar.seriesId);
328
+ const originalNext = allBars.find(b => b.seriesId === nextBar.seriesId);
329
+ const originalGap = originalNext.y - (originalCurrent.y + originalCurrent.height);
330
+ currentYBelow = newY + bar.height + originalGap;
331
+ }
332
+ }
333
+
334
+ // Apply new positions to all bars
335
+ allBars = expandedBars.map(bar => {
336
+ const newPos = newPositions.get(bar.seriesId);
337
+ if (newPos) {
338
+ return _extends({}, bar, {
339
+ y: newPos.y,
340
+ height: newPos.height
341
+ });
342
+ }
343
+ return bar;
344
+ });
345
+
346
+ // Recalculate stack bounds after barMinSize expansion and repositioning
347
+ if (allBars.length > 0) {
348
+ minY = Math.min(...allBars.map(bar => bar.y));
349
+ maxY = Math.max(...allBars.map(bar => bar.y + bar.height));
350
+ }
351
+ }
352
+
353
+ // Apply border radius logic (will be reapplied after stackMinSize if needed)
354
+ const applyBorderRadiusLogic = bars => {
355
+ return bars.sort((a, b) => b.y - a.y).map((a, index) => {
356
+ const barBefore = index > 0 ? bars[index - 1] : null;
357
+ const barAfter = index < bars.length - 1 ? bars[index + 1] : null;
358
+ const shouldRoundTop = index === bars.length - 1 || a.shouldApplyGap && stackGap || !a.shouldApplyGap && barAfter && barAfter.y + barAfter.height !== a.y;
359
+ const shouldRoundBottom = index === 0 || a.shouldApplyGap && stackGap || !a.shouldApplyGap && barBefore && barBefore.y !== a.y + a.height;
360
+ return _extends({}, a, {
361
+ roundTop: Boolean(a.roundTop && shouldRoundTop),
362
+ roundBottom: Boolean(a.roundBottom && shouldRoundBottom)
363
+ });
364
+ });
365
+ };
366
+ allBars = applyBorderRadiusLogic(allBars);
367
+
368
+ // Calculate the bounding rect for the entire stack
369
+ let stackBounds = {
370
+ x,
371
+ y: minY === Infinity ? baseline : minY,
372
+ width,
373
+ height: maxY === -Infinity ? 0 : maxY - minY
374
+ };
375
+
376
+ // Apply stackMinSize constraints
377
+ if (stackMinSize) {
378
+ if (allBars.length === 1 && stackBounds.height < stackMinSize) {
379
+ var _yScale8, _yScale9, _yScale0, _yScale1;
380
+ // For single bars (non-stacked), treat stackMinSize like barMinSize
381
+
382
+ const bar = allBars[0];
383
+ const heightIncrease = stackMinSize - bar.height;
384
+ const [bottom, top] = bar.dataY.sort((a, b) => a - b);
385
+
386
+ // Determine how to expand the bar (same logic as barMinSize)
387
+ let newBottom = bottom;
388
+ let newTop = top;
389
+ const scaleUnit = Math.abs(((_yScale8 = yScale(1)) != null ? _yScale8 : 0) - ((_yScale9 = yScale(0)) != null ? _yScale9 : 0));
390
+ if (bottom === 0) {
391
+ // Expand away from baseline (upward for positive)
392
+ newTop = top + heightIncrease / scaleUnit;
393
+ } else if (top === 0) {
394
+ // Expand away from baseline (downward for negative)
395
+ newBottom = bottom - heightIncrease / scaleUnit;
396
+ } else {
397
+ // Expand in both directions
398
+ const halfIncrease = heightIncrease / scaleUnit / 2;
399
+ newBottom = bottom - halfIncrease;
400
+ newTop = top + halfIncrease;
401
+ }
402
+
403
+ // Recalculate bar position with new data values
404
+ const newBarBottom = (_yScale0 = yScale(newBottom)) != null ? _yScale0 : baseline;
405
+ const newBarTop = (_yScale1 = yScale(newTop)) != null ? _yScale1 : baseline;
406
+ const newHeight = Math.abs(newBarBottom - newBarTop);
407
+ const newY = Math.min(newBarBottom, newBarTop);
408
+ allBars[0] = _extends({}, bar, {
409
+ height: newHeight,
410
+ y: newY
411
+ });
412
+
413
+ // Recalculate stack bounds
414
+ stackBounds = {
415
+ x,
416
+ y: newY,
417
+ width,
418
+ height: newHeight
419
+ };
420
+ } else if (allBars.length > 1 && stackBounds.height < stackMinSize) {
421
+ // For multiple bars (stacked), scale heights while preserving gaps
422
+
423
+ // Calculate total bar height (excluding gaps)
424
+ const totalBarHeight = allBars.reduce((sum, bar) => sum + bar.height, 0);
425
+ const totalGapHeight = stackBounds.height - totalBarHeight;
426
+
427
+ // Calculate how much we need to increase bar heights
428
+ const requiredBarHeight = stackMinSize - totalGapHeight;
429
+ const barScaleFactor = requiredBarHeight / totalBarHeight;
430
+
431
+ // Sort bars by position to maintain order
432
+ const sortedBars = [...allBars].sort((a, b) => a.y - b.y);
433
+
434
+ // Determine if we have bars above and below baseline
435
+ const barsAboveBaseline = sortedBars.filter(bar => bar.y + bar.height <= baseline);
436
+ const barsBelowBaseline = sortedBars.filter(bar => bar.y >= baseline);
437
+
438
+ // Create a map of new positions
439
+ const newPositions = new Map();
440
+
441
+ // Start positioning from the baseline and work outward
442
+ let currentYAbove = baseline; // Start at baseline, work upward (decreasing Y)
443
+ let currentYBelow = baseline; // Start at baseline, work downward (increasing Y)
444
+
445
+ // Position bars above baseline (positive values, decreasing Y)
446
+ for (let i = barsAboveBaseline.length - 1; i >= 0; i--) {
447
+ const bar = barsAboveBaseline[i];
448
+ const newHeight = bar.height * barScaleFactor;
449
+ const newY = currentYAbove - newHeight;
450
+ newPositions.set(bar.seriesId, {
451
+ y: newY,
452
+ height: newHeight
453
+ });
454
+
455
+ // Update currentYAbove for next bar (preserve gaps)
456
+ if (i > 0) {
457
+ const currentBar = barsAboveBaseline[i];
458
+ const nextBar = barsAboveBaseline[i - 1];
459
+ const originalGap = currentBar.y - (nextBar.y + nextBar.height);
460
+ currentYAbove = newY - originalGap;
461
+ }
462
+ }
463
+
464
+ // Position bars below baseline (negative values, increasing Y)
465
+ for (let i = 0; i < barsBelowBaseline.length; i++) {
466
+ const bar = barsBelowBaseline[i];
467
+ const newHeight = bar.height * barScaleFactor;
468
+ const newY = currentYBelow;
469
+ newPositions.set(bar.seriesId, {
470
+ y: newY,
471
+ height: newHeight
472
+ });
473
+
474
+ // Update currentYBelow for next bar (preserve gaps)
475
+ if (i < barsBelowBaseline.length - 1) {
476
+ const currentBar = barsBelowBaseline[i];
477
+ const nextBar = barsBelowBaseline[i + 1];
478
+ const originalGap = nextBar.y - (currentBar.y + currentBar.height);
479
+ currentYBelow = newY + newHeight + originalGap;
480
+ }
481
+ }
482
+
483
+ // Apply new positions to all bars
484
+ allBars = allBars.map(bar => {
485
+ const newPos = newPositions.get(bar.seriesId);
486
+ if (!newPos) return bar;
487
+ return _extends({}, bar, {
488
+ height: newPos.height,
489
+ y: newPos.y
490
+ });
491
+ });
492
+
493
+ // Recalculate stack bounds
494
+ const newMinY = Math.min(...allBars.map(bar => bar.y));
495
+ const newMaxY = Math.max(...allBars.map(bar => bar.y + bar.height));
496
+ stackBounds = {
497
+ x,
498
+ y: newMinY,
499
+ width,
500
+ height: newMaxY - newMinY
501
+ };
502
+ }
503
+
504
+ // Reapply border radius logic only if we actually scaled
505
+ if (stackBounds.height < stackMinSize) {
506
+ allBars = applyBorderRadiusLogic(allBars);
507
+ }
508
+ }
509
+ return {
510
+ bars: allBars,
511
+ stackRect: stackBounds
512
+ };
513
+ }, [series, x, width, getSeriesData, categoryIndex, roundBaseline, baseline, stackGap, barMinSize, stackMinSize, yScale, seriesGradients, theme.color.fgPrimary]);
514
+ const xData = xAxis != null && xAxis.data && Array.isArray(xAxis.data) && typeof xAxis.data[0] === 'number' ? xAxis.data : undefined;
515
+ const dataX = xData ? xData[categoryIndex] : categoryIndex;
516
+ const barElements = bars.map((bar, index) => /*#__PURE__*/_jsx(Bar, {
517
+ BarComponent: defaultBarComponent,
518
+ borderRadius: borderRadius,
519
+ dataX: dataX,
520
+ dataY: bar.dataY,
521
+ fill: bar.fill,
522
+ fillOpacity: defaultFillOpacity,
523
+ height: bar.height,
524
+ originY: baseline,
525
+ roundBottom: bar.roundBottom,
526
+ roundTop: bar.roundTop,
527
+ stroke: defaultStroke,
528
+ strokeWidth: defaultStrokeWidth,
529
+ transition: transition,
530
+ width: bar.width,
531
+ x: bar.x,
532
+ y: bar.y
533
+ }, bar.seriesId + "-" + categoryIndex + "-" + index));
534
+
535
+ // Check if the bar should be rounded based on the baseline, with an epsilon to handle floating-point rounding
536
+ const stackRoundBottom = roundBaseline || Math.abs(stackRect.y + stackRect.height - baseline) >= EPSILON;
537
+ const stackRoundTop = roundBaseline || Math.abs(stackRect.y - baseline) >= EPSILON;
538
+ return /*#__PURE__*/_jsx(BarStackComponent, {
539
+ borderRadius: borderRadius,
540
+ categoryIndex: categoryIndex,
541
+ height: stackRect.height,
542
+ roundBottom: stackRoundBottom,
543
+ roundTop: stackRoundTop,
544
+ transition: transition,
545
+ width: stackRect.width,
546
+ x: stackRect.x,
547
+ y: stackRect.y,
548
+ yOrigin: baseline,
549
+ children: barElements
550
+ });
551
+ });