@coinbase/cds-web-visualization 3.4.0-beta.5 → 3.4.0-beta.6

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 (167) hide show
  1. package/CHANGELOG.md +9 -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 +89 -43
  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 +1 -1
  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 +70 -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 +85 -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 +203 -64
  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/chart.d.ts +27 -7
  87. package/dts/chart/utils/chart.d.ts.map +1 -1
  88. package/dts/chart/utils/context.d.ts +6 -0
  89. package/dts/chart/utils/context.d.ts.map +1 -1
  90. package/dts/chart/utils/gradient.d.ts +104 -0
  91. package/dts/chart/utils/gradient.d.ts.map +1 -0
  92. package/dts/chart/utils/index.d.ts +4 -0
  93. package/dts/chart/utils/index.d.ts.map +1 -1
  94. package/dts/chart/utils/interpolate.d.ts +112 -0
  95. package/dts/chart/utils/interpolate.d.ts.map +1 -0
  96. package/dts/chart/utils/path.d.ts +24 -1
  97. package/dts/chart/utils/path.d.ts.map +1 -1
  98. package/dts/chart/utils/point.d.ts +29 -0
  99. package/dts/chart/utils/point.d.ts.map +1 -1
  100. package/dts/chart/utils/scrubber.d.ts +39 -0
  101. package/dts/chart/utils/scrubber.d.ts.map +1 -0
  102. package/dts/chart/utils/transition.d.ts +65 -0
  103. package/dts/chart/utils/transition.d.ts.map +1 -0
  104. package/esm/chart/CartesianChart.js +140 -85
  105. package/esm/chart/Path.js +51 -46
  106. package/esm/chart/PeriodSelector.js +4 -18
  107. package/esm/chart/area/Area.js +24 -34
  108. package/esm/chart/area/AreaChart.js +24 -15
  109. package/esm/chart/area/DottedArea.js +35 -89
  110. package/esm/chart/area/GradientArea.js +34 -80
  111. package/esm/chart/area/SolidArea.js +29 -11
  112. package/esm/chart/axis/Axis.js +4 -25
  113. package/esm/chart/axis/DefaultAxisTickLabel.js +15 -0
  114. package/esm/chart/axis/XAxis.js +53 -36
  115. package/esm/chart/axis/YAxis.js +55 -32
  116. package/esm/chart/axis/index.js +1 -0
  117. package/esm/chart/bar/Bar.js +3 -1
  118. package/esm/chart/bar/BarChart.js +15 -32
  119. package/esm/chart/bar/BarPlot.js +3 -2
  120. package/esm/chart/bar/BarStack.js +65 -23
  121. package/esm/chart/bar/BarStackGroup.js +7 -17
  122. package/esm/chart/bar/DefaultBar.js +4 -7
  123. package/esm/chart/bar/DefaultBarStack.js +5 -7
  124. package/esm/chart/gradient/Gradient.js +104 -0
  125. package/esm/chart/gradient/index.js +1 -0
  126. package/esm/chart/index.js +2 -1
  127. package/esm/chart/line/DefaultReferenceLineLabel.js +81 -0
  128. package/esm/chart/line/DottedLine.js +38 -17
  129. package/esm/chart/line/Line.js +96 -70
  130. package/esm/chart/line/LineChart.js +18 -6
  131. package/esm/chart/line/ReferenceLine.js +34 -41
  132. package/esm/chart/line/SolidLine.js +36 -15
  133. package/esm/chart/line/index.js +1 -1
  134. package/esm/chart/{line/GradientLine.js → point/DefaultPointLabel.js} +31 -45
  135. package/esm/chart/point/Point.css +2 -0
  136. package/esm/chart/{Point.js → point/Point.js} +66 -57
  137. package/esm/chart/point/index.js +2 -0
  138. package/esm/chart/scrubber/DefaultScrubberBeacon.js +155 -0
  139. package/esm/chart/scrubber/{ScrubberBeaconLabel.js → DefaultScrubberBeaconLabel.js} +23 -10
  140. package/esm/chart/scrubber/DefaultScrubberLabel.js +30 -0
  141. package/esm/chart/scrubber/Scrubber.js +98 -392
  142. package/esm/chart/scrubber/ScrubberBeaconGroup.js +166 -0
  143. package/esm/chart/scrubber/ScrubberBeaconLabelGroup.js +186 -0
  144. package/esm/chart/scrubber/index.js +3 -1
  145. package/esm/chart/text/ChartText.js +13 -19
  146. package/esm/chart/text/{SmartChartTextGroup.js → ChartTextGroup.js} +4 -3
  147. package/esm/chart/text/index.js +1 -1
  148. package/esm/chart/utils/chart.js +29 -3
  149. package/esm/chart/utils/gradient.js +257 -0
  150. package/esm/chart/utils/index.js +4 -0
  151. package/esm/chart/utils/interpolate.js +644 -0
  152. package/esm/chart/utils/path.js +32 -9
  153. package/esm/chart/utils/point.js +69 -0
  154. package/esm/chart/utils/scrubber.js +132 -0
  155. package/esm/chart/utils/transition.js +111 -0
  156. package/package.json +5 -5
  157. package/dts/chart/Point.d.ts +0 -153
  158. package/dts/chart/Point.d.ts.map +0 -1
  159. package/dts/chart/line/GradientLine.d.ts +0 -42
  160. package/dts/chart/line/GradientLine.d.ts.map +0 -1
  161. package/dts/chart/scrubber/ScrubberBeacon.d.ts +0 -93
  162. package/dts/chart/scrubber/ScrubberBeacon.d.ts.map +0 -1
  163. package/dts/chart/scrubber/ScrubberBeaconLabel.d.ts +0 -7
  164. package/dts/chart/scrubber/ScrubberBeaconLabel.d.ts.map +0 -1
  165. package/dts/chart/text/SmartChartTextGroup.d.ts.map +0 -1
  166. package/esm/chart/Point.css +0 -2
  167. package/esm/chart/scrubber/ScrubberBeacon.js +0 -195
