@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,277 @@
1
+ import { scaleBand, scaleLinear, scaleLog } from 'd3-scale';
2
+
3
+ // https://d3js.org/d3-scale - ideal next scale would be time
4
+
5
+ export const isCategoricalScale = scale => {
6
+ return scale !== undefined && 'bandwidth' in scale && typeof scale.bandwidth === 'function';
7
+ };
8
+ export const isNumericScale = scale => {
9
+ return scale !== undefined && !isCategoricalScale(scale);
10
+ };
11
+
12
+ /**
13
+ * Type guard to check if a scale is logarithmic.
14
+ */
15
+ export const isLogScale = scale => {
16
+ return scale !== undefined && 'base' in scale && typeof scale.base === 'function';
17
+ };
18
+
19
+ /**
20
+ * Type guard to check if a scale is a SerializableScale.
21
+ * This can be used in worklets to differentiate between scale objects and scale functions.
22
+ */
23
+ export const isSerializableScale = scale => {
24
+ 'worklet';
25
+
26
+ return typeof scale === 'object' && scale !== null && 'type' in scale && 'domain' in scale && 'range' in scale;
27
+ };
28
+
29
+ /**
30
+ * Create a numeric scale (linear or logarithmic)
31
+ * @returns A numeric scale function
32
+ */
33
+ export const getNumericScale = _ref => {
34
+ let {
35
+ scaleType,
36
+ domain,
37
+ range
38
+ } = _ref;
39
+ const scale = scaleType === 'log' ? scaleLog() : scaleLinear();
40
+ return scale.domain([domain.min, domain.max]).range([range.min, range.max]);
41
+ };
42
+
43
+ /**
44
+ * Create a categorical scale (band)
45
+ * @returns A categorical scale function
46
+ */
47
+ export const getCategoricalScale = _ref2 => {
48
+ let {
49
+ domain,
50
+ range,
51
+ padding = 0.1
52
+ } = _ref2;
53
+ const domainArray = Array.from({
54
+ length: domain.max - domain.min + 1
55
+ }, (_, i) => i);
56
+ const scale = scaleBand().domain(domainArray).range([range.min, range.max]).padding(padding);
57
+ return scale;
58
+ };
59
+
60
+ /**
61
+ * Convert a D3 scale to a serializable scale configuration that can be used in worklets
62
+ */
63
+ export function convertToSerializableScale(d3Scale) {
64
+ if (!d3Scale) return undefined;
65
+ const domain = d3Scale.domain();
66
+ const range = d3Scale.range();
67
+
68
+ // Handle band/categorical scales
69
+ if (isCategoricalScale(d3Scale)) {
70
+ var _step;
71
+ const bandScale = d3Scale;
72
+ const bandwidth = bandScale.bandwidth();
73
+ const step = (_step = bandScale.step == null ? void 0 : bandScale.step()) != null ? _step : (range[1] - range[0]) / domain.length;
74
+ return {
75
+ type: 'band',
76
+ domain: [domain[0], domain[domain.length - 1]],
77
+ range: [range[0], range[range.length - 1]],
78
+ bandwidth,
79
+ step
80
+ };
81
+ }
82
+
83
+ // Handle log scales
84
+ if (isLogScale(d3Scale)) {
85
+ var _base;
86
+ const logScale = d3Scale;
87
+ // D3 log scales default to base 10
88
+ const base = (_base = logScale.base == null ? void 0 : logScale.base()) != null ? _base : 10;
89
+ return {
90
+ type: 'log',
91
+ domain: [domain[0], domain[domain.length - 1]],
92
+ range: [range[0], range[range.length - 1]],
93
+ base
94
+ };
95
+ }
96
+
97
+ // Handle linear scales (default)
98
+ if (isNumericScale(d3Scale)) {
99
+ return {
100
+ type: 'linear',
101
+ domain: [domain[0], domain[domain.length - 1]],
102
+ range: [range[0], range[range.length - 1]]
103
+ };
104
+ }
105
+ return undefined;
106
+ }
107
+
108
+ /**
109
+ * Convert multiple D3 scales to serializable scales
110
+ */
111
+ export function convertScalesToSerializableScales(xScale, yScales) {
112
+ const result = {
113
+ yScales: {}
114
+ };
115
+
116
+ // Convert X scale
117
+ if (xScale) {
118
+ result.xScale = convertToSerializableScale(xScale);
119
+ }
120
+
121
+ // Convert Y scales
122
+ if (yScales) {
123
+ yScales.forEach((scale, id) => {
124
+ const serializableScale = convertToSerializableScale(scale);
125
+ if (serializableScale) {
126
+ result.yScales[id] = serializableScale;
127
+ }
128
+ });
129
+ }
130
+ return result;
131
+ }
132
+
133
+ /**
134
+ * Serializable scale implementations based on D3 scale concepts.
135
+ * These scales can be used directly on the UI thread in Reanimated worklets.
136
+ */
137
+
138
+ /**
139
+ * Serializable linear scale function
140
+ */
141
+ export function applyLinearScale(value, scale) {
142
+ 'worklet';
143
+
144
+ const [d0, d1] = scale.domain;
145
+ const [r0, r1] = scale.range;
146
+ const t = (value - d0) / (d1 - d0); // normalize to [0, 1]
147
+ return r0 + t * (r1 - r0); // interpolate in range
148
+ }
149
+
150
+ /**
151
+ * Serializable log scale function
152
+ */
153
+ export function applyLogScale(value, scale) {
154
+ 'worklet';
155
+
156
+ var _scale$base;
157
+ const [d0, d1] = scale.domain;
158
+ const [r0, r1] = scale.range;
159
+ const base = (_scale$base = scale.base) != null ? _scale$base : 10;
160
+ const logBase = base === 10 ? Math.log10 : base === Math.E ? Math.log : x => Math.log(x) / Math.log(base);
161
+ const t = (logBase(value) - logBase(d0)) / (logBase(d1) - logBase(d0));
162
+ return r0 + t * (r1 - r0);
163
+ }
164
+
165
+ /**
166
+ * Serializable band scale function
167
+ */
168
+ export function applyBandScale(value, scale) {
169
+ 'worklet';
170
+
171
+ const [r0, r1] = scale.range;
172
+ const [domainMin, domainMax] = scale.domain;
173
+ const n = domainMax - domainMin + 1;
174
+ const step = scale.step;
175
+ const index = value - domainMin;
176
+ if (index < 0 || index >= n) {
177
+ return r0;
178
+ }
179
+ const paddingOffset = step - scale.bandwidth;
180
+ const bandStart = r0 + step * index + paddingOffset;
181
+ return bandStart;
182
+ }
183
+
184
+ /**
185
+ * Universal serializable scale function that handles any scale type
186
+ */
187
+ export function applySerializableScale(value, scale) {
188
+ 'worklet';
189
+
190
+ switch (scale.type) {
191
+ case 'linear':
192
+ return applyLinearScale(value, scale);
193
+ case 'log':
194
+ return applyLogScale(value, scale);
195
+ case 'band':
196
+ return applyBandScale(value, scale);
197
+ default:
198
+ return 0;
199
+ }
200
+ }
201
+
202
+ /**
203
+ * Get bandwidth for band scales (returns 0 for other scale types)
204
+ */
205
+ export function getScaleBandwidth(scale) {
206
+ 'worklet';
207
+
208
+ if (scale.type === 'band') {
209
+ return scale.bandwidth;
210
+ }
211
+ return 0;
212
+ }
213
+
214
+ /**
215
+ * Invert a linear scale - convert from range value back to domain value
216
+ */
217
+ export function invertLinearScale(rangeValue, scale) {
218
+ 'worklet';
219
+
220
+ const [d0, d1] = scale.domain;
221
+ const [r0, r1] = scale.range;
222
+ const t = (rangeValue - r0) / (r1 - r0); // normalize to [0, 1]
223
+ return d0 + t * (d1 - d0); // interpolate in domain
224
+ }
225
+
226
+ /**
227
+ * Invert a log scale - convert from range value back to domain value
228
+ */
229
+ export function invertLogScale(rangeValue, scale) {
230
+ 'worklet';
231
+
232
+ var _scale$base2;
233
+ const [d0, d1] = scale.domain;
234
+ const [r0, r1] = scale.range;
235
+ const base = (_scale$base2 = scale.base) != null ? _scale$base2 : 10;
236
+ const logBase = base === 10 ? Math.log10 : base === Math.E ? Math.log : x => Math.log(x) / Math.log(base);
237
+ const t = (rangeValue - r0) / (r1 - r0); // normalize to [0, 1]
238
+ const logValue = logBase(d0) + t * (logBase(d1) - logBase(d0));
239
+
240
+ // Convert back from log space
241
+ return base === 10 ? Math.pow(10, logValue) : base === Math.E ? Math.exp(logValue) : Math.pow(base, logValue);
242
+ }
243
+
244
+ /**
245
+ * Invert a band scale - convert from range value back to domain index
246
+ */
247
+ export function invertBandScale(rangeValue, scale) {
248
+ 'worklet';
249
+
250
+ const [r0, r1] = scale.range;
251
+ const n = scale.domain.length;
252
+ const step = (r1 - r0) / n;
253
+
254
+ // Find which band this range value falls into
255
+ const index = Math.floor((rangeValue - r0) / step);
256
+
257
+ // Clamp to valid range
258
+ return Math.max(0, Math.min(index, n - 1));
259
+ }
260
+
261
+ /**
262
+ * Universal serializable scale invert function that handles any scale type
263
+ */
264
+ export function invertSerializableScale(rangeValue, scale) {
265
+ 'worklet';
266
+
267
+ switch (scale.type) {
268
+ case 'linear':
269
+ return invertLinearScale(rangeValue, scale);
270
+ case 'log':
271
+ return invertLogScale(rangeValue, scale);
272
+ case 'band':
273
+ return invertBandScale(rangeValue, scale);
274
+ default:
275
+ return 0;
276
+ }
277
+ }
@@ -0,0 +1,139 @@
1
+ /**
2
+ * Determines which side (left/right) to place scrubber labels based on available space.
3
+ * Prefers right side, switches to left when labels would overflow.
4
+ */
5
+ export const getLabelPosition = function (beaconX, maxLabelWidth, drawingArea, xOffset) {
6
+ 'worklet';
7
+
8
+ // any regular functions in ui thread must be marked with 'worklet'
9
+ if (xOffset === void 0) {
10
+ xOffset = 16;
11
+ }
12
+ if (drawingArea.width <= 0 || drawingArea.height <= 0) {
13
+ return 'right';
14
+ }
15
+ const availableRightSpace = drawingArea.x + drawingArea.width - beaconX;
16
+ const requiredSpace = maxLabelWidth + xOffset;
17
+ return requiredSpace <= availableRightSpace ? 'right' : 'left';
18
+ };
19
+ /**
20
+ * Calculates Y positions for all labels avoiding overlaps while maintaining order.
21
+ */
22
+ export const calculateLabelYPositions = (dimensions, drawingArea, labelHeight, minGap) => {
23
+ 'worklet';
24
+
25
+ if (dimensions.length === 0) {
26
+ return new Map();
27
+ }
28
+
29
+ // Sort by preferred Y values and create working labels
30
+ const sortedLabels = [...dimensions].sort((a, b) => a.preferredY - b.preferredY).map(dim => ({
31
+ seriesId: dim.seriesId,
32
+ preferredY: dim.preferredY,
33
+ finalY: dim.preferredY
34
+ }));
35
+
36
+ // Initial bounds fitting
37
+ const minY = drawingArea.y + labelHeight / 2;
38
+ const maxY = drawingArea.y + drawingArea.height - labelHeight / 2;
39
+ const requiredDistance = labelHeight + minGap;
40
+ for (const label of sortedLabels) {
41
+ // Clamp each label to the drawing area
42
+ label.finalY = Math.max(minY, Math.min(maxY, label.preferredY));
43
+ }
44
+
45
+ // First pass: push down any overlapping labels
46
+ for (let i = 1; i < sortedLabels.length; i++) {
47
+ const prev = sortedLabels[i - 1];
48
+ const current = sortedLabels[i];
49
+ const minAllowedY = prev.finalY + requiredDistance;
50
+ if (current.finalY < minAllowedY) {
51
+ current.finalY = minAllowedY;
52
+ }
53
+ }
54
+
55
+ // Find collision groups - groups of labels that are tightly packed (gap < minGap between them)
56
+ const collisionGroups = [];
57
+ let currentGroup = [sortedLabels[0]];
58
+ for (let i = 1; i < sortedLabels.length; i++) {
59
+ const prev = sortedLabels[i - 1];
60
+ const current = sortedLabels[i];
61
+ const gap = current.finalY - prev.finalY - labelHeight;
62
+ if (gap < minGap + 0.01) {
63
+ // Labels are touching or very close - part of same collision group
64
+ currentGroup.push(current);
65
+ } else {
66
+ // Gap is large enough - start new group
67
+ collisionGroups.push(currentGroup);
68
+ currentGroup = [current];
69
+ }
70
+ }
71
+ collisionGroups.push(currentGroup);
72
+
73
+ // Process each collision group - optimize positioning to minimize displacement
74
+ for (const group of collisionGroups) {
75
+ if (group.length === 1) {
76
+ // Single label, already at best position
77
+ continue;
78
+ }
79
+ const groupLastLabel = group[group.length - 1];
80
+ const groupFirstLabel = group[0];
81
+ const groupOverflow = groupLastLabel.finalY + labelHeight / 2 - (drawingArea.y + drawingArea.height);
82
+
83
+ // Calculate the ideal center point for this group
84
+ const groupPreferredCenter = group.reduce((sum, label) => sum + label.preferredY, 0) / group.length;
85
+ const groupTotalNeeded = group.length * labelHeight + (group.length - 1) * minGap;
86
+ if (groupOverflow <= 0) {
87
+ // Group fits, but let's center it better if possible
88
+ // Calculate how much we can shift up/down to center around preferred positions
89
+ const currentCenter = (groupFirstLabel.finalY + groupLastLabel.finalY) / 2;
90
+ const desiredShift = groupPreferredCenter - currentCenter;
91
+
92
+ // Calculate max shift in each direction
93
+ const maxShiftUp = groupFirstLabel.finalY - minY;
94
+ const maxShiftDown = maxY - groupLastLabel.finalY;
95
+
96
+ // Apply the shift, constrained by boundaries
97
+ const actualShift = Math.max(-maxShiftUp, Math.min(maxShiftDown, desiredShift));
98
+ if (Math.abs(actualShift) > 0.01) {
99
+ for (const label of group) {
100
+ label.finalY += actualShift;
101
+ }
102
+ }
103
+ } else {
104
+ // Group overflows - need to adjust
105
+ const groupStartY = groupFirstLabel.finalY - labelHeight / 2;
106
+ const availableSpace = drawingArea.y + drawingArea.height - groupStartY;
107
+ const maxShiftUp = groupFirstLabel.finalY - minY;
108
+ if (maxShiftUp >= groupOverflow) {
109
+ // Can shift entire group up to fit
110
+ for (const label of group) {
111
+ label.finalY -= groupOverflow;
112
+ }
113
+ } else if (groupTotalNeeded <= availableSpace) {
114
+ // Can't shift enough, but there's room - redistribute with proper spacing
115
+ let currentY = Math.max(minY, groupFirstLabel.finalY - maxShiftUp);
116
+ const gap = (availableSpace - group.length * labelHeight) / Math.max(1, group.length - 1);
117
+ for (const label of group) {
118
+ label.finalY = currentY;
119
+ currentY += labelHeight + gap;
120
+ }
121
+ } else {
122
+ // Not enough space even with compression - compress gaps and fit to bottom
123
+ const compressedGap = Math.max(1, (availableSpace - group.length * labelHeight) / Math.max(1, group.length - 1));
124
+ // Position so last label is at maxY
125
+ let currentY = maxY - (group.length - 1) * (labelHeight + compressedGap);
126
+ currentY = Math.max(minY, currentY);
127
+ for (const label of group) {
128
+ label.finalY = currentY;
129
+ currentY += labelHeight + compressedGap;
130
+ }
131
+ }
132
+ }
133
+ }
134
+ const result = new Map();
135
+ for (const label of sortedLabels) {
136
+ result.set(label.seriesId, label.finalY);
137
+ }
138
+ return result;
139
+ };
@@ -0,0 +1,185 @@
1
+ import { useEffect, useMemo, useRef } from 'react';
2
+ import { useAnimatedReaction, useSharedValue, withSpring, withTiming } from 'react-native-reanimated';
3
+ import { notifyChange, Skia } from '@shopify/react-native-skia';
4
+ import { interpolatePath } from 'd3-interpolate-path';
5
+
6
+ /**
7
+ * Transition for animations.
8
+ * Supports timing and spring animation types.
9
+ * Used for paths, positions, opacity, and any other animated properties.
10
+ *
11
+ * @example
12
+ * // Spring animation
13
+ * { type: 'spring', damping: 10, stiffness: 100 }
14
+ *
15
+ * @example
16
+ * // Timing animation
17
+ * { type: 'timing', duration: 500, easing: Easing.inOut(Easing.ease) }
18
+ */
19
+
20
+ /**
21
+ * Default transition configuration used across all chart components.
22
+ */
23
+ export const defaultTransition = {
24
+ type: 'spring',
25
+ stiffness: 900,
26
+ damping: 120
27
+ };
28
+
29
+ /**
30
+ * Duration in milliseconds for accessory elements to fade in.
31
+ */
32
+ export const accessoryFadeTransitionDuration = 150;
33
+
34
+ /**
35
+ * Delay in milliseconds before accessory elements fade in.
36
+ */
37
+ export const accessoryFadeTransitionDelay = 350;
38
+
39
+ /**
40
+ * Custom hook that uses d3-interpolate-path for more robust path interpolation.
41
+ * then use Skia's native interpolation in the worklet.
42
+ *
43
+ * @param progress - Shared value between 0 and 1
44
+ * @param fromPath - Starting path as SVG string
45
+ * @param toPath - Ending path as SVG string
46
+ * @returns Interpolated SkPath as a shared value
47
+ */
48
+ export const useD3PathInterpolation = (progress, fromPath, toPath) => {
49
+ // Pre-compute intermediate paths on JS thread using d3-interpolate-path
50
+ const {
51
+ fromSkiaPath,
52
+ i0,
53
+ i1,
54
+ toSkiaPath
55
+ } = useMemo(() => {
56
+ var _Skia$Path$MakeFromSV, _Skia$Path$MakeFromSV2, _Skia$Path$MakeFromSV3, _Skia$Path$MakeFromSV4;
57
+ const pathInterpolator = interpolatePath(fromPath, toPath);
58
+ const d = 1e-3;
59
+ return {
60
+ fromSkiaPath: (_Skia$Path$MakeFromSV = Skia.Path.MakeFromSVGString(fromPath)) != null ? _Skia$Path$MakeFromSV : Skia.Path.Make(),
61
+ i0: (_Skia$Path$MakeFromSV2 = Skia.Path.MakeFromSVGString(pathInterpolator(d))) != null ? _Skia$Path$MakeFromSV2 : Skia.Path.Make(),
62
+ i1: (_Skia$Path$MakeFromSV3 = Skia.Path.MakeFromSVGString(pathInterpolator(1 - d))) != null ? _Skia$Path$MakeFromSV3 : Skia.Path.Make(),
63
+ toSkiaPath: (_Skia$Path$MakeFromSV4 = Skia.Path.MakeFromSVGString(toPath)) != null ? _Skia$Path$MakeFromSV4 : Skia.Path.Make()
64
+ };
65
+ }, [fromPath, toPath]);
66
+ const result = useSharedValue(fromSkiaPath);
67
+ useAnimatedReaction(() => progress.value, t => {
68
+ 'worklet';
69
+
70
+ var _i1$interpolate;
71
+ result.value = (_i1$interpolate = i1.interpolate(i0, t)) != null ? _i1$interpolate : toSkiaPath;
72
+ notifyChange(result);
73
+ }, [fromSkiaPath, i0, i1, toSkiaPath]);
74
+ return result;
75
+ };
76
+
77
+ // Interpolator and useInterpolator are brought over from non exported code in @shopify/react-native-skia
78
+ /**
79
+ * @worklet
80
+ */
81
+
82
+ export const useInterpolator = (factory, value, interpolator, input, output, options) => {
83
+ // eslint-disable-next-line react-hooks/exhaustive-deps
84
+ const init = useMemo(() => factory(), []);
85
+ const result = useSharedValue(init);
86
+ useAnimatedReaction(() => value.value, val => {
87
+ result.value = interpolator(val, input, output, options, result.value);
88
+ notifyChange(result);
89
+ }, [input, output, options]);
90
+ return result;
91
+ };
92
+
93
+ /**
94
+ * Builds a react-native-reanimated animation based on the configuration.
95
+ *
96
+ * @param targetValue - The target value to animate to
97
+ * @param config - The transition configuration
98
+ * @returns The animation value to assign to a shared value
99
+ *
100
+ * @example
101
+ * // Use directly for animation
102
+ * progress.value = 0;
103
+ * progress.value = buildTransition(1, { type: 'spring', damping: 10, stiffness: 100 });
104
+ *
105
+ * @example
106
+ * // Coordinate animations
107
+ * animatedX.value = buildTransition(100, { type: 'spring', damping: 10, stiffness: 100 });
108
+ * animatedY.value = buildTransition(200, { type: 'spring', damping: 10, stiffness: 100 });
109
+ *
110
+ * @example
111
+ * // Timing animation
112
+ * progress.value = buildTransition(1, { type: 'timing', duration: 500 });
113
+ */
114
+ export const buildTransition = (targetValue, transition) => {
115
+ 'worklet';
116
+
117
+ switch (transition.type) {
118
+ case 'timing':
119
+ {
120
+ return withTiming(targetValue, transition);
121
+ }
122
+ case 'spring':
123
+ {
124
+ return withSpring(targetValue, transition);
125
+ }
126
+ default:
127
+ {
128
+ // Fallback to default transition config
129
+ return withSpring(targetValue, defaultTransition);
130
+ }
131
+ }
132
+ };
133
+
134
+ /**
135
+ * Hook for path animation state and transitions.
136
+ *
137
+ * @param currentPath - Current target path to animate to
138
+ * @param initialPath - Initial path for enter animation. When provided, the first animation will go from initialPath to currentPath.
139
+ * @param transition - Transition configuration
140
+ * @returns Animated SkPath as a shared value
141
+ *
142
+ * @example
143
+ * // Simple path transition
144
+ * const path = usePathTransition({
145
+ * currentPath: d ?? '',
146
+ * animate: shouldAnimate,
147
+ * transition: { type: 'timing', duration: 3000 }
148
+ * });
149
+ *
150
+ * @example
151
+ * // Enter animation with different initial config (like DefaultBar)
152
+ * const path = usePathTransition({
153
+ * currentPath: targetPath,
154
+ * initialPath: baselinePath,
155
+ * animate: true,
156
+ * transition: { type: 'timing', duration: 300 }
157
+ * });
158
+ */
159
+ export const usePathTransition = _ref => {
160
+ let {
161
+ currentPath,
162
+ initialPath,
163
+ transition = defaultTransition
164
+ } = _ref;
165
+ // Track the previous path - updated in useEffect AFTER render,
166
+ // so during render it naturally holds the "from" path value
167
+ const previousPathRef = useRef(initialPath != null ? initialPath : currentPath);
168
+ const progress = useSharedValue(0);
169
+
170
+ // During render: previousPathRef still has old value, currentPath is new
171
+ const fromPath = previousPathRef.current;
172
+ const toPath = currentPath;
173
+ useEffect(() => {
174
+ const shouldAnimate = previousPathRef.current !== currentPath;
175
+ if (shouldAnimate) {
176
+ // Update ref for next path change (happens after this render)
177
+ previousPathRef.current = currentPath;
178
+
179
+ // Animate from old path to new path
180
+ progress.value = 0;
181
+ progress.value = buildTransition(1, transition);
182
+ }
183
+ }, [currentPath, transition, progress]);
184
+ return useD3PathInterpolation(progress, fromPath, toPath);
185
+ };
package/esm/index.js CHANGED
@@ -1 +1,4 @@
1
- export * from './sparkline';
1
+ // codegen:start {preset: barrel, include: ./*/index.ts}
2
+ export * from './chart';
3
+ export * from './sparkline';
4
+ // codegen:end