@coinbase/cds-web-visualization 3.3.2 → 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 (212) hide show
  1. package/CHANGELOG.md +50 -2
  2. package/dts/chart/CartesianChart.d.ts +72 -0
  3. package/dts/chart/CartesianChart.d.ts.map +1 -0
  4. package/dts/chart/ChartProvider.d.ts +6 -0
  5. package/dts/chart/ChartProvider.d.ts.map +1 -0
  6. package/dts/chart/Path.d.ts +54 -0
  7. package/dts/chart/Path.d.ts.map +1 -0
  8. package/dts/chart/PeriodSelector.d.ts +57 -0
  9. package/dts/chart/PeriodSelector.d.ts.map +1 -0
  10. package/dts/chart/area/Area.d.ts +78 -0
  11. package/dts/chart/area/Area.d.ts.map +1 -0
  12. package/dts/chart/area/AreaChart.d.ts +79 -0
  13. package/dts/chart/area/AreaChart.d.ts.map +1 -0
  14. package/dts/chart/area/DottedArea.d.ts +45 -0
  15. package/dts/chart/area/DottedArea.d.ts.map +1 -0
  16. package/dts/chart/area/GradientArea.d.ts +39 -0
  17. package/dts/chart/area/GradientArea.d.ts.map +1 -0
  18. package/dts/chart/area/SolidArea.d.ts +23 -0
  19. package/dts/chart/area/SolidArea.d.ts.map +1 -0
  20. package/dts/chart/area/index.d.ts +6 -0
  21. package/dts/chart/area/index.d.ts.map +1 -0
  22. package/dts/chart/axis/Axis.d.ts +255 -0
  23. package/dts/chart/axis/Axis.d.ts.map +1 -0
  24. package/dts/chart/axis/DefaultAxisTickLabel.d.ts +8 -0
  25. package/dts/chart/axis/DefaultAxisTickLabel.d.ts.map +1 -0
  26. package/dts/chart/axis/XAxis.d.ts +16 -0
  27. package/dts/chart/axis/XAxis.d.ts.map +1 -0
  28. package/dts/chart/axis/YAxis.d.ts +21 -0
  29. package/dts/chart/axis/YAxis.d.ts.map +1 -0
  30. package/dts/chart/axis/index.d.ts +5 -0
  31. package/dts/chart/axis/index.d.ts.map +1 -0
  32. package/dts/chart/bar/Bar.d.ts +94 -0
  33. package/dts/chart/bar/Bar.d.ts.map +1 -0
  34. package/dts/chart/bar/BarChart.d.ts +62 -0
  35. package/dts/chart/bar/BarChart.d.ts.map +1 -0
  36. package/dts/chart/bar/BarPlot.d.ts +30 -0
  37. package/dts/chart/bar/BarPlot.d.ts.map +1 -0
  38. package/dts/chart/bar/BarStack.d.ts +103 -0
  39. package/dts/chart/bar/BarStack.d.ts.map +1 -0
  40. package/dts/chart/bar/BarStackGroup.d.ts +36 -0
  41. package/dts/chart/bar/BarStackGroup.d.ts.map +1 -0
  42. package/dts/chart/bar/DefaultBar.d.ts +17 -0
  43. package/dts/chart/bar/DefaultBar.d.ts.map +1 -0
  44. package/dts/chart/bar/DefaultBarStack.d.ts +16 -0
  45. package/dts/chart/bar/DefaultBarStack.d.ts.map +1 -0
  46. package/dts/chart/bar/index.d.ts +8 -0
  47. package/dts/chart/bar/index.d.ts.map +1 -0
  48. package/dts/chart/gradient/Gradient.d.ts +35 -0
  49. package/dts/chart/gradient/Gradient.d.ts.map +1 -0
  50. package/dts/chart/gradient/index.d.ts +2 -0
  51. package/dts/chart/gradient/index.d.ts.map +1 -0
  52. package/dts/chart/index.d.ts +14 -0
  53. package/dts/chart/index.d.ts.map +1 -0
  54. package/dts/chart/line/DefaultReferenceLineLabel.d.ts +9 -0
  55. package/dts/chart/line/DefaultReferenceLineLabel.d.ts.map +1 -0
  56. package/dts/chart/line/DottedLine.d.ts +26 -0
  57. package/dts/chart/line/DottedLine.d.ts.map +1 -0
  58. package/dts/chart/line/Line.d.ts +122 -0
  59. package/dts/chart/line/Line.d.ts.map +1 -0
  60. package/dts/chart/line/LineChart.d.ts +77 -0
  61. package/dts/chart/line/LineChart.d.ts.map +1 -0
  62. package/dts/chart/line/ReferenceLine.d.ts +178 -0
  63. package/dts/chart/line/ReferenceLine.d.ts.map +1 -0
  64. package/dts/chart/line/SolidLine.d.ts +25 -0
  65. package/dts/chart/line/SolidLine.d.ts.map +1 -0
  66. package/dts/chart/line/index.d.ts +7 -0
  67. package/dts/chart/line/index.d.ts.map +1 -0
  68. package/dts/chart/point/DefaultPointLabel.d.ts +10 -0
  69. package/dts/chart/point/DefaultPointLabel.d.ts.map +1 -0
  70. package/dts/chart/point/Point.d.ts +201 -0
  71. package/dts/chart/point/Point.d.ts.map +1 -0
  72. package/dts/chart/point/index.d.ts +3 -0
  73. package/dts/chart/point/index.d.ts.map +1 -0
  74. package/dts/chart/scrubber/DefaultScrubberBeacon.d.ts +24 -0
  75. package/dts/chart/scrubber/DefaultScrubberBeacon.d.ts.map +1 -0
  76. package/dts/chart/scrubber/DefaultScrubberBeaconLabel.d.ts +12 -0
  77. package/dts/chart/scrubber/DefaultScrubberBeaconLabel.d.ts.map +1 -0
  78. package/dts/chart/scrubber/DefaultScrubberLabel.d.ts +10 -0
  79. package/dts/chart/scrubber/DefaultScrubberLabel.d.ts.map +1 -0
  80. package/dts/chart/scrubber/Scrubber.d.ts +290 -0
  81. package/dts/chart/scrubber/Scrubber.d.ts.map +1 -0
  82. package/dts/chart/scrubber/ScrubberBeaconGroup.d.ts +70 -0
  83. package/dts/chart/scrubber/ScrubberBeaconGroup.d.ts.map +1 -0
  84. package/dts/chart/scrubber/ScrubberBeaconLabelGroup.d.ts +32 -0
  85. package/dts/chart/scrubber/ScrubberBeaconLabelGroup.d.ts.map +1 -0
  86. package/dts/chart/scrubber/ScrubberProvider.d.ts +17 -0
  87. package/dts/chart/scrubber/ScrubberProvider.d.ts.map +1 -0
  88. package/dts/chart/scrubber/index.d.ts +5 -0
  89. package/dts/chart/scrubber/index.d.ts.map +1 -0
  90. package/dts/chart/text/ChartText.d.ts +117 -0
  91. package/dts/chart/text/ChartText.d.ts.map +1 -0
  92. package/dts/chart/text/ChartTextGroup.d.ts +61 -0
  93. package/dts/chart/text/ChartTextGroup.d.ts.map +1 -0
  94. package/dts/chart/text/index.d.ts +3 -0
  95. package/dts/chart/text/index.d.ts.map +1 -0
  96. package/dts/chart/utils/axis.d.ts +342 -0
  97. package/dts/chart/utils/axis.d.ts.map +1 -0
  98. package/dts/chart/utils/bar.d.ts +20 -0
  99. package/dts/chart/utils/bar.d.ts.map +1 -0
  100. package/dts/chart/utils/chart.d.ts +117 -0
  101. package/dts/chart/utils/chart.d.ts.map +1 -0
  102. package/dts/chart/utils/context.d.ts +101 -0
  103. package/dts/chart/utils/context.d.ts.map +1 -0
  104. package/dts/chart/utils/gradient.d.ts +104 -0
  105. package/dts/chart/utils/gradient.d.ts.map +1 -0
  106. package/dts/chart/utils/index.d.ts +12 -0
  107. package/dts/chart/utils/index.d.ts.map +1 -0
  108. package/dts/chart/utils/interpolate.d.ts +112 -0
  109. package/dts/chart/utils/interpolate.d.ts.map +1 -0
  110. package/dts/chart/utils/path.d.ts +130 -0
  111. package/dts/chart/utils/path.d.ts.map +1 -0
  112. package/dts/chart/utils/point.d.ts +104 -0
  113. package/dts/chart/utils/point.d.ts.map +1 -0
  114. package/dts/chart/utils/scale.d.ts +43 -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 +65 -0
  119. package/dts/chart/utils/transition.d.ts.map +1 -0
  120. package/dts/index.d.ts +1 -0
  121. package/dts/index.d.ts.map +1 -1
  122. package/dts/sparkline/Sparkline.d.ts +44 -9
  123. package/dts/sparkline/Sparkline.d.ts.map +1 -1
  124. package/dts/sparkline/SparklineArea.d.ts +4 -0
  125. package/dts/sparkline/SparklineArea.d.ts.map +1 -1
  126. package/dts/sparkline/SparklineAreaPattern.d.ts +5 -0
  127. package/dts/sparkline/SparklineAreaPattern.d.ts.map +1 -1
  128. package/dts/sparkline/SparklineGradient.d.ts +5 -0
  129. package/dts/sparkline/SparklineGradient.d.ts.map +1 -1
  130. package/dts/sparkline/generateSparklineWithId.d.ts +1 -0
  131. package/dts/sparkline/generateSparklineWithId.d.ts.map +1 -1
  132. package/dts/sparkline/sparkline-interactive/SparklineInteractive.d.ts +9 -0
  133. package/dts/sparkline/sparkline-interactive/SparklineInteractive.d.ts.map +1 -1
  134. package/dts/sparkline/sparkline-interactive/SparklineInteractiveAnimatedPath.d.ts +3 -0
  135. package/dts/sparkline/sparkline-interactive/SparklineInteractiveAnimatedPath.d.ts.map +1 -1
  136. package/dts/sparkline/sparkline-interactive/SparklineInteractivePaths.d.ts +2 -1
  137. package/dts/sparkline/sparkline-interactive/SparklineInteractivePaths.d.ts.map +1 -1
  138. package/esm/chart/CartesianChart.css +1 -0
  139. package/esm/chart/CartesianChart.js +313 -0
  140. package/esm/chart/ChartProvider.js +10 -0
  141. package/esm/chart/Path.js +95 -0
  142. package/esm/chart/PeriodSelector.css +1 -0
  143. package/esm/chart/PeriodSelector.js +112 -0
  144. package/esm/chart/area/Area.js +75 -0
  145. package/esm/chart/area/AreaChart.js +173 -0
  146. package/esm/chart/area/DottedArea.js +87 -0
  147. package/esm/chart/area/GradientArea.js +65 -0
  148. package/esm/chart/area/SolidArea.js +47 -0
  149. package/esm/chart/area/index.js +7 -0
  150. package/esm/chart/axis/Axis.js +25 -0
  151. package/esm/chart/axis/DefaultAxisTickLabel.js +15 -0
  152. package/esm/chart/axis/XAxis.css +2 -0
  153. package/esm/chart/axis/XAxis.js +219 -0
  154. package/esm/chart/axis/YAxis.css +2 -0
  155. package/esm/chart/axis/YAxis.js +214 -0
  156. package/esm/chart/axis/index.js +6 -0
  157. package/esm/chart/bar/Bar.js +61 -0
  158. package/esm/chart/bar/BarChart.js +130 -0
  159. package/esm/chart/bar/BarPlot.js +97 -0
  160. package/esm/chart/bar/BarStack.js +561 -0
  161. package/esm/chart/bar/BarStackGroup.js +86 -0
  162. package/esm/chart/bar/DefaultBar.js +61 -0
  163. package/esm/chart/bar/DefaultBarStack.js +58 -0
  164. package/esm/chart/bar/index.js +9 -0
  165. package/esm/chart/gradient/Gradient.js +104 -0
  166. package/esm/chart/gradient/index.js +1 -0
  167. package/esm/chart/index.js +15 -0
  168. package/esm/chart/line/DefaultReferenceLineLabel.js +81 -0
  169. package/esm/chart/line/DottedLine.js +59 -0
  170. package/esm/chart/line/Line.js +185 -0
  171. package/esm/chart/line/LineChart.js +132 -0
  172. package/esm/chart/line/ReferenceLine.js +140 -0
  173. package/esm/chart/line/SolidLine.js +55 -0
  174. package/esm/chart/line/index.js +8 -0
  175. package/esm/chart/point/DefaultPointLabel.js +44 -0
  176. package/esm/chart/point/Point.css +2 -0
  177. package/esm/chart/point/Point.js +180 -0
  178. package/esm/chart/point/index.js +2 -0
  179. package/esm/chart/scrubber/DefaultScrubberBeacon.js +155 -0
  180. package/esm/chart/scrubber/DefaultScrubberBeaconLabel.js +46 -0
  181. package/esm/chart/scrubber/DefaultScrubberLabel.js +30 -0
  182. package/esm/chart/scrubber/Scrubber.js +189 -0
  183. package/esm/chart/scrubber/ScrubberBeaconGroup.js +166 -0
  184. package/esm/chart/scrubber/ScrubberBeaconLabelGroup.js +186 -0
  185. package/esm/chart/scrubber/ScrubberProvider.js +228 -0
  186. package/esm/chart/scrubber/index.js +4 -0
  187. package/esm/chart/text/ChartText.js +230 -0
  188. package/esm/chart/text/ChartTextGroup.js +227 -0
  189. package/esm/chart/text/index.js +4 -0
  190. package/esm/chart/utils/axis.js +593 -0
  191. package/esm/chart/utils/bar.js +24 -0
  192. package/esm/chart/utils/chart.js +255 -0
  193. package/esm/chart/utils/context.js +15 -0
  194. package/esm/chart/utils/gradient.js +257 -0
  195. package/esm/chart/utils/index.js +13 -0
  196. package/esm/chart/utils/interpolate.js +644 -0
  197. package/esm/chart/utils/path.js +227 -0
  198. package/esm/chart/utils/point.js +187 -0
  199. package/esm/chart/utils/scale.js +48 -0
  200. package/esm/chart/utils/scrubber.js +132 -0
  201. package/esm/chart/utils/transition.js +111 -0
  202. package/esm/index.js +4 -1
  203. package/esm/sparkline/Sparkline.js +129 -15
  204. package/esm/sparkline/SparklineArea.js +7 -2
  205. package/esm/sparkline/SparklineAreaPattern.js +4 -2
  206. package/esm/sparkline/SparklineGradient.js +16 -58
  207. package/esm/sparkline/generateSparklineWithId.js +3 -2
  208. package/esm/sparkline/sparkline-interactive/SparklineInteractive.js +5 -1
  209. package/esm/sparkline/sparkline-interactive/SparklineInteractiveAnimatedPath.js +5 -2
  210. package/esm/sparkline/sparkline-interactive/SparklineInteractiveMarkerDates.js +1 -1
  211. package/esm/sparkline/sparkline-interactive/SparklineInteractivePaths.js +4 -0
  212. package/package.json +13 -9
