@coinbase/cds-web-visualization 3.4.0-beta.1 → 3.4.0-beta.11

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 (175) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/dts/chart/CartesianChart.d.ts +38 -2
  3. package/dts/chart/CartesianChart.d.ts.map +1 -1
  4. package/dts/chart/Path.d.ts +27 -7
  5. package/dts/chart/Path.d.ts.map +1 -1
  6. package/dts/chart/PeriodSelector.d.ts +0 -4
  7. package/dts/chart/PeriodSelector.d.ts.map +1 -1
  8. package/dts/chart/area/Area.d.ts +54 -24
  9. package/dts/chart/area/Area.d.ts.map +1 -1
  10. package/dts/chart/area/AreaChart.d.ts +33 -6
  11. package/dts/chart/area/AreaChart.d.ts.map +1 -1
  12. package/dts/chart/area/DottedArea.d.ts +21 -44
  13. package/dts/chart/area/DottedArea.d.ts.map +1 -1
  14. package/dts/chart/area/GradientArea.d.ts +21 -12
  15. package/dts/chart/area/GradientArea.d.ts.map +1 -1
  16. package/dts/chart/area/SolidArea.d.ts +16 -1
  17. package/dts/chart/area/SolidArea.d.ts.map +1 -1
  18. package/dts/chart/axis/Axis.d.ts +109 -63
  19. package/dts/chart/axis/Axis.d.ts.map +1 -1
  20. package/dts/chart/axis/DefaultAxisTickLabel.d.ts +8 -0
  21. package/dts/chart/axis/DefaultAxisTickLabel.d.ts.map +1 -0
  22. package/dts/chart/axis/XAxis.d.ts +1 -1
  23. package/dts/chart/axis/XAxis.d.ts.map +1 -1
  24. package/dts/chart/axis/YAxis.d.ts +2 -2
  25. package/dts/chart/axis/YAxis.d.ts.map +1 -1
  26. package/dts/chart/axis/index.d.ts +1 -0
  27. package/dts/chart/axis/index.d.ts.map +1 -1
  28. package/dts/chart/bar/Bar.d.ts +16 -13
  29. package/dts/chart/bar/Bar.d.ts.map +1 -1
  30. package/dts/chart/bar/BarChart.d.ts +17 -8
  31. package/dts/chart/bar/BarChart.d.ts.map +1 -1
  32. package/dts/chart/bar/BarPlot.d.ts +2 -1
  33. package/dts/chart/bar/BarPlot.d.ts.map +1 -1
  34. package/dts/chart/bar/BarStack.d.ts +40 -48
  35. package/dts/chart/bar/BarStack.d.ts.map +1 -1
  36. package/dts/chart/bar/BarStackGroup.d.ts +1 -0
  37. package/dts/chart/bar/BarStackGroup.d.ts.map +1 -1
  38. package/dts/chart/bar/DefaultBar.d.ts.map +1 -1
  39. package/dts/chart/bar/DefaultBarStack.d.ts.map +1 -1
  40. package/dts/chart/gradient/Gradient.d.ts +35 -0
  41. package/dts/chart/gradient/Gradient.d.ts.map +1 -0
  42. package/dts/chart/gradient/index.d.ts +2 -0
  43. package/dts/chart/gradient/index.d.ts.map +1 -0
  44. package/dts/chart/index.d.ts +2 -1
  45. package/dts/chart/index.d.ts.map +1 -1
  46. package/dts/chart/line/DefaultReferenceLineLabel.d.ts +9 -0
  47. package/dts/chart/line/DefaultReferenceLineLabel.d.ts.map +1 -0
  48. package/dts/chart/line/DottedLine.d.ts +15 -3
  49. package/dts/chart/line/DottedLine.d.ts.map +1 -1
  50. package/dts/chart/line/Line.d.ts +87 -28
  51. package/dts/chart/line/Line.d.ts.map +1 -1
  52. package/dts/chart/line/LineChart.d.ts +26 -8
  53. package/dts/chart/line/LineChart.d.ts.map +1 -1
  54. package/dts/chart/line/ReferenceLine.d.ts +91 -44
  55. package/dts/chart/line/ReferenceLine.d.ts.map +1 -1
  56. package/dts/chart/line/SolidLine.d.ts +14 -3
  57. package/dts/chart/line/SolidLine.d.ts.map +1 -1
  58. package/dts/chart/line/index.d.ts +1 -1
  59. package/dts/chart/line/index.d.ts.map +1 -1
  60. package/dts/chart/point/DefaultPointLabel.d.ts +10 -0
  61. package/dts/chart/point/DefaultPointLabel.d.ts.map +1 -0
  62. package/dts/chart/point/Point.d.ts +201 -0
  63. package/dts/chart/point/Point.d.ts.map +1 -0
  64. package/dts/chart/point/index.d.ts +3 -0
  65. package/dts/chart/point/index.d.ts.map +1 -0
  66. package/dts/chart/scrubber/DefaultScrubberBeacon.d.ts +24 -0
  67. package/dts/chart/scrubber/DefaultScrubberBeacon.d.ts.map +1 -0
  68. package/dts/chart/scrubber/DefaultScrubberBeaconLabel.d.ts +12 -0
  69. package/dts/chart/scrubber/DefaultScrubberBeaconLabel.d.ts.map +1 -0
  70. package/dts/chart/scrubber/DefaultScrubberLabel.d.ts +10 -0
  71. package/dts/chart/scrubber/DefaultScrubberLabel.d.ts.map +1 -0
  72. package/dts/chart/scrubber/Scrubber.d.ts +207 -66
  73. package/dts/chart/scrubber/Scrubber.d.ts.map +1 -1
  74. package/dts/chart/scrubber/ScrubberBeaconGroup.d.ts +70 -0
  75. package/dts/chart/scrubber/ScrubberBeaconGroup.d.ts.map +1 -0
  76. package/dts/chart/scrubber/ScrubberBeaconLabelGroup.d.ts +32 -0
  77. package/dts/chart/scrubber/ScrubberBeaconLabelGroup.d.ts.map +1 -0
  78. package/dts/chart/scrubber/index.d.ts +3 -0
  79. package/dts/chart/scrubber/index.d.ts.map +1 -1
  80. package/dts/chart/text/ChartText.d.ts +46 -43
  81. package/dts/chart/text/ChartText.d.ts.map +1 -1
  82. package/dts/chart/text/{SmartChartTextGroup.d.ts → ChartTextGroup.d.ts} +9 -3
  83. package/dts/chart/text/ChartTextGroup.d.ts.map +1 -0
  84. package/dts/chart/text/index.d.ts +1 -1
  85. package/dts/chart/text/index.d.ts.map +1 -1
  86. package/dts/chart/utils/axis.d.ts +25 -1
  87. package/dts/chart/utils/axis.d.ts.map +1 -1
  88. package/dts/chart/utils/chart.d.ts +27 -7
  89. package/dts/chart/utils/chart.d.ts.map +1 -1
  90. package/dts/chart/utils/context.d.ts +6 -0
  91. package/dts/chart/utils/context.d.ts.map +1 -1
  92. package/dts/chart/utils/gradient.d.ts +104 -0
  93. package/dts/chart/utils/gradient.d.ts.map +1 -0
  94. package/dts/chart/utils/index.d.ts +4 -0
  95. package/dts/chart/utils/index.d.ts.map +1 -1
  96. package/dts/chart/utils/interpolate.d.ts +112 -0
  97. package/dts/chart/utils/interpolate.d.ts.map +1 -0
  98. package/dts/chart/utils/path.d.ts +24 -1
  99. package/dts/chart/utils/path.d.ts.map +1 -1
  100. package/dts/chart/utils/point.d.ts +40 -7
  101. package/dts/chart/utils/point.d.ts.map +1 -1
  102. package/dts/chart/utils/scale.d.ts +11 -0
  103. package/dts/chart/utils/scale.d.ts.map +1 -1
  104. package/dts/chart/utils/scrubber.d.ts +39 -0
  105. package/dts/chart/utils/scrubber.d.ts.map +1 -0
  106. package/dts/chart/utils/transition.d.ts +65 -0
  107. package/dts/chart/utils/transition.d.ts.map +1 -0
  108. package/dts/sparkline/sparkline-interactive/SparklineInteractiveMarkerDates.d.ts.map +1 -1
  109. package/esm/chart/CartesianChart.js +140 -85
  110. package/esm/chart/Path.js +53 -47
  111. package/esm/chart/PeriodSelector.js +4 -18
  112. package/esm/chart/area/Area.js +24 -34
  113. package/esm/chart/area/AreaChart.js +24 -15
  114. package/esm/chart/area/DottedArea.js +35 -89
  115. package/esm/chart/area/GradientArea.js +34 -80
  116. package/esm/chart/area/SolidArea.js +29 -11
  117. package/esm/chart/axis/Axis.js +4 -39
  118. package/esm/chart/axis/DefaultAxisTickLabel.js +15 -0
  119. package/esm/chart/axis/XAxis.js +184 -63
  120. package/esm/chart/axis/YAxis.js +190 -57
  121. package/esm/chart/axis/index.js +1 -0
  122. package/esm/chart/bar/Bar.js +3 -1
  123. package/esm/chart/bar/BarChart.js +15 -32
  124. package/esm/chart/bar/BarPlot.js +3 -2
  125. package/esm/chart/bar/BarStack.js +65 -23
  126. package/esm/chart/bar/BarStackGroup.js +7 -17
  127. package/esm/chart/bar/DefaultBar.js +4 -7
  128. package/esm/chart/bar/DefaultBarStack.js +5 -7
  129. package/esm/chart/gradient/Gradient.js +104 -0
  130. package/esm/chart/gradient/index.js +1 -0
  131. package/esm/chart/index.js +2 -1
  132. package/esm/chart/line/DefaultReferenceLineLabel.js +81 -0
  133. package/esm/chart/line/DottedLine.js +38 -17
  134. package/esm/chart/line/Line.js +96 -70
  135. package/esm/chart/line/LineChart.js +18 -6
  136. package/esm/chart/line/ReferenceLine.js +41 -43
  137. package/esm/chart/line/SolidLine.js +36 -15
  138. package/esm/chart/line/index.js +1 -1
  139. package/esm/chart/{line/GradientLine.js → point/DefaultPointLabel.js} +31 -45
  140. package/esm/chart/point/Point.css +2 -0
  141. package/esm/chart/{Point.js → point/Point.js} +66 -57
  142. package/esm/chart/point/index.js +2 -0
  143. package/esm/chart/scrubber/DefaultScrubberBeacon.js +155 -0
  144. package/esm/chart/scrubber/{ScrubberBeaconLabel.js → DefaultScrubberBeaconLabel.js} +23 -10
  145. package/esm/chart/scrubber/DefaultScrubberLabel.js +30 -0
  146. package/esm/chart/scrubber/Scrubber.js +98 -392
  147. package/esm/chart/scrubber/ScrubberBeaconGroup.js +166 -0
  148. package/esm/chart/scrubber/ScrubberBeaconLabelGroup.js +186 -0
  149. package/esm/chart/scrubber/index.js +3 -1
  150. package/esm/chart/text/ChartText.js +15 -20
  151. package/esm/chart/text/{SmartChartTextGroup.js → ChartTextGroup.js} +4 -3
  152. package/esm/chart/text/index.js +1 -1
  153. package/esm/chart/utils/axis.js +45 -29
  154. package/esm/chart/utils/chart.js +29 -3
  155. package/esm/chart/utils/gradient.js +257 -0
  156. package/esm/chart/utils/index.js +4 -0
  157. package/esm/chart/utils/interpolate.js +644 -0
  158. package/esm/chart/utils/path.js +32 -9
  159. package/esm/chart/utils/point.js +99 -12
  160. package/esm/chart/utils/scale.js +13 -2
  161. package/esm/chart/utils/scrubber.js +132 -0
  162. package/esm/chart/utils/transition.js +111 -0
  163. package/esm/sparkline/sparkline-interactive/SparklineInteractiveMarkerDates.js +8 -4
  164. package/package.json +9 -9
  165. package/dts/chart/Point.d.ts +0 -153
  166. package/dts/chart/Point.d.ts.map +0 -1
  167. package/dts/chart/line/GradientLine.d.ts +0 -42
  168. package/dts/chart/line/GradientLine.d.ts.map +0 -1
  169. package/dts/chart/scrubber/ScrubberBeacon.d.ts +0 -93
  170. package/dts/chart/scrubber/ScrubberBeacon.d.ts.map +0 -1
  171. package/dts/chart/scrubber/ScrubberBeaconLabel.d.ts +0 -7
  172. package/dts/chart/scrubber/ScrubberBeaconLabel.d.ts.map +0 -1
  173. package/dts/chart/text/SmartChartTextGroup.d.ts.map +0 -1
  174. package/esm/chart/Point.css +0 -2
  175. package/esm/chart/scrubber/ScrubberBeacon.js +0 -195
