@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,592 @@
1
+ const _excluded = ["id"];
2
+ 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); }
3
+ function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
4
+ import { useCallback, useMemo, useState } from 'react';
5
+ import { getChartDomain, getChartRange, isValidBounds } from './chart';
6
+ import { getCategoricalScale, getNumericScale, isCategoricalScale, isNumericScale } from './scale';
7
+ export const defaultAxisId = 'DEFAULT_AXIS_ID';
8
+ export const defaultAxisScaleType = 'linear';
9
+
10
+ /**
11
+ * Axis configuration with computed bounds
12
+ */
13
+
14
+ /**
15
+ * Axis configuration without computed bounds (used for input)
16
+ */
17
+
18
+ /**
19
+ * Gets a D3 scale based on the axis configuration.
20
+ * Handles both numeric (linear/log) and categorical (band) scales.
21
+ *
22
+ * For numeric scales, the domain limit controls whether bounds are "nice" (human-friendly)
23
+ * or "strict" (exact min/max). Range can be customized using function-based configuration.
24
+ *
25
+ * @param params - Scale parameters
26
+ * @returns The D3 scale function
27
+ * @throws An Error if bounds are invalid
28
+ */
29
+ export const getAxisScale = _ref => {
30
+ var _config$scaleType;
31
+ let {
32
+ config,
33
+ type,
34
+ range,
35
+ dataDomain
36
+ } = _ref;
37
+ const scaleType = (_config$scaleType = config == null ? void 0 : config.scaleType) != null ? _config$scaleType : 'linear';
38
+ let adjustedRange = range;
39
+
40
+ // Invert range for Y axis for SVG coordinate system
41
+ if (type === 'y') {
42
+ adjustedRange = {
43
+ min: adjustedRange.max,
44
+ max: adjustedRange.min
45
+ };
46
+ }
47
+ let adjustedDomain = dataDomain;
48
+ if (config != null && config.domain) {
49
+ var _config$domain$min, _config$domain$max;
50
+ adjustedDomain = {
51
+ min: (_config$domain$min = config.domain.min) != null ? _config$domain$min : dataDomain.min,
52
+ max: (_config$domain$max = config.domain.max) != null ? _config$domain$max : dataDomain.max
53
+ };
54
+ }
55
+ if (!isValidBounds(adjustedDomain)) throw new Error('Invalid domain bounds. See https://cds.coinbase.com/http://localhost:3000/components/graphs/XAxis/#domain');
56
+ if (scaleType === 'band') {
57
+ var _config$categoryPaddi;
58
+ return getCategoricalScale({
59
+ domain: adjustedDomain,
60
+ range: adjustedRange,
61
+ padding: (_config$categoryPaddi = config == null ? void 0 : config.categoryPadding) != null ? _config$categoryPaddi : 0.3
62
+ });
63
+ } else {
64
+ const scale = getNumericScale({
65
+ domain: adjustedDomain,
66
+ range: adjustedRange,
67
+ scaleType: scaleType
68
+ });
69
+ if ((config == null ? void 0 : config.domainLimit) === 'nice') scale.nice();
70
+ return scale;
71
+ }
72
+ };
73
+
74
+ /**
75
+ * Formats the array of user-provided axis configs with default values and validates axis ids.
76
+ * Ensures at least one axis config exists if no input is provided.
77
+ * Requires specific axis ids when there are more than 1 axes.
78
+ * Defaults the axis id for a single axis config if there is no id.
79
+ * @param type - the type of axis, 'x' or 'y'
80
+ * @param axes - array of axis configs or single axis config
81
+ * @param defaultId - the default id to use for the axis
82
+ * @param defaultScaleType - the default scale type to use for the axis
83
+ * @returns array of axis configs with IDs
84
+ */
85
+ export const getAxisConfig = function (type, axes, defaultId, defaultScaleType) {
86
+ if (defaultId === void 0) {
87
+ defaultId = defaultAxisId;
88
+ }
89
+ if (defaultScaleType === void 0) {
90
+ defaultScaleType = defaultAxisScaleType;
91
+ }
92
+ const defaultDomainLimit = type === 'x' ? 'strict' : 'nice';
93
+ if (!axes) {
94
+ return [{
95
+ id: defaultId,
96
+ scaleType: defaultScaleType,
97
+ domainLimit: defaultDomainLimit
98
+ }];
99
+ }
100
+ if (Array.isArray(axes)) {
101
+ const axesLength = axes.length;
102
+ // forces id to be defined on every input config when there are multiple axes
103
+ if (axesLength > 1 && axes.some(_ref2 => {
104
+ let {
105
+ id
106
+ } = _ref2;
107
+ return id === undefined;
108
+ })) {
109
+ throw new Error('When defining multiple axes, each must have a unique id. See https://cds.coinbase.com/components/graphs/YAxis/#multiple-y-axes.');
110
+ }
111
+ return axes.map(_ref3 => {
112
+ let {
113
+ id
114
+ } = _ref3,
115
+ axis = _objectWithoutPropertiesLoose(_ref3, _excluded);
116
+ return _extends({
117
+ // defaults the axis id if only a single axis is provided
118
+ id: axesLength > 1 ? id != null ? id : defaultAxisId : id,
119
+ scaleType: defaultScaleType,
120
+ domainLimit: defaultDomainLimit
121
+ }, axis);
122
+ });
123
+ }
124
+
125
+ // Single axis config
126
+ return [_extends({
127
+ id: defaultId,
128
+ scaleType: defaultScaleType,
129
+ domainLimit: defaultDomainLimit
130
+ }, axes)];
131
+ };
132
+
133
+ /**
134
+ * Calculates the data domain for an axis based on its configuration and series data.
135
+ * Handles both x and y axes, categorical data, custom domain configurations, and stacking.
136
+ *
137
+ * @param axisParam - The axis configuration
138
+ * @param series - Array of series objects (for stacking support)
139
+ * @param axisType - Whether this is an 'x' or 'y' axis
140
+ * @returns The calculated axis bounds
141
+ */
142
+ export const getAxisDomain = (axisParam, series, axisType) => {
143
+ var _finalDomain$min, _finalDomain$max;
144
+ let dataDomain = null;
145
+ if (axisParam.data && Array.isArray(axisParam.data) && axisParam.data.length > 0) {
146
+ const firstItem = axisParam.data[0];
147
+ if (typeof firstItem === 'number') {
148
+ // Numeric data - use actual min/max values
149
+ const numericData = axisParam.data;
150
+ dataDomain = {
151
+ min: Math.min(...numericData),
152
+ max: Math.max(...numericData)
153
+ };
154
+ } else if (typeof firstItem === 'string') {
155
+ // String labels - use indices as domain (0 to length-1)
156
+ // This allows using string labels with linear scales
157
+ dataDomain = {
158
+ min: 0,
159
+ max: axisParam.data.length - 1
160
+ };
161
+ }
162
+ }
163
+
164
+ // Calculate domain from series data
165
+ const seriesDomain = axisType === 'x' ? getChartDomain(series) : getChartRange(series);
166
+
167
+ // If data sets the domain, use that instead of the series domain
168
+ const preferredDataDomain = dataDomain != null ? dataDomain : seriesDomain;
169
+ const bounds = axisParam.domain;
170
+ let finalDomain;
171
+ if (typeof bounds === 'function') {
172
+ var _preferredDataDomain$, _preferredDataDomain$2;
173
+ // Apply the transform function to the base domain
174
+ // No need to default to 0 here since we'll do it once at the end
175
+ finalDomain = bounds({
176
+ min: (_preferredDataDomain$ = preferredDataDomain.min) != null ? _preferredDataDomain$ : 0,
177
+ max: (_preferredDataDomain$2 = preferredDataDomain.max) != null ? _preferredDataDomain$2 : 0
178
+ });
179
+ } else if (bounds && typeof bounds === 'object') {
180
+ var _bounds$min, _bounds$max;
181
+ // Merge explicit bounds with calculated domain
182
+ finalDomain = {
183
+ min: (_bounds$min = bounds.min) != null ? _bounds$min : preferredDataDomain.min,
184
+ max: (_bounds$max = bounds.max) != null ? _bounds$max : preferredDataDomain.max
185
+ };
186
+ } else {
187
+ // Use the base domain as-is
188
+ finalDomain = preferredDataDomain;
189
+ }
190
+
191
+ // Ensure we always return valid bounds with no undefined values
192
+ return {
193
+ min: (_finalDomain$min = finalDomain.min) != null ? _finalDomain$min : 0,
194
+ max: (_finalDomain$max = finalDomain.max) != null ? _finalDomain$max : 0
195
+ };
196
+ };
197
+
198
+ /**
199
+ * Calculates the visual range for an axis based on the chart rectangle and configuration.
200
+ * Handles custom range configurations including functions and partial bounds.
201
+ *
202
+ * @param axisParam - The axis configuration
203
+ * @param chartRect - The chart drawing area rectangle
204
+ * @param axisType - Whether this is an 'x' or 'y' axis
205
+ * @returns The calculated axis range bounds
206
+ */
207
+ export const getAxisRange = (axisParam, chartRect, axisType) => {
208
+ // Calculate base range based on axis type
209
+ let baseRange;
210
+ if (axisType === 'x') {
211
+ baseRange = {
212
+ min: chartRect.x,
213
+ max: chartRect.x + chartRect.width
214
+ };
215
+ } else {
216
+ baseRange = {
217
+ min: chartRect.y,
218
+ max: chartRect.y + chartRect.height
219
+ };
220
+ }
221
+
222
+ // Apply any custom range configuration
223
+ const rangeConfig = axisParam.range;
224
+ if (!rangeConfig) {
225
+ return baseRange;
226
+ }
227
+ if (typeof rangeConfig === 'function') {
228
+ // Apply the transform function to the base range
229
+ return rangeConfig(baseRange);
230
+ } else {
231
+ var _rangeConfig$min, _rangeConfig$max;
232
+ // Merge explicit range values with calculated range
233
+ return {
234
+ min: (_rangeConfig$min = rangeConfig.min) != null ? _rangeConfig$min : baseRange.min,
235
+ max: (_rangeConfig$max = rangeConfig.max) != null ? _rangeConfig$max : baseRange.max
236
+ };
237
+ }
238
+ };
239
+
240
+ /**
241
+ * Options for tick generation behavior
242
+ */
243
+
244
+ /**
245
+ * Formats a tick value for display on an axis.
246
+ * Consolidates the identical formatting logic shared between XAxis and YAxis.
247
+ *
248
+ * @param value - The raw tick value to format
249
+ * @param tickFormatter - Optional custom formatter function
250
+ * @returns The formatted tick value as a React node
251
+ */
252
+ export const formatAxisTick = (value, tickFormatter) => {
253
+ if (tickFormatter) {
254
+ return tickFormatter(value);
255
+ }
256
+ return value;
257
+ };
258
+
259
+ /**
260
+ * Calculates a rounded step size for tick generation.
261
+ * Chooses from multiples of 1, 2, or 5 (scaled by powers of 10).
262
+ *
263
+ * @param roughStep - The approximate step size needed
264
+ * @param minStep - Optional minimum step size constraint
265
+ * @param maxStep - Optional maximum step size constraint
266
+ * @returns rounded step size within the specified constraints
267
+ */
268
+ const calculateNiceStep = (roughStep, minStep, maxStep) => {
269
+ if (roughStep <= 0) return minStep != null ? minStep : 1;
270
+ const magnitude = Math.pow(10, Math.floor(Math.log10(roughStep)));
271
+ const residual = roughStep / magnitude;
272
+ let roundResidual;
273
+ if (residual <= 1) {
274
+ roundResidual = 1;
275
+ } else if (residual <= 2) {
276
+ roundResidual = 2;
277
+ } else if (residual <= 5) {
278
+ roundResidual = 5;
279
+ } else {
280
+ roundResidual = 10;
281
+ }
282
+ let niceStep = roundResidual * magnitude;
283
+ if (minStep !== undefined && niceStep < minStep) {
284
+ niceStep = minStep;
285
+ }
286
+ if (maxStep !== undefined && niceStep > maxStep) {
287
+ niceStep = maxStep;
288
+ }
289
+ return niceStep;
290
+ };
291
+
292
+ /**
293
+ * Generates evenly distributed tick values.
294
+ * Always includes first and last domain values, with intermediate ticks evenly distributed using nice step sizes.
295
+ * Selects from actual data points (possibleTickValues) or generates nice round numbers.
296
+ *
297
+ * @param scale - The numeric scale function
298
+ * @param tickInterval - Space between ticks (in pixels)
299
+ * @param possibleTickValues - Optional array of possible tick values to select from (e.g., data indices). If not provided, generates nice round numbers with guaranteed first/last inclusion.
300
+ * @param options - Options for tick generation behavior
301
+ * @returns Array of tick values, always including first and last domain values
302
+ */
303
+ const generateEvenlyDistributedTicks = (scale, tickInterval, possibleTickValues, options) => {
304
+ var _options$minTickCount;
305
+ const minTickCount = (_options$minTickCount = options == null ? void 0 : options.minTickCount) != null ? _options$minTickCount : 4;
306
+ const [rangeMin, rangeMax] = scale.range();
307
+ const range = Math.abs(rangeMax - rangeMin);
308
+ const tickCountFromSpace = Math.floor(range / tickInterval);
309
+ const tickCount = Math.max(tickCountFromSpace, minTickCount);
310
+ if (tickCount < 1) {
311
+ return [];
312
+ }
313
+
314
+ // If we have possibleTickValues, select evenly from them
315
+ if (possibleTickValues && possibleTickValues.length > 0) {
316
+ // Limit tick count to available values
317
+ const finalTickCount = Math.min(tickCount, possibleTickValues.length);
318
+ const tickValues = [];
319
+ const step = (possibleTickValues.length - 1) / (finalTickCount - 1);
320
+ for (let i = 0; i < finalTickCount; i++) {
321
+ const index = i === finalTickCount - 1 ? possibleTickValues.length - 1 : Math.round(step * i);
322
+ tickValues.push(possibleTickValues[index]);
323
+ }
324
+ return tickValues;
325
+ }
326
+
327
+ // Generate nice round numbers that always include first and last domain values
328
+ const [domainMin, domainMax] = scale.domain();
329
+ if (tickCount === 1) {
330
+ return [domainMin];
331
+ }
332
+ if (tickCount === 2) {
333
+ return [domainMin, domainMax];
334
+ }
335
+
336
+ // Calculate a nice step size
337
+ const domainRange = domainMax - domainMin;
338
+ const roughStep = domainRange / (tickCount - 1);
339
+ const niceStep = calculateNiceStep(roughStep, options == null ? void 0 : options.minStep, options == null ? void 0 : options.maxStep);
340
+
341
+ // Generate ticks starting from domainMin and stepping by niceStep
342
+ const tickValues = [domainMin];
343
+
344
+ // Generate intermediate ticks using the nice step, starting from domainMin
345
+ let currentTick = domainMin + niceStep;
346
+ while (currentTick < domainMax) {
347
+ // Avoid floating point precision issues
348
+ const roundedTick = Number(currentTick.toFixed(10));
349
+ tickValues.push(roundedTick);
350
+ currentTick += niceStep;
351
+ }
352
+
353
+ // Only include domainMax if it naturally falls on a step (or very close due to floating point)
354
+ // or if the last tick is far enough away that including max provides useful context
355
+ const lastTick = tickValues[tickValues.length - 1];
356
+ const distanceToMax = domainMax - lastTick;
357
+
358
+ // Include max if:
359
+ // 1. It naturally falls on a step (within floating point tolerance)
360
+ // 2. Or the last tick is more than half a step away (provides meaningful context)
361
+ const tolerance = niceStep * 0.0001; // Floating point tolerance
362
+ const shouldIncludeMax = Math.abs(distanceToMax - niceStep) < tolerance ||
363
+ // Natural step
364
+ distanceToMax > niceStep * 0.5; // Far enough to provide context
365
+
366
+ if (shouldIncludeMax && domainMax !== lastTick) {
367
+ tickValues.push(domainMax);
368
+ }
369
+ return tickValues;
370
+ };
371
+
372
+ /**
373
+ * Processes tick configuration and returns tick data with positions.
374
+ *
375
+ * **Parameter Precedence by Scale Type:**
376
+ *
377
+ * **For Numeric Scales (linear/log):**
378
+ * 1. `ticks` (array) - Explicit tick values override all other options
379
+ * 2. `ticks` (function) - Filter function for tick selection
380
+ * 3. `ticks` (boolean) - Show/hide all possible ticks
381
+ * 4. `requestedTickCount` - D3 automatic tick generation (overrides tickInterval)
382
+ * 5. `tickInterval` - Pixel-based spacing (fallback)
383
+ *
384
+ * **For Categorical Scales (band):**
385
+ * 1. `ticks` (array) - Explicit category indices to display
386
+ * 2. `ticks` (function) - Filter function for category selection
387
+ * 3. `ticks` (boolean) - Show/hide all categories
388
+ * 4. Default - Show all categories (requestedTickCount and tickInterval are ignored)
389
+ *
390
+ * @param params - Tick processing parameters
391
+ * @param params.ticks - Custom tick configuration with multiple formats:
392
+ * - **Array**: For numeric scales: exact tick values; For band scales: category indices
393
+ * - **Function**: Predicate to filter tick values or category indices
394
+ * - **Boolean**: Show all (true) or no ticks (false) for both scale types
395
+ * @param params.scaleFunction - D3 scale function (numeric or band scale)
396
+ * @param params.requestedTickCount - Number of ticks for D3 generation (**numeric scales only**, overrides tickInterval)
397
+ * @param params.categories - Category labels (**band scales only**)
398
+ * @param params.possibleTickValues - Available tick values for filtering/selection (**numeric scales only**)
399
+ * @param params.tickInterval - Pixel spacing between ticks (**numeric scales only**, fallback option)
400
+ * @returns Array of tick data with values and positions
401
+ *
402
+ * @example
403
+ * // Basic usage with tickInterval for pixel-based spacing
404
+ * import { scaleLinear } from 'd3-scale';
405
+ *
406
+ * const numericScale = scaleLinear().domain([0, 10]).range([0, 400]);
407
+ * const result = getAxisTicksData({
408
+ * scaleFunction: numericScale,
409
+ * tickInterval: 80, // 80 pixels between ticks
410
+ * possibleTickValues: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
411
+ * });
412
+ * // Returns: [
413
+ * // { tick: 0, position: 0 }, // Always includes first
414
+ * // { tick: 2, position: 80 },
415
+ * // { tick: 5, position: 200 },
416
+ * // { tick: 7, position: 280 },
417
+ * // { tick: 10, position: 400 } // Always includes last
418
+ * // ]
419
+ *
420
+ * @example
421
+ * // Using requestedTickCount for D3-generated ticks
422
+ * const result = getAxisTicksData({
423
+ * scaleFunction: numericScale,
424
+ * requestedTickCount: 5
425
+ * });
426
+ * // Uses D3's tick generation algorithm
427
+ *
428
+ * @example
429
+ * // Using explicit tick values
430
+ * const result = getAxisTicksData({
431
+ * scaleFunction: numericScale,
432
+ * ticks: [0, 2.5, 5, 7.5, 10]
433
+ * });
434
+ * // Returns exact positions for specified values
435
+ *
436
+ * @example
437
+ * // Using tick filter function
438
+ * const result = getAxisTicksData({
439
+ * scaleFunction: numericScale,
440
+ * ticks: (value) => value % 2 === 0, // Only even numbers
441
+ * possibleTickValues: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
442
+ * });
443
+ * // Returns: [0, 2, 4, 6, 8, 10] with their positions
444
+ *
445
+ * @example
446
+ * // Band scale with categories (requestedTickCount and tickInterval are ignored)
447
+ * import { scaleBand } from 'd3-scale';
448
+ *
449
+ * const bandScale = scaleBand().domain([0, 1, 2, 3, 4]).range([0, 400]).padding(0.1);
450
+ * const result = getAxisTicksData({
451
+ * scaleFunction: bandScale,
452
+ * categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May'],
453
+ * ticks: [0, 2, 4], // Show only Jan (index 0), Mar (index 2), May (index 4)
454
+ * requestedTickCount: 10, // IGNORED for band scales
455
+ * tickInterval: 50 // IGNORED for band scales
456
+ * });
457
+ * // Returns tick positions centered in each selected band
458
+ */
459
+ export const getAxisTicksData = _ref4 => {
460
+ let {
461
+ ticks,
462
+ scaleFunction,
463
+ requestedTickCount,
464
+ categories = [],
465
+ possibleTickValues,
466
+ tickInterval,
467
+ options
468
+ } = _ref4;
469
+ // Handle band scales
470
+ if (isCategoricalScale(scaleFunction)) {
471
+ // If explicit ticks are provided as array, use them
472
+ if (Array.isArray(ticks)) {
473
+ return ticks.filter(index => index >= 0 && index < categories.length).map(index => {
474
+ var _bandwidth;
475
+ // Band scales expect numeric indices, not category strings
476
+ const position = scaleFunction(index);
477
+ if (position === undefined) return null;
478
+ return {
479
+ tick: index,
480
+ position: position + ((_bandwidth = scaleFunction.bandwidth == null ? void 0 : scaleFunction.bandwidth()) != null ? _bandwidth : 0) / 2
481
+ };
482
+ }).filter(Boolean);
483
+ }
484
+
485
+ // If a tick function is provided, use it to filter
486
+ if (typeof ticks === 'function') {
487
+ return categories.map((category, index) => {
488
+ var _bandwidth2;
489
+ if (!ticks(index)) return null;
490
+
491
+ // Band scales expect numeric indices, not category strings
492
+ const position = scaleFunction(index);
493
+ if (position === undefined) return null;
494
+ return {
495
+ tick: index,
496
+ position: position + ((_bandwidth2 = scaleFunction.bandwidth == null ? void 0 : scaleFunction.bandwidth()) != null ? _bandwidth2 : 0) / 2
497
+ };
498
+ }).filter(Boolean);
499
+ }
500
+ if (typeof ticks === 'boolean' && !ticks) {
501
+ return [];
502
+ }
503
+
504
+ // For band scales without explicit ticks, show all categories
505
+ // requestedTickCount is ignored for categorical scales - use ticks parameter to control visibility
506
+ return categories.map((category, index) => {
507
+ var _bandwidth3;
508
+ // Band scales expect numeric indices, not category strings
509
+ const position = scaleFunction(index);
510
+ if (position === undefined) return null;
511
+ return {
512
+ tick: index,
513
+ position: position + ((_bandwidth3 = scaleFunction.bandwidth == null ? void 0 : scaleFunction.bandwidth()) != null ? _bandwidth3 : 0) / 2
514
+ };
515
+ }).filter(Boolean);
516
+ }
517
+
518
+ // Handle numeric scales
519
+ if (!isNumericScale(scaleFunction)) {
520
+ console.warn('Scale does not support automatic tick generation');
521
+ return [];
522
+ }
523
+ const numericScale = scaleFunction;
524
+ let tickValues = [];
525
+ if (Array.isArray(ticks)) {
526
+ // Use exact tick values provided
527
+ tickValues = ticks;
528
+ } else if (typeof ticks === 'function') {
529
+ // Filter the possible tick values using the predicate function
530
+ if (possibleTickValues) {
531
+ tickValues = possibleTickValues.filter(ticks);
532
+ } else {
533
+ // Fallback to scale-generated ticks if no possible tick values provided
534
+ const generatedTicks = numericScale.ticks(requestedTickCount);
535
+ tickValues = generatedTicks.filter(ticks);
536
+ }
537
+ } else if (requestedTickCount !== undefined) {
538
+ // Use scale-generated ticks
539
+ tickValues = numericScale.ticks(requestedTickCount);
540
+ } else if (tickInterval !== undefined) {
541
+ tickValues = generateEvenlyDistributedTicks(numericScale, tickInterval, possibleTickValues, options);
542
+ }
543
+
544
+ // Map values to positions using the scale function
545
+ return tickValues.map(tick => ({
546
+ tick,
547
+ position: numericScale(tick)
548
+ }));
549
+ };
550
+ /**
551
+ * Calculates the total amount of padding needed to render a set of axes on the main drawing area of the chart.
552
+ * Returns the registed axes, an API for adding/removing axes as well as the total calculated padding that must be reserved in the drawing area.
553
+ */
554
+ export const useTotalAxisPadding = () => {
555
+ const [renderedAxes, setRenderedAxes] = useState(new Map());
556
+ const registerAxis = useCallback((id, position, size) => {
557
+ setRenderedAxes(prev => {
558
+ const newMap = new Map(prev);
559
+ newMap.set(id, {
560
+ id,
561
+ position,
562
+ size
563
+ });
564
+ return newMap;
565
+ });
566
+ }, []);
567
+ const unregisterAxis = useCallback(id => {
568
+ setRenderedAxes(prev => {
569
+ const newMap = new Map(prev);
570
+ newMap.delete(id);
571
+ return newMap;
572
+ });
573
+ }, []);
574
+ const axisPadding = useMemo(() => {
575
+ const padding = {
576
+ top: 0,
577
+ right: 0,
578
+ bottom: 0,
579
+ left: 0
580
+ };
581
+ renderedAxes.forEach(axis => {
582
+ padding[axis.position] += axis.size;
583
+ });
584
+ return padding;
585
+ }, [renderedAxes]);
586
+ return {
587
+ renderedAxes,
588
+ axisPadding,
589
+ registerAxis,
590
+ unregisterAxis
591
+ };
592
+ };
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Calculates the size adjustment needed for bars when accounting for gaps between them.
3
+ * This function helps determine how much to reduce each bar's width to accommodate
4
+ * the specified gap size between multiple bars in a group.
5
+ *
6
+ * @param barCount - The number of bars in the group
7
+ * @param gapSize - The desired gap size between bars
8
+ * @returns The amount to reduce each bar's size by, or 0 if there's only one bar
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * // For 3 bars with 12px gaps, each bar should be reduced by 8px
13
+ * const adjustment = getBarSizeAdjustment(3, 12);
14
+ *
15
+ * // Single bar needs no adjustment
16
+ * const singleBarAdjustment = getBarSizeAdjustment(1, 10);
17
+ * ```
18
+ */
19
+ export function getBarSizeAdjustment(barCount, gapSize) {
20
+ if (barCount <= 1) {
21
+ return 0;
22
+ }
23
+ return gapSize * (barCount - 1) / barCount;
24
+ }