@@ -0,0 +1,313 @@
1
+ const _excluded = ["series", "children", "animate", "xAxis", "yAxis", "inset", "enableScrubbing", "onScrubberPositionChange", "width", "height", "className", "classNames", "style", "styles"];
2
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
3
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
4
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
5
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
6
+ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
7
+ function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
8
+ 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; }
9
+ import React, { forwardRef, memo, useCallback, useMemo, useRef } from 'react';
10
+ import { cx } from '@coinbase/cds-web';
11
+ import { useDimensions } from '@coinbase/cds-web/hooks/useDimensions';
12
+ import { Box } from '@coinbase/cds-web/layout';
13
+ import { ScrubberProvider } from './scrubber/ScrubberProvider';
14
+ import { CartesianChartProvider } from './ChartProvider';
15
+ import { defaultAxisId, defaultChartInset, getAxisConfig, getAxisDomain, getAxisRange, getAxisScale, getChartInset, getStackedSeriesData as calculateStackedSeriesData, useTotalAxisPadding } from './utils';
16
+ import { jsx as _jsx } from "react/jsx-runtime";
17
+ const focusStylesCss = "cds-focusStylesCss-f4oy7ru";
18
+ export const CartesianChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) => {
19
+ let {
20
+ series,
21
+ children,
22
+ animate = true,
23
+ xAxis: xAxisConfigProp,
24
+ yAxis: yAxisConfigProp,
25
+ inset,
26
+ enableScrubbing,
27
+ onScrubberPositionChange,
28
+ width = '100%',
29
+ height = '100%',
30
+ className,
31
+ classNames,
32
+ style,
33
+ styles
34
+ } = _ref,
35
+ props = _objectWithoutProperties(_ref, _excluded);
36
+ const {
37
+ observe,
38
+ width: chartWidth,
39
+ height: chartHeight
40
+ } = useDimensions();
41
+ const svgRef = useRef(null);
42
+ const calculatedInset = useMemo(() => getChartInset(inset, defaultChartInset), [inset]);
43
+
44
+ // Axis configs store the properties of each axis, such as id, scale type, domain limit, etc.
45
+ // We only support 1 x axis but allow for multiple y axes.
46
+ const xAxisConfig = useMemo(() => getAxisConfig('x', xAxisConfigProp)[0], [xAxisConfigProp]);
47
+ const yAxisConfig = useMemo(() => getAxisConfig('y', yAxisConfigProp), [yAxisConfigProp]);
48
+ const {
49
+ renderedAxes,
50
+ registerAxis,
51
+ unregisterAxis,
52
+ axisPadding
53
+ } = useTotalAxisPadding();
54
+ const chartRect = useMemo(() => {
55
+ if (chartWidth <= 0 || chartHeight <= 0) return {
56
+ x: 0,
57
+ y: 0,
58
+ width: 0,
59
+ height: 0
60
+ };
61
+ const totalInset = {
62
+ top: calculatedInset.top + axisPadding.top,
63
+ right: calculatedInset.right + axisPadding.right,
64
+ bottom: calculatedInset.bottom + axisPadding.bottom,
65
+ left: calculatedInset.left + axisPadding.left
66
+ };
67
+ const availableWidth = chartWidth - totalInset.left - totalInset.right;
68
+ const availableHeight = chartHeight - totalInset.top - totalInset.bottom;
69
+ return {
70
+ x: totalInset.left,
71
+ y: totalInset.top,
72
+ width: availableWidth > 0 ? availableWidth : 0,
73
+ height: availableHeight > 0 ? availableHeight : 0
74
+ };
75
+ }, [chartHeight, chartWidth, calculatedInset, axisPadding]);
76
+ const {
77
+ xAxis,
78
+ xScale
79
+ } = useMemo(() => {
80
+ if (!chartRect || chartRect.width <= 0 || chartRect.height <= 0) return {
81
+ xAxis: undefined,
82
+ xScale: undefined
83
+ };
84
+ const domain = getAxisDomain(xAxisConfig, series !== null && series !== void 0 ? series : [], 'x');
85
+ const range = getAxisRange(xAxisConfig, chartRect, 'x');
86
+ const axisConfig = {
87
+ scaleType: xAxisConfig.scaleType,
88
+ domain,
89
+ range,
90
+ data: xAxisConfig.data,
91
+ categoryPadding: xAxisConfig.categoryPadding,
92
+ domainLimit: xAxisConfig.domainLimit
93
+ };
94
+
95
+ // Create the scale
96
+ const scale = getAxisScale({
97
+ config: axisConfig,
98
+ type: 'x',
99
+ range: axisConfig.range,
100
+ dataDomain: axisConfig.domain
101
+ });
102
+ if (!scale) return {
103
+ xAxis: undefined,
104
+ xScale: undefined
105
+ };
106
+
107
+ // Update axis config with actual scale domain (after .nice() or other adjustments)
108
+ const scaleDomain = scale.domain();
109
+ const actualDomain = Array.isArray(scaleDomain) && scaleDomain.length === 2 ? {
110
+ min: scaleDomain[0],
111
+ max: scaleDomain[1]
112
+ } : axisConfig.domain;
113
+ const finalAxisConfig = _objectSpread(_objectSpread({}, axisConfig), {}, {
114
+ domain: actualDomain
115
+ });
116
+ return {
117
+ xAxis: finalAxisConfig,
118
+ xScale: scale
119
+ };
120
+ }, [xAxisConfig, series, chartRect]);
121
+ const {
122
+ yAxes,
123
+ yScales
124
+ } = useMemo(() => {
125
+ const axes = new Map();
126
+ const scales = new Map();
127
+ if (!chartRect || chartRect.width <= 0 || chartRect.height <= 0) return {
128
+ yAxes: axes,
129
+ yScales: scales
130
+ };
131
+ yAxisConfig.forEach(axisParam => {
132
+ var _axisParam$id, _series$filter, _axisParam$domainLimi;
133
+ const axisId = (_axisParam$id = axisParam.id) !== null && _axisParam$id !== void 0 ? _axisParam$id : defaultAxisId;
134
+
135
+ // Get relevant series data
136
+ const relevantSeries = (_series$filter = series === null || series === void 0 ? void 0 : series.filter(s => {
137
+ var _s$yAxisId;
138
+ return ((_s$yAxisId = s.yAxisId) !== null && _s$yAxisId !== void 0 ? _s$yAxisId : defaultAxisId) === axisId;
139
+ })) !== null && _series$filter !== void 0 ? _series$filter : [];
140
+
141
+ // Calculate domain and range
142
+ const dataDomain = getAxisDomain(axisParam, relevantSeries, 'y');
143
+ const range = getAxisRange(axisParam, chartRect, 'y');
144
+ const axisConfig = {
145
+ scaleType: axisParam.scaleType,
146
+ domain: dataDomain,
147
+ range,
148
+ data: axisParam.data,
149
+ categoryPadding: axisParam.categoryPadding,
150
+ domainLimit: (_axisParam$domainLimi = axisParam.domainLimit) !== null && _axisParam$domainLimi !== void 0 ? _axisParam$domainLimi : 'nice'
151
+ };
152
+
153
+ // Create the scale
154
+ const scale = getAxisScale({
155
+ config: axisConfig,
156
+ type: 'y',
157
+ range: axisConfig.range,
158
+ dataDomain: axisConfig.domain
159
+ });
160
+ if (scale) {
161
+ scales.set(axisId, scale);
162
+
163
+ // Update axis config with actual scale domain (after .nice() or other adjustments)
164
+ const scaleDomain = scale.domain();
165
+ const actualDomain = Array.isArray(scaleDomain) && scaleDomain.length === 2 ? {
166
+ min: scaleDomain[0],
167
+ max: scaleDomain[1]
168
+ } : axisConfig.domain;
169
+ axes.set(axisId, _objectSpread(_objectSpread({}, axisConfig), {}, {
170
+ domain: actualDomain
171
+ }));
172
+ }
173
+ });
174
+ return {
175
+ yAxes: axes,
176
+ yScales: scales
177
+ };
178
+ }, [yAxisConfig, series, chartRect]);
179
+ const getXAxis = useCallback(() => xAxis, [xAxis]);
180
+ const getYAxis = useCallback(id => yAxes.get(id !== null && id !== void 0 ? id : defaultAxisId), [yAxes]);
181
+ const getXScale = useCallback(() => xScale, [xScale]);
182
+ const getYScale = useCallback(id => yScales.get(id !== null && id !== void 0 ? id : defaultAxisId), [yScales]);
183
+ const getSeries = useCallback(seriesId => series === null || series === void 0 ? void 0 : series.find(s => s.id === seriesId), [series]);
184
+ const stackedDataMap = useMemo(() => {
185
+ if (!series) return new Map();
186
+ return calculateStackedSeriesData(series);
187
+ }, [series]);
188
+ const getStackedSeriesData = useCallback(seriesId => {
189
+ if (!seriesId) return undefined;
190
+ return stackedDataMap.get(seriesId);
191
+ }, [stackedDataMap]);
192
+ const dataLength = useMemo(() => {
193
+ // If xAxis has categorical data, use that length
194
+ if (xAxisConfig.data && xAxisConfig.data.length > 0) {
195
+ return xAxisConfig.data.length;
196
+ }
197
+
198
+ // Otherwise, find the longest series
199
+ if (!series || series.length === 0) return 0;
200
+ return series.reduce((max, s) => {
201
+ var _seriesData$length;
202
+ const seriesData = getStackedSeriesData(s.id);
203
+ return Math.max(max, (_seriesData$length = seriesData === null || seriesData === void 0 ? void 0 : seriesData.length) !== null && _seriesData$length !== void 0 ? _seriesData$length : 0);
204
+ }, 0);
205
+ }, [xAxisConfig.data, series, getStackedSeriesData]);
206
+ const getAxisBounds = useCallback(axisId => {
207
+ const axis = renderedAxes.get(axisId);
208
+ if (!axis || !chartRect) return;
209
+ const axesAtPosition = Array.from(renderedAxes.values()).filter(a => a.position === axis.position).sort((a, b) => a.id.localeCompare(b.id));
210
+ const axisIndex = axesAtPosition.findIndex(a => a.id === axisId);
211
+ if (axisIndex === -1) return;
212
+
213
+ // Calculate offset from previous axes at the same position
214
+ const offsetFromPreviousAxes = axesAtPosition.slice(0, axisIndex).reduce((sum, a) => sum + a.size, 0);
215
+ if (axis.position === 'top') {
216
+ // Position above the chart rect, accounting for user inset
217
+ const startY = calculatedInset.top + offsetFromPreviousAxes;
218
+ return {
219
+ x: chartRect.x,
220
+ y: startY,
221
+ width: chartRect.width,
222
+ height: axis.size
223
+ };
224
+ } else if (axis.position === 'bottom') {
225
+ // Position below the chart rect, accounting for user inset
226
+ const startY = chartRect.y + chartRect.height + offsetFromPreviousAxes;
227
+ return {
228
+ x: chartRect.x,
229
+ y: startY,
230
+ width: chartRect.width,
231
+ height: axis.size
232
+ };
233
+ } else if (axis.position === 'left') {
234
+ // Position to the left of the chart rect, accounting for user inset
235
+ const startX = calculatedInset.left + offsetFromPreviousAxes;
236
+ return {
237
+ x: startX,
238
+ y: chartRect.y,
239
+ width: axis.size,
240
+ height: chartRect.height
241
+ };
242
+ } else {
243
+ // right - position to the right of the chart rect, accounting for user inset
244
+ const startX = chartRect.x + chartRect.width + offsetFromPreviousAxes;
245
+ return {
246
+ x: startX,
247
+ y: chartRect.y,
248
+ width: axis.size,
249
+ height: chartRect.height
250
+ };
251
+ }
252
+ }, [renderedAxes, chartRect, calculatedInset]);
253
+ const contextValue = useMemo(() => ({
254
+ series: series !== null && series !== void 0 ? series : [],
255
+ getSeries,
256
+ getSeriesData: getStackedSeriesData,
257
+ animate,
258
+ width: chartWidth,
259
+ height: chartHeight,
260
+ getXAxis,
261
+ getYAxis,
262
+ getXScale,
263
+ getYScale,
264
+ drawingArea: chartRect,
265
+ dataLength,
266
+ registerAxis,
267
+ unregisterAxis,
268
+ getAxisBounds
269
+ }), [series, getSeries, getStackedSeriesData, animate, chartWidth, chartHeight, getXAxis, getYAxis, getXScale, getYScale, chartRect, dataLength, registerAxis, unregisterAxis, getAxisBounds]);
270
+ const rootClassNames = useMemo(() => cx(className, classNames === null || classNames === void 0 ? void 0 : classNames.root), [className, classNames]);
271
+ const rootStyles = useMemo(() => _objectSpread(_objectSpread({}, style), styles === null || styles === void 0 ? void 0 : styles.root), [style, styles === null || styles === void 0 ? void 0 : styles.root]);
272
+ return /*#__PURE__*/_jsx(CartesianChartProvider, {
273
+ value: contextValue,
274
+ children: /*#__PURE__*/_jsx(ScrubberProvider, {
275
+ enableScrubbing: !!enableScrubbing,
276
+ onScrubberPositionChange: onScrubberPositionChange,
277
+ svgRef: svgRef,
278
+ children: /*#__PURE__*/_jsx(Box, _objectSpread(_objectSpread({
279
+ ref: node => {
280
+ observe(node);
281
+ },
282
+ className: rootClassNames,
283
+ height: height,
284
+ style: rootStyles,
285
+ width: width
286
+ }, props), {}, {
287
+ children: /*#__PURE__*/_jsx(Box, {
288
+ ref: node => {
289
+ const svgElement = node;
290
+ svgRef.current = svgElement;
291
+ // Forward the ref to the user
292
+ if (ref) {
293
+ if (typeof ref === 'function') {
294
+ ref(svgElement);
295
+ } else {
296
+ ref.current = svgElement;
297
+ }
298
+ }
299
+ },
300
+ "aria-live": "polite",
301
+ as: "svg",
302
+ className: cx(enableScrubbing && focusStylesCss, classNames === null || classNames === void 0 ? void 0 : classNames.chart),
303
+ height: "100%",
304
+ style: styles === null || styles === void 0 ? void 0 : styles.chart,
305
+ tabIndex: enableScrubbing ? 0 : undefined,
306
+ width: "100%",
307
+ children: children
308
+ })
309
+ }))
310
+ })
311
+ });
312
+ }));
313
+ import "./CartesianChart.css";
@@ -0,0 +1,10 @@
1
+ import { createContext, useContext } from 'react';
2
+ const CartesianChartContext = /*#__PURE__*/createContext(undefined);
3
+ export const useCartesianChartContext = () => {
4
+ const context = useContext(CartesianChartContext);
5
+ if (!context) {
6
+ throw new Error('useCartesianChartContext must be used within a CartesianChart component. See http://cds.coinbase.com/components/graphs/CartesianChart.');
7
+ }
8
+ return context;
9
+ };
10
+ export const CartesianChartProvider = CartesianChartContext.Provider;
@@ -0,0 +1,95 @@
1
+ const _excluded = ["d", "transition"],
2
+ _excluded2 = ["animate", "clipRect", "clipOffset", "d", "transition"];
3
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
4
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
5
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
6
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
7
+ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
8
+ function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
9
+ 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; }
10
+ import { memo, useId, useMemo } from 'react';
11
+ import { m as motion } from 'framer-motion';
12
+ import { usePathTransition } from './utils/transition';
13
+ import { useCartesianChartContext } from './ChartProvider';
14
+
15
+ /**
16
+ * Duration in seconds for path enter transition.
17
+ */
18
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
19
+ export const pathEnterTransitionDuration = 0.5;
20
+ const AnimatedPath = /*#__PURE__*/memo(_ref => {
21
+ let {
22
+ d = '',
23
+ transition
24
+ } = _ref,
25
+ pathProps = _objectWithoutProperties(_ref, _excluded);
26
+ const interpolatedPath = usePathTransition({
27
+ currentPath: d,
28
+ transition
29
+ });
30
+ return /*#__PURE__*/_jsx(motion.path, _objectSpread({
31
+ d: interpolatedPath
32
+ }, pathProps));
33
+ });
34
+ export const Path = /*#__PURE__*/memo(_ref2 => {
35
+ let {
36
+ animate: animateProp,
37
+ clipRect,
38
+ clipOffset = 0,
39
+ d = '',
40
+ transition
41
+ } = _ref2,
42
+ pathProps = _objectWithoutProperties(_ref2, _excluded2);
43
+ const clipPathId = useId();
44
+ const context = useCartesianChartContext();
45
+ const rect = clipRect !== undefined ? clipRect : context.drawingArea;
46
+ const animate = animateProp !== null && animateProp !== void 0 ? animateProp : context.animate;
47
+
48
+ // The clip offset provides extra padding to prevent path from being cut off
49
+ // Area charts typically use offset=0 for exact clipping, while lines use offset=2 for breathing room
50
+ const totalOffset = clipOffset * 2; // Applied on both sides
51
+
52
+ const clipPathAnimation = useMemo(() => {
53
+ if (rect === null) return;
54
+ return {
55
+ hidden: {
56
+ width: 0
57
+ },
58
+ visible: {
59
+ width: rect.width + totalOffset,
60
+ transition: {
61
+ type: 'timing',
62
+ duration: pathEnterTransitionDuration
63
+ }
64
+ }
65
+ };
66
+ }, [rect, totalOffset]);
67
+ const clipPath = useMemo(() => rect !== null ? "url(#".concat(clipPathId, ")") : undefined, [rect, clipPathId]);
68
+ return /*#__PURE__*/_jsxs(_Fragment, {
69
+ children: [rect !== null && /*#__PURE__*/_jsx("defs", {
70
+ children: /*#__PURE__*/_jsx("clipPath", {
71
+ id: clipPathId,
72
+ children: !animate ? /*#__PURE__*/_jsx("rect", {
73
+ height: rect.height + totalOffset,
74
+ width: rect.width + totalOffset,
75
+ x: rect.x - clipOffset,
76
+ y: rect.y - clipOffset
77
+ }) : /*#__PURE__*/_jsx(motion.rect, {
78
+ animate: "visible",
79
+ height: rect.height + totalOffset,
80
+ initial: "hidden",
81
+ variants: clipPathAnimation,
82
+ x: rect.x - clipOffset,
83
+ y: rect.y - clipOffset
84
+ })
85
+ })
86
+ }), !animate ? /*#__PURE__*/_jsx("path", _objectSpread({
87
+ clipPath: clipPath,
88
+ d: d
89
+ }, pathProps)) : /*#__PURE__*/_jsx(AnimatedPath, _objectSpread({
90
+ clipPath: clipPath,
91
+ d: d,
92
+ transition: transition
93
+ }, pathProps))]
94
+ });
95
+ });
@@ -0,0 +1 @@
1
+ .cds-dotBaseCss-dfbcvh4{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;width:var(--space-1);height:var(--space-1);background:currentColor;border-radius:1000px;margin-inline-end:var(--space-0_75);}
@@ -0,0 +1,112 @@
1
+ const _excluded = ["as", "color", "label", "display", "alignItems", "font", "hideDot"],
2
+ _excluded2 = ["background", "activeBackground", "width", "justifyContent", "TabComponent", "TabsActiveIndicatorComponent"];
3
+ function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
4
+ 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; }
5
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
6
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
7
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
8
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
9
+ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
10
+ import React, { forwardRef, memo, useMemo } from 'react';
11
+ import { Box } from '@coinbase/cds-web/layout';
12
+ import { SegmentedTabs, tabsTransitionConfig } from '@coinbase/cds-web/tabs';
13
+ import { SegmentedTab } from '@coinbase/cds-web/tabs/SegmentedTab';
14
+ import { Text } from '@coinbase/cds-web/typography';
15
+ import { m as motion } from 'framer-motion';
16
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
17
+ const MotionBox = motion(Box);
18
+
19
+ // Animated active indicator to support smooth transition of background color
20
+ export const PeriodSelectorActiveIndicator = /*#__PURE__*/memo(_ref => {
21
+ let {
22
+ activeTabRect,
23
+ background = 'bgPrimaryWash',
24
+ position = 'absolute',
25
+ borderRadius = 1000,
26
+ style
27
+ } = _ref;
28
+ const {
29
+ width,
30
+ height,
31
+ x
32
+ } = activeTabRect;
33
+ const activeAnimation = useMemo(() => ({
34
+ width,
35
+ x
36
+ }), [width, x]);
37
+ if (!width) return null;
38
+ return /*#__PURE__*/_jsx(MotionBox, {
39
+ animate: activeAnimation,
40
+ borderRadius: borderRadius,
41
+ "data-testid": "period-selector-active-indicator",
42
+ height: height,
43
+ initial: false,
44
+ position: position,
45
+ role: "none",
46
+ style: _objectSpread({
47
+ backgroundColor: "var(--color-".concat(background, ")"),
48
+ transition: 'background-color 0.2s ease'
49
+ }, style),
50
+ transition: tabsTransitionConfig
51
+ });
52
+ });
53
+ export const liveTabLabelDefaultElement = 'span';
54
+ // is this bad to use var(--space-1) for height and width?
55
+ const dotBaseCss = "cds-dotBaseCss-dfbcvh4";
56
+ export const LiveTabLabel = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref2, ref) => {
57
+ let {
58
+ as,
59
+ color = 'fgNegative',
60
+ label = 'LIVE',
61
+ display = 'inline-flex',
62
+ alignItems = 'center',
63
+ font = 'label1',
64
+ hideDot
65
+ } = _ref2,
66
+ props = _objectWithoutProperties(_ref2, _excluded);
67
+ const Component = as !== null && as !== void 0 ? as : liveTabLabelDefaultElement;
68
+ return /*#__PURE__*/_jsxs(Text, _objectSpread(_objectSpread({
69
+ ref: ref,
70
+ alignItems: alignItems,
71
+ as: Component,
72
+ color: color,
73
+ display: display,
74
+ font: font
75
+ }, props), {}, {
76
+ children: [!hideDot && /*#__PURE__*/_jsx("span", {
77
+ className: dotBaseCss
78
+ }), label]
79
+ }));
80
+ }));
81
+
82
+ // Custom tab component with primary color for active state
83
+ const PeriodSelectorTab = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((props, ref) => /*#__PURE__*/_jsx(SegmentedTab, _objectSpread({
84
+ ref: ref,
85
+ activeColor: "fgPrimary",
86
+ font: "label1"
87
+ }, props))));
88
+ /**
89
+ * PeriodSelector is a specialized version of SegmentedTabs optimized for chart period selection.
90
+ * It provides transparent background, primary wash active state, and full-width layout by default.
91
+ */
92
+ export const PeriodSelector = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref3, ref) => {
93
+ let {
94
+ background = 'transparent',
95
+ activeBackground = 'bgPrimaryWash',
96
+ width = '100%',
97
+ justifyContent = 'space-between',
98
+ TabComponent = PeriodSelectorTab,
99
+ TabsActiveIndicatorComponent = PeriodSelectorActiveIndicator
100
+ } = _ref3,
101
+ props = _objectWithoutProperties(_ref3, _excluded2);
102
+ return /*#__PURE__*/_jsx(SegmentedTabs, _objectSpread({
103
+ ref: ref,
104
+ TabComponent: TabComponent,
105
+ TabsActiveIndicatorComponent: TabsActiveIndicatorComponent,
106
+ activeBackground: activeBackground,
107
+ background: background,
108
+ justifyContent: justifyContent,
109
+ width: width
110
+ }, props));
111
+ }));
112
+ import "./PeriodSelector.css";
@@ -0,0 +1,75 @@
1
+ import React, { memo, useMemo } from 'react';
2
+ import { useCartesianChartContext } from '../ChartProvider';
3
+ import { getAreaPath } from '../utils';
4
+ import { DottedArea } from './DottedArea';
5
+ import { GradientArea } from './GradientArea';
6
+ import { SolidArea } from './SolidArea';
7
+ import { jsx as _jsx } from "react/jsx-runtime";
8
+ export const Area = /*#__PURE__*/memo(_ref => {
9
+ let {
10
+ seriesId,
11
+ curve = 'bump',
12
+ type = 'solid',
13
+ AreaComponent: AreaComponentProp,
14
+ fill: fillProp,
15
+ fillOpacity = 1,
16
+ baseline,
17
+ connectNulls,
18
+ gradient: gradientProp,
19
+ transition,
20
+ animate
21
+ } = _ref;
22
+ const {
23
+ getSeries,
24
+ getSeriesData,
25
+ getXScale,
26
+ getYScale,
27
+ getXAxis
28
+ } = useCartesianChartContext();
29
+ const matchedSeries = useMemo(() => getSeries(seriesId), [seriesId, getSeries]);
30
+ const gradient = useMemo(() => gradientProp !== null && gradientProp !== void 0 ? gradientProp : matchedSeries === null || matchedSeries === void 0 ? void 0 : matchedSeries.gradient, [gradientProp, matchedSeries === null || matchedSeries === void 0 ? void 0 : matchedSeries.gradient]);
31
+ const fill = useMemo(() => fillProp !== null && fillProp !== void 0 ? fillProp : matchedSeries === null || matchedSeries === void 0 ? void 0 : matchedSeries.color, [fillProp, matchedSeries === null || matchedSeries === void 0 ? void 0 : matchedSeries.color]);
32
+ const sourceData = useMemo(() => getSeriesData(seriesId), [seriesId, getSeriesData]);
33
+ const xAxis = getXAxis();
34
+ const xScale = getXScale();
35
+ const yScale = getYScale(matchedSeries === null || matchedSeries === void 0 ? void 0 : matchedSeries.yAxisId);
36
+ const area = useMemo(() => {
37
+ if (!sourceData || sourceData.length === 0 || !xScale || !yScale) return '';
38
+
39
+ // Get numeric x-axis data if available
40
+ const xData = xAxis !== null && xAxis !== void 0 && xAxis.data && Array.isArray(xAxis.data) && typeof xAxis.data[0] === 'number' ? xAxis.data : undefined;
41
+ return getAreaPath({
42
+ data: sourceData,
43
+ xScale,
44
+ yScale,
45
+ curve,
46
+ xData,
47
+ connectNulls
48
+ });
49
+ }, [sourceData, xScale, yScale, curve, xAxis === null || xAxis === void 0 ? void 0 : xAxis.data, connectNulls]);
50
+ const AreaComponent = useMemo(() => {
51
+ if (AreaComponentProp) {
52
+ return AreaComponentProp;
53
+ }
54
+ switch (type) {
55
+ case 'dotted':
56
+ return DottedArea;
57
+ case 'gradient':
58
+ return GradientArea;
59
+ case 'solid':
60
+ default:
61
+ return SolidArea;
62
+ }
63
+ }, [AreaComponentProp, type]);
64
+ if (!xScale || !yScale || !sourceData || !area) return;
65
+ return /*#__PURE__*/_jsx(AreaComponent, {
66
+ animate: animate,
67
+ baseline: baseline,
68
+ d: area,
69
+ fill: fill,
70
+ fillOpacity: fillOpacity,
71
+ gradient: gradient,
72
+ transition: transition,
73
+ yAxisId: matchedSeries === null || matchedSeries === void 0 ? void 0 : matchedSeries.yAxisId
74
+ });
75
+ });