@@ -1,4 +1,4 @@
1
- const _excluded = ["series", "children", "animate", "xAxis", "yAxis", "inset", "enableScrubbing", "onScrubberPositionChange", "width", "height", "className", "style"];
1
+ const _excluded = ["series", "children", "animate", "xAxis", "yAxis", "inset", "enableScrubbing", "onScrubberPositionChange", "width", "height", "className", "classNames", "style", "styles"];
2
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
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
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; }
@@ -20,15 +20,17 @@ export const CartesianChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, r
20
20
  series,
21
21
  children,
22
22
  animate = true,
23
- xAxis: xAxisConfigInput,
24
- yAxis: yAxisConfigInput,
25
- inset: insetInput,
23
+ xAxis: xAxisConfigProp,
24
+ yAxis: yAxisConfigProp,
25
+ inset,
26
26
  enableScrubbing,
27
27
  onScrubberPositionChange,
28
28
  width = '100%',
29
29
  height = '100%',
30
30
  className,
31
- style
31
+ classNames,
32
+ style,
33
+ styles
32
34
  } = _ref,
33
35
  props = _objectWithoutProperties(_ref, _excluded);
34
36
  const {
@@ -36,15 +38,13 @@ export const CartesianChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, r
36
38
  width: chartWidth,
37
39
  height: chartHeight
38
40
  } = useDimensions();