@@ -0,0 +1,166 @@
1
+ import { forwardRef, memo, useCallback, useImperativeHandle, useMemo } from 'react';
2
+ import { useRefMap } from '@coinbase/cds-common/hooks/useRefMap';
3
+ import { useCartesianChartContext } from '../ChartProvider';
4
+ import { evaluateGradientAtValue, getGradientConfig, useScrubberContext } from '../utils';
5
+ import { DefaultScrubberBeacon } from './DefaultScrubberBeacon';
6
+ import { jsx as _jsx } from "react/jsx-runtime";
7
+ // Helper component to calculate beacon data for a specific series
8
+ const BeaconWithData = /*#__PURE__*/memo(_ref => {
9
+ let {
10
+ seriesId,
11
+ dataIndex,
12
+ dataX,
13
+ isIdle,
14
+ BeaconComponent,
15
+ idlePulse,
16
+ transitions,
17
+ className,
18
+ style,
19
+ testID,
20
+ beaconRef
21
+ } = _ref;
22
+ const {
23
+ getSeries,
24
+ getSeriesData,
25
+ getXScale,
26
+ getYScale
27
+ } = useCartesianChartContext();
28
+ const series = useMemo(() => getSeries(seriesId), [getSeries, seriesId]);
29
+ const sourceData = useMemo(() => getSeriesData(seriesId), [getSeriesData, seriesId]);
30
+ const gradient = series === null || series === void 0 ? void 0 : series.gradient;
31
+
32
+ // Get dataY from series data
33
+ const dataY = useMemo(() => {
34
+ if (sourceData && dataIndex >= 0 && dataIndex < sourceData.length) {
35
+ const dataValue = sourceData[dataIndex];
36
+ if (typeof dataValue === 'number') {
37
+ return dataValue;
38
+ } else if (Array.isArray(dataValue)) {
39
+ const validValues = dataValue.filter(val => val !== null);
40
+ if (validValues.length >= 1) {
41
+ return validValues[validValues.length - 1];
42
+ }
43
+ }
44
+ }
45
+ return undefined;
46
+ }, [sourceData, dataIndex]);
47
+
48
+ // Evaluate gradient color
49
+ const color = useMemo(() => {
50
+ var _series$color, _series$color2;
51
+ if (dataY === undefined) return (_series$color = series === null || series === void 0 ? void 0 : series.color) !== null && _series$color !== void 0 ? _series$color : 'var(--color-fgPrimary)';
52
+ if (gradient) {
53
+ const xScale = getXScale();
54
+ const yScale = getYScale(series === null || series === void 0 ? void 0 : series.yAxisId);
55
+ if (xScale && yScale) {
56
+ const gradientScale = gradient.axis === 'x' ? xScale : yScale;
57
+ const stops = getGradientConfig(gradient, xScale, yScale);
58
+ if (stops) {
59
+ var _gradient$axis;
60
+ const gradientAxis = (_gradient$axis = gradient.axis) !== null && _gradient$axis !== void 0 ? _gradient$axis : 'y';
61
+ const dataValue = gradientAxis === 'x' ? dataX : dataY;
62
+ const evaluatedColor = evaluateGradientAtValue(stops, dataValue, gradientScale);
63
+ if (evaluatedColor) {
64
+ return evaluatedColor;
65
+ }
66
+ }
67
+ }
68
+ }
69
+ return (_series$color2 = series === null || series === void 0 ? void 0 : series.color) !== null && _series$color2 !== void 0 ? _series$color2 : 'var(--color-fgPrimary)';
70
+ }, [gradient, dataX, dataY, series === null || series === void 0 ? void 0 : series.color, series === null || series === void 0 ? void 0 : series.yAxisId, getXScale, getYScale]);
71
+ if (dataY === undefined) return null;
72
+ return /*#__PURE__*/_jsx(BeaconComponent, {
73
+ ref: beaconRef,
74
+ className: className,
75
+ color: color,
76
+ dataX: dataX,
77
+ dataY: dataY,
78
+ idlePulse: idlePulse,
79
+ isIdle: isIdle,
80
+ seriesId: seriesId,
81
+ style: style,
82
+ testID: testID,
83
+ transitions: transitions
84
+ });
85
+ });
86
+ export const ScrubberBeaconGroup = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref2, ref) => {
87
+ let {
88
+ seriesIds,
89
+ idlePulse,
90
+ transitions,
91
+ BeaconComponent = DefaultScrubberBeacon,
92
+ className,
93
+ style,
94
+ testID
95
+ } = _ref2;
96
+ const ScrubberBeaconRefs = useRefMap();
97
+ const {
98
+ scrubberPosition
99
+ } = useScrubberContext();
100
+ const {
101
+ getXScale,
102
+ getXAxis,
103
+ dataLength,
104
+ series
105
+ } = useCartesianChartContext();
106
+
107
+ // Expose imperative handle with pulse method
108
+ useImperativeHandle(ref, () => ({
109
+ pulse: () => {
110
+ Object.values(ScrubberBeaconRefs.refs).forEach(beaconRef => {
111
+ beaconRef === null || beaconRef === void 0 || beaconRef.pulse();
112
+ });
113
+ }
114
+ }));
115
+ const filteredSeries = useMemo(() => {
116
+ var _series$filter;
117
+ return (_series$filter = series === null || series === void 0 ? void 0 : series.filter(s => seriesIds.includes(s.id))) !== null && _series$filter !== void 0 ? _series$filter : [];
118
+ }, [series, seriesIds]);
119
+ const {
120
+ dataX,
121
+ dataIndex
122
+ } = useMemo(() => {
123
+ const xScale = getXScale();
124
+ const xAxis = getXAxis();
125
+ if (!xScale) return {
126
+ dataX: undefined,
127
+ dataIndex: undefined
128
+ };
129
+ const dataIndex = scrubberPosition !== null && scrubberPosition !== void 0 ? scrubberPosition : Math.max(0, dataLength - 1);
130
+
131
+ // Convert index to actual x value if axis has data
132
+ let dataX;
133
+ if (xAxis !== null && xAxis !== void 0 && xAxis.data && Array.isArray(xAxis.data) && xAxis.data[dataIndex] !== undefined) {
134
+ const dataValue = xAxis.data[dataIndex];
135
+ dataX = typeof dataValue === 'string' ? dataIndex : dataValue;
136
+ } else {
137
+ dataX = dataIndex;
138
+ }
139
+ return {
140
+ dataX,
141
+ dataIndex
142
+ };
143
+ }, [getXScale, getXAxis, scrubberPosition, dataLength]);
144
+ const isIdle = scrubberPosition === undefined;
145
+ const createBeaconRef = useCallback(seriesId => {
146
+ return beaconRef => {
147
+ if (beaconRef) {
148
+ ScrubberBeaconRefs.registerRef(seriesId, beaconRef);
149
+ }
150
+ };
151
+ }, [ScrubberBeaconRefs]);
152
+ if (dataX === undefined || dataIndex === undefined) return null;
153
+ return filteredSeries.map(s => /*#__PURE__*/_jsx(BeaconWithData, {
154
+ BeaconComponent: BeaconComponent,
155
+ beaconRef: createBeaconRef(s.id),
156
+ className: className,
157
+ dataIndex: dataIndex,
158
+ dataX: dataX,
159
+ idlePulse: idlePulse,
160
+ isIdle: isIdle,
161
+ seriesId: s.id,
162
+ style: style,
163
+ testID: testID ? "".concat(testID !== null && testID !== void 0 ? testID : 'beacon', "-").concat(s.id) : undefined,
164
+ transitions: transitions
165
+ }, s.id));
166
+ }));
@@ -0,0 +1,186 @@
1
+ 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; }
2
+ 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; }
3
+ 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; }
4
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
5
+ 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); }
6
+ import { memo, useCallback, useMemo, useState } from 'react';
7
+ import { useCartesianChartContext } from '../ChartProvider';
8
+ import { getPointOnScale, useScrubberContext } from '../utils';
9
+ import { calculateLabelYPositions, getLabelPosition } from '../utils/scrubber';
10
+ import { DefaultScrubberBeaconLabel } from './DefaultScrubberBeaconLabel';
11
+ import { jsx as _jsx } from "react/jsx-runtime";
12
+ const PositionedLabel = /*#__PURE__*/memo(_ref => {
13
+ let {
14
+ index,
15
+ positions,
16
+ position,
17
+ label,
18
+ color,
19
+ seriesId,
20
+ onDimensionsChange,
21
+ BeaconLabelComponent,
22
+ labelHorizontalOffset,
23
+ labelFont
24
+ } = _ref;
25
+ const pos = positions[index];
26
+
27
+ // Don't render if position is null (invalid data)
28
+ if (!pos) {
29
+ return null;
30
+ }
31
+ const x = pos.x;
32
+ const y = pos.y;
33
+ const dx = position === 'right' ? labelHorizontalOffset : -labelHorizontalOffset;
34
+ const horizontalAlignment = position === 'right' ? 'left' : 'right';
35
+ return /*#__PURE__*/_jsx(BeaconLabelComponent, {
36
+ color: color,
37
+ dx: dx,
38
+ font: labelFont,
39
+ horizontalAlignment: horizontalAlignment,
40
+ label: label,
41
+ onDimensionsChange: d => onDimensionsChange(seriesId, d),
42
+ seriesId: seriesId,
43
+ x: x,
44
+ y: y
45
+ });
46
+ });
47
+ export const ScrubberBeaconLabelGroup = /*#__PURE__*/memo(_ref2 => {
48
+ let {
49
+ labels,
50
+ labelMinGap = 4,
51
+ labelHorizontalOffset = 16,
52
+ labelFont,
53
+ BeaconLabelComponent = DefaultScrubberBeaconLabel
54
+ } = _ref2;
55
+ const {
56
+ getSeries,
57
+ getSeriesData,
58
+ getXScale,
59
+ getYScale,
60
+ getXAxis,
61
+ drawingArea,
62
+ dataLength
63
+ } = useCartesianChartContext();
64
+ const {
65
+ scrubberPosition
66
+ } = useScrubberContext();
67
+ const [labelDimensions, setLabelDimensions] = useState({});
68
+ const handleDimensionsChange = useCallback((seriesId, dimensions) => {
69
+ setLabelDimensions(prev => {
70
+ const existing = prev[seriesId];
71
+ if (existing && existing.width === dimensions.width && existing.height === dimensions.height) {
72
+ return prev;
73
+ }
74
+ return _objectSpread(_objectSpread({}, prev), {}, {
75
+ [seriesId]: dimensions
76
+ });
77
+ });
78
+ }, []);
79
+ const seriesInfo = useMemo(() => {
80
+ return labels.map(label => {
81
+ const series = getSeries(label.seriesId);
82
+ if (!series) return null;
83
+ const sourceData = getSeriesData(label.seriesId);
84
+ const yScale = getYScale(series.yAxisId);
85
+ return {
86
+ seriesId: label.seriesId,
87
+ sourceData,
88
+ yScale
89
+ };
90
+ }).filter(info => info !== null);
91
+ }, [labels, getSeries, getSeriesData, getYScale]);
92
+ const xScale = getXScale();
93
+ const xAxis = getXAxis();
94
+ const dataIndex = useMemo(() => {
95
+ return scrubberPosition !== null && scrubberPosition !== void 0 ? scrubberPosition : Math.max(0, dataLength - 1);
96
+ }, [scrubberPosition, dataLength]);
97
+ const dataX = useMemo(() => {
98
+ if (xAxis !== null && xAxis !== void 0 && xAxis.data && Array.isArray(xAxis.data) && xAxis.data[dataIndex] !== undefined) {
99
+ const dataValue = xAxis.data[dataIndex];
100
+ return typeof dataValue === 'string' ? dataIndex : dataValue;
101
+ }
102
+ return dataIndex;
103
+ }, [xAxis, dataIndex]);
104
+ const allLabelPositions = useMemo(() => {
105
+ if (!xScale || dataX === undefined) return [];
106
+ const sharedPixelX = getPointOnScale(dataX, xScale);
107
+ const desiredPositions = seriesInfo.map(info => {
108
+ let dataY;
109
+ if (info.yScale) {
110
+ if (info.sourceData && dataIndex !== undefined && dataIndex >= 0 && dataIndex < info.sourceData.length) {
111
+ const dataValue = info.sourceData[dataIndex];
112
+ if (Array.isArray(dataValue)) {
113
+ const validValues = dataValue.filter(val => val !== null);
114
+ if (validValues.length >= 1) {
115
+ dataY = validValues[validValues.length - 1];
116
+ }
117
+ }
118
+ }
119
+ }
120
+ if (dataY !== undefined && info.yScale) {
121
+ return {
122
+ seriesId: info.seriesId,
123
+ x: sharedPixelX,
124
+ desiredY: getPointOnScale(dataY, info.yScale)
125
+ };
126
+ }
127
+
128
+ // Return null for invalid data
129
+ return null;
130
+ });
131
+ const maxLabelHeight = Math.max(...Object.values(labelDimensions).map(dim => dim.height));
132
+ const maxLabelWidth = Math.max(...Object.values(labelDimensions).map(dim => dim.width));
133
+
134
+ // Only apply collision detection to valid positions
135
+ const validPositions = desiredPositions.filter(pos => pos !== null);
136
+
137
+ // Convert to LabelDimension format expected by utility
138
+ const dimensions = validPositions.map(pos => {
139
+ var _trackedDimensions$wi, _trackedDimensions$he;
140
+ const trackedDimensions = labelDimensions[pos.seriesId];
141
+ return {
142
+ seriesId: pos.seriesId,
143
+ width: (_trackedDimensions$wi = trackedDimensions === null || trackedDimensions === void 0 ? void 0 : trackedDimensions.width) !== null && _trackedDimensions$wi !== void 0 ? _trackedDimensions$wi : maxLabelWidth,
144
+ height: (_trackedDimensions$he = trackedDimensions === null || trackedDimensions === void 0 ? void 0 : trackedDimensions.height) !== null && _trackedDimensions$he !== void 0 ? _trackedDimensions$he : maxLabelHeight,
145
+ preferredX: pos.x,
146
+ preferredY: pos.desiredY
147
+ };
148
+ });
149
+
150
+ // Calculate Y positions with collision resolution for valid positions only
151
+ const yPositions = calculateLabelYPositions(dimensions, drawingArea, maxLabelHeight, labelMinGap);
152
+
153
+ // Return all positions (including null ones)
154
+ return desiredPositions.map(pos => {
155
+ var _yPositions$get;
156
+ if (!pos) return null;
157
+ return {
158
+ seriesId: pos.seriesId,
159
+ x: pos.x,
160
+ y: (_yPositions$get = yPositions.get(pos.seriesId)) !== null && _yPositions$get !== void 0 ? _yPositions$get : pos.desiredY
161
+ };
162
+ });
163
+ }, [seriesInfo, dataIndex, dataX, xScale, labelDimensions, drawingArea, labelMinGap]);
164
+ const currentPosition = useMemo(() => {
165
+ if (!xScale || dataX === undefined) return 'right';
166
+ const pixelX = getPointOnScale(dataX, xScale);
167
+ const maxWidth = Math.max(...Object.values(labelDimensions).map(dim => dim.width));
168
+ return getLabelPosition(pixelX, maxWidth, drawingArea, labelHorizontalOffset);
169
+ }, [dataX, xScale, labelDimensions, drawingArea, labelHorizontalOffset]);
170
+ return seriesInfo.map((info, index) => {
171
+ const labelInfo = labels.find(label => label.seriesId === info.seriesId);
172
+ if (!labelInfo) return;
173
+ return /*#__PURE__*/_jsx(PositionedLabel, {
174
+ BeaconLabelComponent: BeaconLabelComponent,
175
+ color: labelInfo.color,
176
+ index: index,
177
+ label: labelInfo.label,
178
+ labelFont: labelFont,
179
+ labelHorizontalOffset: labelHorizontalOffset,
180
+ onDimensionsChange: handleDimensionsChange,
181
+ position: currentPosition,
182
+ positions: allLabelPositions,
183
+ seriesId: info.seriesId
184
+ }, info.seriesId);
185
+ });
186
+ });
@@ -1,2 +1,4 @@
1
- // Only export Scrubber component
1
+ export * from './DefaultScrubberBeacon';
2
+ export * from './DefaultScrubberBeaconLabel';
3
+ export * from './DefaultScrubberLabel';
2
4
  export * from './Scrubber';