39
- const internalSvgRef = useRef(null);
40
- const userInset = useMemo(() => {
41
- return getChartInset(insetInput, defaultChartInset);
42
- }, [insetInput]);
41
+ const svgRef = useRef(null);
42
+ const calculatedInset = useMemo(() => getChartInset(inset, defaultChartInset), [inset]);
43
43
 
44
44
  // Axis configs store the properties of each axis, such as id, scale type, domain limit, etc.
45
45
  // We only support 1 x axis but allow for multiple y axes.
46
- const xAxisConfig = useMemo(() => getAxisConfig('x', xAxisConfigInput)[0], [xAxisConfigInput]);
47
- const yAxisConfig = useMemo(() => getAxisConfig('y', yAxisConfigInput), [yAxisConfigInput]);
46
+ const xAxisConfig = useMemo(() => getAxisConfig('x', xAxisConfigProp)[0], [xAxisConfigProp]);
47
+ const yAxisConfig = useMemo(() => getAxisConfig('y', yAxisConfigProp), [yAxisConfigProp]);
48
48
  const {
49
49
  renderedAxes,
50
50
  registerAxis,
@@ -59,10 +59,10 @@ export const CartesianChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, r
59
59
  height: 0
60
60
  };
61
61
  const totalInset = {
62
- top: userInset.top + axisPadding.top,
63
- right: userInset.right + axisPadding.right,
64
- bottom: userInset.bottom + axisPadding.bottom,
65
- left: userInset.left + axisPadding.left
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
66
  };
67
67
  const availableWidth = chartWidth - totalInset.left - totalInset.right;
68
68
  const availableHeight = chartHeight - totalInset.top - totalInset.bottom;
@@ -72,11 +72,15 @@ export const CartesianChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, r
72
72
  width: availableWidth > 0 ? availableWidth : 0,
73
73
  height: availableHeight > 0 ? availableHeight : 0
74
74
  };
75
- }, [chartHeight, chartWidth, userInset, axisPadding]);
76
-
77
- // Axes contain the config along with domain and range, which get calculated here.
78
- const xAxis = useMemo(() => {
79
- if (!chartRect || chartRect.width <= 0 || chartRect.height <= 0) return undefined;
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
+ };
80
84
  const domain = getAxisDomain(xAxisConfig, series !== null && series !== void 0 ? series : [], 'x');
81
85
  const range = getAxisRange(xAxisConfig, chartRect, 'x');
82
86
  const axisConfig = {
@@ -87,11 +91,43 @@ export const CartesianChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, r
87
91
  categoryPadding: xAxisConfig.categoryPadding,
88
92
  domainLimit: xAxisConfig.domainLimit
89
93
  };
90
- return axisConfig;
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
+ };
91
120
  }, [xAxisConfig, series, chartRect]);
92
- const yAxes = useMemo(() => {
121
+ const {
122
+ yAxes,
123
+ yScales
124
+ } = useMemo(() => {
93
125
  const axes = new Map();
94
- if (!chartRect || chartRect.width <= 0 || chartRect.height <= 0) return axes;
126
+ const scales = new Map();
127
+ if (!chartRect || chartRect.width <= 0 || chartRect.height <= 0) return {
128
+ yAxes: axes,
129
+ yScales: scales
130
+ };
95
131
  yAxisConfig.forEach(axisParam => {
96
132
  var _axisParam$id, _series$filter, _axisParam$domainLimi;
97
133
  const axisId = (_axisParam$id = axisParam.id) !== null && _axisParam$id !== void 0 ? _axisParam$id : defaultAxisId;
@@ -102,36 +138,19 @@ export const CartesianChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, r
102
138
  return ((_s$yAxisId = s.yAxisId) !== null && _s$yAxisId !== void 0 ? _s$yAxisId : defaultAxisId) === axisId;
103
139
  })) !== null && _series$filter !== void 0 ? _series$filter : [];
104
140
 
105
- // Calculate domain and range in one pass
106
- const domain = getAxisDomain(axisParam, relevantSeries, 'y');
141
+ // Calculate domain and range
142
+ const dataDomain = getAxisDomain(axisParam, relevantSeries, 'y');
107
143
  const range = getAxisRange(axisParam, chartRect, 'y');
108
- axes.set(axisId, {
144
+ const axisConfig = {
109
145
  scaleType: axisParam.scaleType,
110
- domain,
146
+ domain: dataDomain,
111
147
  range,
112
148
  data: axisParam.data,
113
149
  categoryPadding: axisParam.categoryPadding,
114
150
  domainLimit: (_axisParam$domainLimi = axisParam.domainLimit) !== null && _axisParam$domainLimi !== void 0 ? _axisParam$domainLimi : 'nice'
115
- });
116
- });
117
- return axes;
118
- }, [yAxisConfig, series, chartRect]);
151
+ };
119
152
 