@@ -67,9 +67,9 @@ export const ChartText = /*#__PURE__*/memo(_ref => {
67
67
  fontFamily,
68
68
  fontSize,
69
69
  fontWeight,
70
- elevation,
70
+ elevated,
71
71
  color = 'var(--color-fgMuted)',
72
- background = elevation && elevation > 0 ? 'var(--color-bg)' : 'transparent',
72
+ background = elevated ? 'var(--color-bg)' : 'transparent',
73
73
  borderRadius,
74
74
  inset: insetInput,
75
75
  onDimensionsChange,
@@ -112,7 +112,7 @@ export const ChartText = /*#__PURE__*/memo(_ref => {
112
112
  };
113
113
  }
114
114
  const parentBounds = bounds !== null && bounds !== void 0 ? bounds : fullChartBounds;
115
- if (!textBBox || !parentBounds || parentBounds.width <= 0 || parentBounds.height <= 0) {
115
+ if (!backgroundRectDimensions || !parentBounds || parentBounds.width <= 0 || parentBounds.height <= 0) {
116
116
  return {
117
117
  x: 0,
118
118
  y: 0
@@ -120,25 +120,21 @@ export const ChartText = /*#__PURE__*/memo(_ref => {
120
120
  }
121
121
  let x = 0;
122
122
  let y = 0;
123
-
124
- // X-axis overflow
125
- if (textBBox.x < parentBounds.x) {
126
- x = parentBounds.x - textBBox.x; // positive = shift right
127
- } else if (textBBox.x + textBBox.width > parentBounds.x + parentBounds.width) {
128
- x = parentBounds.x + parentBounds.width - (textBBox.x + textBBox.width); // negative = shift left
123
+ if (backgroundRectDimensions.x < parentBounds.x) {
124
+ x = parentBounds.x - backgroundRectDimensions.x; // positive = shift right
125
+ } else if (backgroundRectDimensions.x + backgroundRectDimensions.width > parentBounds.x + parentBounds.width) {
126
+ x = parentBounds.x + parentBounds.width - (backgroundRectDimensions.x + backgroundRectDimensions.width); // negative = shift left
129
127
  }
130
-
131
- // Y-axis overflow
132
- if (textBBox.y < parentBounds.y) {
133
- y = parentBounds.y - textBBox.y; // positive = shift down
134
- } else if (textBBox.y + textBBox.height > parentBounds.y + parentBounds.height) {
135
- y = parentBounds.y + parentBounds.height - (textBBox.y + textBBox.height); // negative = shift up
128
+ if (backgroundRectDimensions.y < parentBounds.y) {
129
+ y = parentBounds.y - backgroundRectDimensions.y; // positive = shift down
130
+ } else if (backgroundRectDimensions.y + backgroundRectDimensions.height > parentBounds.y + parentBounds.height) {
131
+ y = parentBounds.y + parentBounds.height - (backgroundRectDimensions.y + backgroundRectDimensions.height); // negative = shift up
136
132
  }
137
133
  return {
138
134
  x,
139
135
  y
140
136
  };
141
- }, [textBBox, fullChartBounds, bounds, disableRepositioning]);
137
+ }, [backgroundRectDimensions, fullChartBounds, bounds, disableRepositioning]);
142
138
 
143
139
  // Compose the final reported rect including any overflow translation applied
144
140
  const reportedRect = useMemo(() => {
@@ -150,8 +146,6 @@ export const ChartText = /*#__PURE__*/memo(_ref => {
150
146
  height: backgroundRectDimensions.height
151
147
  };
152
148
  }, [backgroundRectDimensions, overflowAmount.x, overflowAmount.y]);
153
-
154
- // send latest calculated dimensions (adjusted for translation) to parent
155
149
  useEffect(() => {
156
150
  if (onDimensionsChange && reportedRect !== null) {
157
151
  onDimensionsChange(reportedRect);
@@ -203,7 +197,7 @@ export const ChartText = /*#__PURE__*/memo(_ref => {
203
197
  as: "rect",
204
198
  className: classNames === null || classNames === void 0 ? void 0 : classNames.backgroundRect,
205
199
  fill: background,
206
- filter: elevation && elevation > 0 ? "drop-shadow(var(--shadow-elevation".concat(elevation, "))") : undefined,
200
+ filter: elevated ? 'drop-shadow(var(--shadow-elevation1))' : undefined,
207
201
  height: backgroundRectDimensions === null || backgroundRectDimensions === void 0 ? void 0 : backgroundRectDimensions.height,
208
202
  rx: borderRadius,
209
203
  ry: borderRadius,
@@ -36,12 +36,13 @@ const EPSILON_PX = 0.5;
36
36
  *
37
37
  * The component focuses solely on overlap prevention logic for better separation of concerns.
38
38
  */
39
- export const SmartChartTextGroup = /*#__PURE__*/memo(_ref => {
39
+ export const ChartTextGroup = /*#__PURE__*/memo(_ref => {
40
40
  let {
41
41
  labels,
42
42
  minGap = 8,
43
43
  prioritizeEndLabels = true,
44
- chartTextProps
44
+ chartTextProps,
45
+ LabelComponent = ChartText
45
46
  } = _ref;
46
47
  const [boundingBoxes, setBoundingBoxes] = useState(new Map());
47
48
  const _ref2 = chartTextProps !== null && chartTextProps !== void 0 ? chartTextProps : {},
@@ -213,7 +214,7 @@ export const SmartChartTextGroup = /*#__PURE__*/memo(_ref => {
213
214
  display: 'none'
214
215
  } : {})
215
216
  };
216
- return /*#__PURE__*/_jsx(ChartText, _objectSpread(_objectSpread(_objectSpread({
217
+ return /*#__PURE__*/_jsx(LabelComponent, _objectSpread(_objectSpread(_objectSpread({
217
218
  x: labelData.x,
218
219
  y: labelData.y
219
220
  }, restChartTextProps), labelData.chartTextProps), {}, {
@@ -1,4 +1,4 @@
1
1
  // codegen:start {preset: barrel, include: ./*.tsx, exclude: ./__stories__/*.tsx}
2
2
  export * from './ChartText';
3
- export * from './SmartChartTextGroup';
3
+ export * from './ChartTextGroup';
4
4
  // codegen:end
@@ -19,13 +19,13 @@ export const getChartDomain = (series, min, max) => {
19
19
  return domain;
20
20
  }
21
21
  if (series.length > 0) {
22
- const maxDataLength = Math.max(...series.map(s => {
22
+ const dataLength = Math.max(...series.map(s => {
23
23
  var _s$data;
24
24
  return ((_s$data = s.data) === null || _s$data === void 0 ? void 0 : _s$data.length) || 0;
25
25
  }));
26
- if (maxDataLength > 0) {
26
+ if (dataLength > 0) {
27
27
  if (domain.min === undefined) domain.min = 0;
28
- if (domain.max === undefined) domain.max = maxDataLength - 1;
28
+ if (domain.max === undefined) domain.max = dataLength - 1;
29
29
  }
30
30
  }
31
31
  return domain;
@@ -111,6 +111,32 @@ export const getStackedSeriesData = series => {
111
111
  return stackedDataMap;
112
112
  };
113
113
 
114
+ /**
115
+ * Extracts line data values from series data that may contain tuples.
116
+ * For tuple data [[baseline, value]], extracts the last value.
117
+ * For numeric data [value], returns as-is.
118
+ *
119
+ * @param data - Array of numbers, tuples, or null values
120
+ * @returns Array of numbers or null values
121
+ */
122
+ export const getLineData = data => {
123
+ if (!data) return [];
124
+
125
+ // Check if this is tuple data by finding first non-null entry
126
+ const firstNonNull = data.find(d => d !== null);
127
+ if (Array.isArray(firstNonNull)) {
128
+ return data.map(d => {
129
+ var _d$at;
130
+ if (d === null) return null;
131
+ if (Array.isArray(d)) return (_d$at = d.at(-1)) !== null && _d$at !== void 0 ? _d$at : null;
132
+ return d;
133
+ });
134
+ }
135
+
136
+ // Already numeric data
137
+ return data;
138
+ };
139
+
114
140
  /**
115
141
  * Calculates the range of a chart from series data.
116
142
  * Range represents the range of y-values from the data.