120
- // Scales are the functions that convert data values to visual positions.
121
- // They are calculated here based on the above axes.
122
- const xScale = useMemo(() => {
123
- if (!chartRect || chartRect.width <= 0 || chartRect.height <= 0 || xAxis === undefined) return undefined;
124
- return getAxisScale({
125
- config: xAxis,
126
- type: 'x',
127
- range: xAxis.range,
128
- dataDomain: xAxis.domain
129
- });
130
- }, [chartRect, xAxis]);
131
- const yScales = useMemo(() => {
132
- const scales = new Map();
133
- if (!chartRect || chartRect.width <= 0 || chartRect.height <= 0) return scales;
134
- yAxes.forEach((axisConfig, axisId) => {
153
+ // Create the scale
135
154
  const scale = getAxisScale({
136
155
  config: axisConfig,
137
156
  type: 'y',
@@ -140,10 +159,23 @@ export const CartesianChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, r
140
159
  });
141
160
  if (scale) {
142
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
+ }));
143
172
  }
144
173
  });
145
- return scales;
146
- }, [chartRect, yAxes]);
174
+ return {
175
+ yAxes: axes,
176
+ yScales: scales
177
+ };
178
+ }, [yAxisConfig, series, chartRect]);
147
179
  const getXAxis = useCallback(() => xAxis, [xAxis]);
148
180
  const getYAxis = useCallback(id => yAxes.get(id !== null && id !== void 0 ? id : defaultAxisId), [yAxes]);
149
181
  const getXScale = useCallback(() => xScale, [xScale]);
@@ -157,6 +189,20 @@ export const CartesianChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, r
157
189
  if (!seriesId) return undefined;
158
190
  return stackedDataMap.get(seriesId);
159
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]);
160
206
  const getAxisBounds = useCallback(axisId => {
161
207
  const axis = renderedAxes.get(axisId);
162
208
  if (!axis || !chartRect) return;
@@ -168,7 +214,7 @@ export const CartesianChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, r
168
214
  const offsetFromPreviousAxes = axesAtPosition.slice(0, axisIndex).reduce((sum, a) => sum + a.size, 0);
169
215
  if (axis.position === 'top') {
170
216
  // Position above the chart rect, accounting for user inset
171
- const startY = userInset.top + offsetFromPreviousAxes;
217
+ const startY = calculatedInset.top + offsetFromPreviousAxes;
172
218
  return {
173
219
  x: chartRect.x,
174
220
  y: startY,
@@ -186,7 +232,7 @@ export const CartesianChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, r
186
232
  };
187
233
  } else if (axis.position === 'left') {
188
234
  // Position to the left of the chart rect, accounting for user inset
189
- const startX = userInset.left + offsetFromPreviousAxes;
235
+ const startX = calculatedInset.left + offsetFromPreviousAxes;
190
236
  return {
191
237
  x: startX,
192
238
  y: chartRect.y,
@@ -203,7 +249,7 @@ export const CartesianChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, r
203
249
  height: chartRect.height
204
250
  };
205
251
  }
206
- }, [renderedAxes, chartRect, userInset]);
252
+ }, [renderedAxes, chartRect, calculatedInset]);
207
253
  const contextValue = useMemo(() => ({
208
254
  series: series !== null && series !== void 0 ? series : [],
209
255
  getSeries,
@@ -216,43 +262,52 @@ export const CartesianChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, r
216
262
  getXScale,
217
263
  getYScale,
218
264
  drawingArea: chartRect,
265
+ dataLength,
219
266
  registerAxis,
220
267
  unregisterAxis,
221
268
  getAxisBounds
222
- }), [series, getSeries, getStackedSeriesData, animate, chartWidth, chartHeight, getXAxis, getYAxis, getXScale, getYScale, chartRect, registerAxis, unregisterAxis, getAxisBounds]);
223
- return /*#__PURE__*/_jsx(Box, _objectSpread(_objectSpread({
224
- ref: node => {
225
- // Handle the observe ref, internal ref, and forwarded ref
226
- observe(node);
227
- if (internalSvgRef.current !== node) {
228
- internalSvgRef.current = node;
229
- }
230
- if (ref) {
231
- if (typeof ref === 'function') {
232
- ref(node);
233
- } else {
234
- ref.current = node;
235
- }
236
- }
237
- },
238
- "aria-live": "polite",
239
- as: "svg",
240
- className: cx(enableScrubbing && focusStylesCss, className),
241
- height: height,
242
- role: "figure",
243
- style: style,
244
- tabIndex: enableScrubbing ? 0 : undefined,
245
- width: width
246
- }, props), {}, {
247
- children: /*#__PURE__*/_jsx(CartesianChartProvider, {
248
- value: contextValue,
249
- children: /*#__PURE__*/_jsx(ScrubberProvider, {
250
- enableScrubbing: !!enableScrubbing,
251
- onScrubberPositionChange: onScrubberPositionChange,
252
- svgRef: internalSvgRef,
253
- children: children
254
- })
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
+ }))
255
310
  })
256
- }));
311
+ });
257
312
  }));
258
313
  import "./CartesianChart.css";
package/esm/chart/Path.js CHANGED
@@ -1,4 +1,5 @@
1
- const _excluded = ["animate", "clipRect", "clipOffset", "d"];
1
+ const _excluded = ["d", "transition"],
2
+ _excluded2 = ["animate", "clipRect", "clipOffset", "d", "transition"];
2
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; }
3
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; }
4
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,52 +7,66 @@ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol"
6
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); }
7
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; }
8
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; }
9
- import 'd3-transition';
10
- import { memo, useCallback, useEffect, useId, useRef } from 'react';
11
- import { useValueChanges } from '@coinbase/cds-common/hooks/useValueChanges';
12
- import { interpolatePath } from 'd3-interpolate-path';
13
- import { select } from 'd3-selection';
10
+ import { memo, useId, useMemo } from 'react';
14
11
  import { m as motion } from 'framer-motion';
12
+ import { usePathTransition } from './utils/transition';
15
13
  import { useCartesianChartContext } from './ChartProvider';
14
+
15
+ /**
16
+ * Duration in seconds for path enter transition.
17
+ */
16
18
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
17
- export const Path = /*#__PURE__*/memo(_ref => {
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 => {
18
35
  let {
19
36
  animate: animateProp,
20
37
  clipRect,
21
38
  clipOffset = 0,
22
- d = ''
23
- } = _ref,
24
- pathProps = _objectWithoutProperties(_ref, _excluded);
25
- const pathRef = useRef(null);
39
+ d = '',
40
+ transition
41
+ } = _ref2,
42
+ pathProps = _objectWithoutProperties(_ref2, _excluded2);
26
43
  const clipPathId = useId();
27
44
  const context = useCartesianChartContext();
28
- const rect = clipRect !== null && clipRect !== void 0 ? clipRect : context.drawingArea;
45
+ const rect = clipRect !== undefined ? clipRect : context.drawingArea;
29
46
  const animate = animateProp !== null && animateProp !== void 0 ? animateProp : context.animate;
30
- const {
31
- previousValue: previousPath,
32
- newValue: newPath,
33
- hasChanged,
34
- addPreviousValue
35
- } = useValueChanges(d);
36
- const morphPath = useCallback(() => {
37
- if (!pathRef.current || !newPath || !previousPath) return;
38
- select(pathRef.current).transition().duration(300).attrTween('d', function tween() {
39
- return interpolatePath(previousPath, newPath);
40
- });
41
- }, [previousPath, newPath]);
42
- useEffect(() => {
43
- addPreviousValue(newPath);
44
- if (animate && hasChanged && previousPath) {
45
- morphPath();
46
- }
47
- }, [addPreviousValue, newPath, animate, hasChanged, previousPath, morphPath]);
48
47
 
49
48
  // The clip offset provides extra padding to prevent path from being cut off
50
49
  // Area charts typically use offset=0 for exact clipping, while lines use offset=2 for breathing room
51
50
  const totalOffset = clipOffset * 2; // Applied on both sides
52
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]);
53
68
  return /*#__PURE__*/_jsxs(_Fragment, {
54
- children: [/*#__PURE__*/_jsx("defs", {
69
+ children: [rect !== null && /*#__PURE__*/_jsx("defs", {
55
70
  children: /*#__PURE__*/_jsx("clipPath", {
56
71
  id: clipPathId,
57
72
  children: !animate ? /*#__PURE__*/_jsx("rect", {
@@ -63,27 +78,18 @@ export const Path = /*#__PURE__*/memo(_ref => {
63
78
  animate: "visible",
64
79
  height: rect.height + totalOffset,
65
80
  initial: "hidden",
66
- variants: {
67
- hidden: {
68
- width: 0
69
- },
70
- visible: {
71
- width: rect.width + totalOffset,
72
- transition: {
73
- type: 'spring',
74
- duration: 1,
75
- bounce: 0
76
- }
77
- }
78
- },
81
+ variants: clipPathAnimation,
79
82
  x: rect.x - clipOffset,
80
83
  y: rect.y - clipOffset
81
84
  })
82
85
  })
83
- }), /*#__PURE__*/_jsx("path", _objectSpread({
84
- ref: pathRef,
85
- clipPath: "url(#".concat(clipPathId, ")"),
86
+ }), !animate ? /*#__PURE__*/_jsx("path", _objectSpread({
87
+ clipPath: clipPath,
86
88
  d: d
89
+ }, pathProps)) : /*#__PURE__*/_jsx(AnimatedPath, _objectSpread({
90
+ clipPath: clipPath,
91
+ d: d,
92
+ transition: transition
87
93
  }, pathProps))]
88
94
  });
89
95
  });
@@ -1,4 +1,4 @@
1
- const _excluded = ["as", "color", "label", "display", "alignItems", "font", "hideDot", "disablePulse"],
1
+ const _excluded = ["as", "color", "label", "display", "alignItems", "font", "hideDot"],
2
2
  _excluded2 = ["background", "activeBackground", "width", "justifyContent", "TabComponent", "TabsActiveIndicatorComponent"];
3
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
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; }
@@ -15,11 +15,6 @@ import { Text } from '@coinbase/cds-web/typography';
15
15
  import { m as motion } from 'framer-motion';
16
16
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
17
17
  const MotionBox = motion(Box);
18
- const pulseTransitionConfig = {
19
- duration: 2,
20
- repeat: Infinity,
21
- ease: 'easeInOut'
22
- };
23
18
 
24
19
  // Animated active indicator to support smooth transition of background color
25
20
  export const PeriodSelectorActiveIndicator = /*#__PURE__*/memo(_ref => {
@@ -66,15 +61,10 @@ export const LiveTabLabel = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref2, re
66
61
  display = 'inline-flex',
67
62
  alignItems = 'center',
68
63
  font = 'label1',
69
- hideDot,
70
- disablePulse
64
+ hideDot
71
65
  } = _ref2,
72
66
  props = _objectWithoutProperties(_ref2, _excluded);
73
67
  const Component = as !== null && as !== void 0 ? as : liveTabLabelDefaultElement;
74
- const pulseAnimation = !disablePulse ? {
75
- opacity: [1, 0, 1],
76
- transition: pulseTransitionConfig
77
- } : undefined;
78
68
  return /*#__PURE__*/_jsxs(Text, _objectSpread(_objectSpread({
79
69
  ref: ref,
80
70
  alignItems: alignItems,
@@ -83,12 +73,8 @@ export const LiveTabLabel = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref2, re
83
73
  display: display,
84
74
  font: font
85
75
  }, props), {}, {
86
- children: [!hideDot && /*#__PURE__*/_jsx(motion.span, {
87
- animate: !disablePulse && pulseAnimation,
88
- className: dotBaseCss,
89
- initial: {
90
- opacity: 1
91
- }
76
+ children: [!hideDot && /*#__PURE__*/_jsx("span", {
77
+ className: dotBaseCss
92
78
  }), label]
93
79
  }));
94
80
  }));
@@ -6,17 +6,18 @@ import { GradientArea } from './GradientArea';
6
6
  import { SolidArea } from './SolidArea';
7
7
  import { jsx as _jsx } from "react/jsx-runtime";
8
8
  export const Area = /*#__PURE__*/memo(_ref => {
9
- var _ref2;
10
9
  let {
11
10
  seriesId,
12
- curve = 'linear',
11
+ curve = 'bump',
13
12
  type = 'solid',
14
- AreaComponent: SelectedAreaComponent,
15
- fill: specifiedFill,
13
+ AreaComponent: AreaComponentProp,
14
+ fill: fillProp,
16
15
  fillOpacity = 1,
17
- stroke,
18
- strokeWidth,
19
- baseline
16
+ baseline,
17
+ connectNulls,
18
+ gradient: gradientProp,
19
+ transition,
20
+ animate
20
21
  } = _ref;
21
22
  const {
22
23
  getSeries,
@@ -25,20 +26,10 @@ export const Area = /*#__PURE__*/memo(_ref => {
25
26
  getYScale,
26
27
  getXAxis
27
28
  } = useCartesianChartContext();
28
-
29
- // Get sourceData from series (using stacked data if available)
30
29
  const matchedSeries = useMemo(() => getSeries(seriesId), [seriesId, getSeries]);
31
-
32
- // Check for stacked data first, then fall back to raw data
33
- const sourceData = useMemo(() => {
34
- const stackedData = getSeriesData(seriesId);
35
- if (stackedData) {
36
- return stackedData;
37
- }
38
- return getSeriesData(seriesId) || null;
39
- }, [seriesId, getSeriesData]);
40
-
41
- // Get scales and axes for this series
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]);
42
33
  const xAxis = getXAxis();
43
34
  const xScale = getXScale();
44
35
  const yScale = getYScale(matchedSeries === null || matchedSeries === void 0 ? void 0 : matchedSeries.yAxisId);
@@ -52,34 +43,33 @@ export const Area = /*#__PURE__*/memo(_ref => {
52
43
  xScale,
53
44
  yScale,
54
45
  curve,
55
- xData
46
+ xData,
47
+ connectNulls
56
48
  });
57
- }, [sourceData, xScale, yScale, curve, xAxis === null || xAxis === void 0 ? void 0 : xAxis.data]);
49
+ }, [sourceData, xScale, yScale, curve, xAxis === null || xAxis === void 0 ? void 0 : xAxis.data, connectNulls]);
58
50
  const AreaComponent = useMemo(() => {
59
- if (SelectedAreaComponent) {
60
- return SelectedAreaComponent;
51
+ if (AreaComponentProp) {
52
+ return AreaComponentProp;
61
53
  }
62
54
  switch (type) {
63
- case 'solid':
64
- return SolidArea;
65
55
  case 'dotted':
66
56
  return DottedArea;
67
57
  case 'gradient':
68
- default:
69
58
  return GradientArea;
59
+ case 'solid':
60
+ default:
61
+ return SolidArea;
70
62
  }
71
- }, [SelectedAreaComponent, type]);
72
- if (!xScale || !yScale || !sourceData || !area) {
73
- return null;
74
- }
75
- const fill = (_ref2 = specifiedFill !== null && specifiedFill !== void 0 ? specifiedFill : matchedSeries === null || matchedSeries === void 0 ? void 0 : matchedSeries.color) !== null && _ref2 !== void 0 ? _ref2 : 'var(--color-fgPrimary)';
63
+ }, [AreaComponentProp, type]);
64
+ if (!xScale || !yScale || !sourceData || !area) return;
76
65
  return /*#__PURE__*/_jsx(AreaComponent, {
66
+ animate: animate,
77
67
  baseline: baseline,
78
68
  d: area,
79
69
  fill: fill,
80
70
  fillOpacity: fillOpacity,
81
- stroke: stroke,
82
- strokeWidth: strokeWidth,
71
+ gradient: gradient,
72
+ transition: transition,
83
73
  yAxisId: matchedSeries === null || matchedSeries === void 0 ? void 0 : matchedSeries.yAxisId
84
74
  });
85
75
  });