@coinbase/cds-mobile-visualization 3.4.0-beta.23 → 3.4.0-beta.25
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.
- package/CHANGELOG.md +16 -0
- package/dts/chart/CartesianChart.d.ts +19 -0
- package/dts/chart/CartesianChart.d.ts.map +1 -1
- package/dts/chart/Path.d.ts +2 -1
- package/dts/chart/Path.d.ts.map +1 -1
- package/dts/chart/bar/Bar.d.ts +18 -54
- package/dts/chart/bar/Bar.d.ts.map +1 -1
- package/dts/chart/bar/BarChart.d.ts +2 -2
- package/dts/chart/bar/BarPlot.d.ts.map +1 -1
- package/dts/chart/bar/BarStack.d.ts +4 -4
- package/dts/chart/bar/BarStack.d.ts.map +1 -1
- package/dts/chart/bar/DefaultBar.d.ts.map +1 -1
- package/dts/chart/bar/DefaultBarStack.d.ts.map +1 -1
- package/dts/chart/line/LineChart.d.ts +17 -3
- package/dts/chart/line/LineChart.d.ts.map +1 -1
- package/dts/chart/point/Point.d.ts +2 -1
- package/dts/chart/point/Point.d.ts.map +1 -1
- package/dts/chart/scrubber/Scrubber.d.ts +4 -2
- package/dts/chart/scrubber/Scrubber.d.ts.map +1 -1
- package/dts/chart/scrubber/ScrubberAccessibilityView.d.ts +12 -0
- package/dts/chart/scrubber/ScrubberAccessibilityView.d.ts.map +1 -0
- package/dts/chart/utils/bar.d.ts +155 -0
- package/dts/chart/utils/bar.d.ts.map +1 -1
- package/dts/chart/utils/chart.d.ts +2 -1
- package/dts/chart/utils/chart.d.ts.map +1 -1
- package/dts/chart/utils/path.d.ts.map +1 -1
- package/dts/sparkline/Sparkline.d.ts +2 -1
- package/dts/sparkline/Sparkline.d.ts.map +1 -1
- package/dts/sparkline/SparklineArea.d.ts +2 -1
- package/dts/sparkline/SparklineArea.d.ts.map +1 -1
- package/dts/sparkline/SparklineGradient.d.ts +2 -1
- package/dts/sparkline/SparklineGradient.d.ts.map +1 -1
- package/dts/sparkline/sparkline-interactive/SparklineInteractive.d.ts +2 -1
- package/dts/sparkline/sparkline-interactive/SparklineInteractive.d.ts.map +1 -1
- package/esm/chart/CartesianChart.js +39 -14
- package/esm/chart/__stories__/CartesianChart.stories.js +10 -0
- package/esm/chart/__stories__/ChartAccessibility.stories.js +721 -0
- package/esm/chart/area/__stories__/AreaChart.stories.js +17 -3
- package/esm/chart/axis/__stories__/Axis.stories.js +65 -48
- package/esm/chart/bar/Bar.js +8 -14
- package/esm/chart/bar/BarChart.js +7 -7
- package/esm/chart/bar/BarPlot.js +37 -46
- package/esm/chart/bar/BarStack.js +71 -604
- package/esm/chart/bar/DefaultBar.js +11 -18
- package/esm/chart/bar/DefaultBarStack.js +12 -21
- package/esm/chart/bar/__stories__/BarChart.stories.js +110 -6
- package/esm/chart/line/LineChart.js +22 -1
- package/esm/chart/line/__stories__/LineChart.stories.js +84 -46
- package/esm/chart/scrubber/ScrubberAccessibilityView.js +177 -0
- package/esm/chart/scrubber/__stories__/Scrubber.stories.js +57 -5
- package/esm/chart/utils/bar.js +775 -0
- package/esm/chart/utils/chart.js +2 -1
- package/esm/chart/utils/path.js +5 -12
- package/esm/sparkline/Sparkline.js +2 -1
- package/esm/sparkline/SparklineArea.js +2 -1
- package/esm/sparkline/SparklineGradient.js +2 -1
- package/esm/sparkline/sparkline-interactive/SparklineInteractive.js +2 -1
- package/package.json +5 -5
|
@@ -1,17 +1,22 @@
|
|
|
1
|
+
import { useCallback } from 'react';
|
|
1
2
|
import { Example, ExampleScreen } from '@coinbase/cds-mobile/examples/ExampleScreen';
|
|
2
3
|
import { useTheme } from '@coinbase/cds-mobile/hooks/useTheme';
|
|
3
4
|
import { DottedLine } from '../../line';
|
|
4
5
|
import { Scrubber } from '../../scrubber/Scrubber';
|
|
5
6
|
import { AreaChart } from '..';
|
|
6
7
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
8
|
+
const basicData = [24, 13, 98, 39, 48, 38, 43];
|
|
7
9
|
const BasicExample = () => {
|
|
10
|
+
const getScrubberAccessibilityLabel = useCallback(index => "Point " + (index + 1) + ": " + basicData[index], []);
|
|
8
11
|
return /*#__PURE__*/_jsx(AreaChart, {
|
|
9
12
|
enableScrubbing: true,
|
|
10
13
|
showYAxis: true,
|
|
14
|
+
accessibilityLabel: "Area chart with " + basicData.length + " data points. Swipe to navigate.",
|
|
15
|
+
getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
|
|
11
16
|
height: 400,
|
|
12
17
|
series: [{
|
|
13
18
|
id: 'pageViews',
|
|
14
|
-
data:
|
|
19
|
+
data: basicData
|
|
15
20
|
}],
|
|
16
21
|
yAxis: {
|
|
17
22
|
showGrid: true,
|
|
@@ -22,21 +27,26 @@ const BasicExample = () => {
|
|
|
22
27
|
children: /*#__PURE__*/_jsx(Scrubber, {})
|
|
23
28
|
});
|
|
24
29
|
};
|
|
30
|
+
const currentRewardsData = [100, 150, 200, 280, 380, 500, 650, 820, 1020, 1250, 1510, 1800, 2120, 2470, 2850, 3260, 3700, 4170];
|
|
31
|
+
const potentialRewardsData = [150, 220, 300, 400, 520, 660, 820, 1000, 1200, 1420, 1660, 1920, 2200, 2500, 2820, 3160, 3520, 3900];
|
|
25
32
|
const StackedExample = () => {
|
|
26
33
|
const theme = useTheme();
|
|
34
|
+
const getScrubberAccessibilityLabel = useCallback(index => "Point " + (index + 1) + ": current " + currentRewardsData[index] + ", potential " + potentialRewardsData[index], []);
|
|
27
35
|
return /*#__PURE__*/_jsx(AreaChart, {
|
|
28
36
|
enableScrubbing: true,
|
|
29
37
|
showLines: true,
|
|
30
38
|
stacked: true,
|
|
39
|
+
accessibilityLabel: "Stacked rewards chart with " + currentRewardsData.length + " data points. Swipe to navigate.",
|
|
31
40
|
curve: "natural",
|
|
41
|
+
getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
|
|
32
42
|
height: 256,
|
|
33
43
|
series: [{
|
|
34
44
|
id: 'currentRewards',
|
|
35
|
-
data:
|
|
45
|
+
data: currentRewardsData,
|
|
36
46
|
color: theme.color.fg
|
|
37
47
|
}, {
|
|
38
48
|
id: 'potentialRewards',
|
|
39
|
-
data:
|
|
49
|
+
data: potentialRewardsData,
|
|
40
50
|
color: theme.color.fgPositive,
|
|
41
51
|
type: 'dotted',
|
|
42
52
|
LineComponent: DottedLine
|
|
@@ -59,6 +69,8 @@ const AreaChartStories = () => {
|
|
|
59
69
|
enableScrubbing: true,
|
|
60
70
|
showLines: true,
|
|
61
71
|
showYAxis: true,
|
|
72
|
+
accessibilityLabel: "Area chart with negative values. 7 data points. Swipe to navigate.",
|
|
73
|
+
getScrubberAccessibilityLabel: index => "Point " + (index + 1) + ": " + [24, 13, -98, 39, 48, 38, 43][index],
|
|
62
74
|
height: 150,
|
|
63
75
|
series: [{
|
|
64
76
|
id: 'pageViews',
|
|
@@ -101,6 +113,8 @@ const AreaChartStories = () => {
|
|
|
101
113
|
showLines: true,
|
|
102
114
|
showXAxis: true,
|
|
103
115
|
showYAxis: true,
|
|
116
|
+
accessibilityLabel: "Volume by asset. 5 data points. Swipe to navigate.",
|
|
117
|
+
getScrubberAccessibilityLabel: index => ['BTC', 'ETH', 'SOL', 'DOGE', 'ADA'][index] + ": " + [68, 54, 43, 29, 18][index] + "%",
|
|
104
118
|
height: 280,
|
|
105
119
|
layout: "horizontal",
|
|
106
120
|
series: [{
|
|
@@ -53,10 +53,14 @@ const Simple = () => {
|
|
|
53
53
|
const pageViews = data.map(d => d.pv);
|
|
54
54
|
const pageNames = data.map(d => d.name);
|
|
55
55
|
const pageUniqueVisitors = data.map(d => d.uv);
|
|
56
|
+
const chartAccessibilityLabel = "Page views and unique visitors across " + pageNames.length + " pages. Swipe to navigate.";
|
|
57
|
+
const getScrubberAccessibilityLabel = useCallback(index => pageNames[index] + ": " + pageViews[index] + " views, " + pageUniqueVisitors[index] + " unique visitors", [pageNames, pageViews, pageUniqueVisitors]);
|
|
56
58
|
return /*#__PURE__*/_jsx(LineChart, {
|
|
57
59
|
enableScrubbing: true,
|
|
58
60
|
showXAxis: true,
|
|
59
61
|
showYAxis: true,
|
|
62
|
+
accessibilityLabel: chartAccessibilityLabel,
|
|
63
|
+
getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
|
|
60
64
|
height: defaultChartHeight,
|
|
61
65
|
inset: 32,
|
|
62
66
|
series: [{
|
|
@@ -97,8 +101,8 @@ const Simple = () => {
|
|
|
97
101
|
};
|
|
98
102
|
const TimeOfDayAxesExample = () => {
|
|
99
103
|
const theme = useTheme();
|
|
100
|
-
const lineA = [5, 5, 10, 90, 85, 70, 30, 25, 25];
|
|
101
|
-
const lineB = [90, 85, 70, 25, 23, 40, 45, 40, 50];
|
|
104
|
+
const lineA = useMemo(() => [5, 5, 10, 90, 85, 70, 30, 25, 25], []);
|
|
105
|
+
const lineB = useMemo(() => [90, 85, 70, 25, 23, 40, 45, 40, 50], []);
|
|
102
106
|
const timeData = useMemo(() => [new Date(2023, 7, 31), new Date(2023, 7, 31, 12), new Date(2023, 8, 1), new Date(2023, 8, 1, 12), new Date(2023, 8, 2), new Date(2023, 8, 2, 12), new Date(2023, 8, 3), new Date(2023, 8, 3, 12), new Date(2023, 8, 4)].map(d => d.getTime()), []);
|
|
103
107
|
const dateFormatter = useCallback(index => {
|
|
104
108
|
return new Date(timeData[index]).toLocaleDateString('en-US', {
|
|
@@ -117,8 +121,12 @@ const TimeOfDayAxesExample = () => {
|
|
|
117
121
|
const dateTicks = useMemo(() => {
|
|
118
122
|
return timeData.map((d, index) => index).filter(d => d % 2 === 0);
|
|
119
123
|
}, [timeData]);
|
|
124
|
+
const chartAccessibilityLabel = "Chart with " + lineA.length + " data points. Swipe to navigate.";
|
|
125
|
+
const getScrubberAccessibilityLabel = useCallback(index => "Point " + (index + 1) + ": lineA " + lineA[index] + ", lineB " + lineB[index], [lineA, lineB]);
|
|
120
126
|
return /*#__PURE__*/_jsxs(LineChart, {
|
|
121
127
|
enableScrubbing: true,
|
|
128
|
+
accessibilityLabel: chartAccessibilityLabel,
|
|
129
|
+
getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
|
|
122
130
|
height: defaultChartHeight,
|
|
123
131
|
series: [{
|
|
124
132
|
id: 'lineA',
|
|
@@ -150,51 +158,57 @@ const TimeOfDayAxesExample = () => {
|
|
|
150
158
|
}), /*#__PURE__*/_jsx(Scrubber, {})]
|
|
151
159
|
});
|
|
152
160
|
};
|
|
153
|
-
const
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
161
|
+
const multipleYAxesData = [1, 10, 30, 50, 70, 90, 100];
|
|
162
|
+
const MultipleYAxesExample = () => {
|
|
163
|
+
const getScrubberAccessibilityLabel = useCallback(index => "Point " + (index + 1) + ": linear " + multipleYAxesData[index] + ", log " + multipleYAxesData[index], []);
|
|
164
|
+
return /*#__PURE__*/_jsxs(CartesianChart, {
|
|
165
|
+
enableScrubbing: true,
|
|
166
|
+
accessibilityLabel: "Chart with linear and log axes. 7 data points. Swipe to navigate.",
|
|
167
|
+
getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
|
|
168
|
+
height: defaultChartHeight,
|
|
169
|
+
series: [{
|
|
170
|
+
id: 'linear',
|
|
171
|
+
yAxisId: 'linearAxis',
|
|
172
|
+
data: multipleYAxesData,
|
|
173
|
+
label: 'linear'
|
|
174
|
+
}, {
|
|
175
|
+
id: 'log',
|
|
176
|
+
yAxisId: 'logAxis',
|
|
177
|
+
data: multipleYAxesData,
|
|
178
|
+
label: 'log'
|
|
179
|
+
}],
|
|
180
|
+
xAxis: {
|
|
181
|
+
data: multipleYAxesData
|
|
182
|
+
},
|
|
183
|
+
yAxis: [{
|
|
184
|
+
id: 'linearAxis',
|
|
185
|
+
scaleType: 'linear'
|
|
186
|
+
}, {
|
|
187
|
+
id: 'logAxis',
|
|
188
|
+
scaleType: 'log'
|
|
189
|
+
}],
|
|
190
|
+
children: [/*#__PURE__*/_jsx(XAxis, {
|
|
191
|
+
showLine: true,
|
|
192
|
+
showTickMarks: true
|
|
193
|
+
}), /*#__PURE__*/_jsx(YAxis, {
|
|
194
|
+
showLine: true,
|
|
195
|
+
showTickMarks: true,
|
|
196
|
+
axisId: "logAxis",
|
|
197
|
+
position: "left"
|
|
198
|
+
}), /*#__PURE__*/_jsx(YAxis, {
|
|
199
|
+
showLine: true,
|
|
200
|
+
showTickMarks: true,
|
|
201
|
+
axisId: "linearAxis",
|
|
202
|
+
position: "left"
|
|
203
|
+
}), /*#__PURE__*/_jsx(Line, {
|
|
204
|
+
curve: "natural",
|
|
205
|
+
seriesId: "linear"
|
|
206
|
+
}), /*#__PURE__*/_jsx(Line, {
|
|
207
|
+
curve: "natural",
|
|
208
|
+
seriesId: "log"
|
|
209
|
+
}), /*#__PURE__*/_jsx(Scrubber, {})]
|
|
210
|
+
});
|
|
211
|
+
};
|
|
198
212
|
const AxesOnAllSides = () => {
|
|
199
213
|
const theme = useTheme();
|
|
200
214
|
const data = [30, 45, 60, 80, 55, 40, 65];
|
|
@@ -298,9 +312,12 @@ const DomainLimitType = _ref => {
|
|
|
298
312
|
let {
|
|
299
313
|
limit
|
|
300
314
|
} = _ref;
|
|
301
|
-
const exponentialData = [1, 2, 4, 8, 15, 30, 65, 140, 280, 580, 1200, 2400, 4800, 9500, 19000, 38000, 75000, 150000];
|
|
315
|
+
const exponentialData = useMemo(() => [1, 2, 4, 8, 15, 30, 65, 140, 280, 580, 1200, 2400, 4800, 9500, 19000, 38000, 75000, 150000], []);
|
|
316
|
+
const getScrubberAccessibilityLabel = useCallback(index => "Point " + (index + 1) + ": " + exponentialData[index], [exponentialData]);
|
|
302
317
|
return /*#__PURE__*/_jsxs(CartesianChart, {
|
|
303
318
|
enableScrubbing: true,
|
|
319
|
+
accessibilityLabel: "Exponential growth chart with " + exponentialData.length + " data points. Swipe to navigate.",
|
|
320
|
+
getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
|
|
304
321
|
height: defaultChartHeight,
|
|
305
322
|
series: [{
|
|
306
323
|
id: 'growthLinear',
|
package/esm/chart/bar/Bar.js
CHANGED
|
@@ -34,6 +34,7 @@ export const Bar = /*#__PURE__*/memo(_ref => {
|
|
|
34
34
|
borderRadius = 4,
|
|
35
35
|
roundTop = true,
|
|
36
36
|
roundBottom = true,
|
|
37
|
+
minSize,
|
|
37
38
|
transitions,
|
|
38
39
|
transition
|
|
39
40
|
} = _ref;
|
|
@@ -41,28 +42,21 @@ export const Bar = /*#__PURE__*/memo(_ref => {
|
|
|
41
42
|
const {
|
|
42
43
|
layout
|
|
43
44
|
} = useCartesianChartContext();
|
|
44
|
-
|
|
45
|
-
// Use theme color as default if no fill is provided
|
|
46
|
-
const effectiveFill = fill != null ? fill : theme.color.fgPrimary;
|
|
47
|
-
const borderRadiusPixels = useMemo(() => borderRadius != null ? borderRadius : 0, [borderRadius]);
|
|
48
45
|
const barPath = useMemo(() => {
|
|
49
|
-
return getBarPath(x, y, width, height,
|
|
50
|
-
}, [x, y, width, height,
|
|
51
|
-
const
|
|
52
|
-
if (!barPath)
|
|
53
|
-
return null;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// Always use the BarComponent for rendering
|
|
46
|
+
return getBarPath(x, y, width, height, borderRadius, roundTop, roundBottom, layout);
|
|
47
|
+
}, [x, y, width, height, borderRadius, roundTop, roundBottom, layout]);
|
|
48
|
+
const origin = useMemo(() => originProp != null ? originProp : layout === 'horizontal' ? x : y + height, [originProp, layout, x, y, height]);
|
|
49
|
+
if (!barPath) return;
|
|
57
50
|
return /*#__PURE__*/_jsx(BarComponent, {
|
|
58
51
|
borderRadius: borderRadius,
|
|
59
52
|
d: barPath,
|
|
60
53
|
dataX: dataX,
|
|
61
54
|
dataY: dataY,
|
|
62
|
-
fill:
|
|
55
|
+
fill: fill != null ? fill : theme.color.fgPrimary,
|
|
63
56
|
fillOpacity: fillOpacity,
|
|
64
57
|
height: height,
|
|
65
|
-
|
|
58
|
+
minSize: minSize,
|
|
59
|
+
origin: origin,
|
|
66
60
|
roundBottom: roundBottom,
|
|
67
61
|
roundTop: roundTop,
|
|
68
62
|
seriesId: seriesId,
|
|
@@ -44,9 +44,9 @@ export const BarChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) =>
|
|
|
44
44
|
});
|
|
45
45
|
}, [seriesProp, stacked]);
|
|
46
46
|
const seriesIds = useMemo(() => series == null ? void 0 : series.map(s => s.id), [series]);
|
|
47
|
-
const
|
|
48
|
-
const defaultXScaleType =
|
|
49
|
-
const defaultYScaleType =
|
|
47
|
+
const isHorizontalLayout = chartProps.layout === 'horizontal';
|
|
48
|
+
const defaultXScaleType = isHorizontalLayout ? 'linear' : 'band';
|
|
49
|
+
const defaultYScaleType = isHorizontalLayout ? 'band' : 'linear';
|
|
50
50
|
|
|
51
51
|
// Split axis props into config props for Chart and visual props for axis components
|
|
52
52
|
const _ref2 = xAxis || {},
|
|
@@ -82,24 +82,24 @@ export const BarChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) =>
|
|
|
82
82
|
scaleType: xScaleType != null ? xScaleType : defaultXScaleType,
|
|
83
83
|
data: xData,
|
|
84
84
|
categoryPadding: xCategoryPadding,
|
|
85
|
-
domain:
|
|
85
|
+
domain: isHorizontalLayout && !hasNegativeValues ? _extends({
|
|
86
86
|
min: 0
|
|
87
87
|
}, xDomain) : xDomain,
|
|
88
88
|
domainLimit: xDomainLimit,
|
|
89
89
|
range: xRange
|
|
90
|
-
}), [xScaleType, defaultXScaleType, xData, xCategoryPadding,
|
|
90
|
+
}), [xScaleType, defaultXScaleType, xData, xCategoryPadding, isHorizontalLayout, hasNegativeValues, xDomain, xDomainLimit, xRange]);
|
|
91
91
|
|
|
92
92
|
// Set default min domain to 0 for bar chart, but only if there are no negative values.
|
|
93
93
|
const yAxisConfig = useMemo(() => ({
|
|
94
94
|
scaleType: yScaleType != null ? yScaleType : defaultYScaleType,
|
|
95
95
|
data: yData,
|
|
96
96
|
categoryPadding: yCategoryPadding,
|
|
97
|
-
domain: !
|
|
97
|
+
domain: !isHorizontalLayout && !hasNegativeValues ? _extends({
|
|
98
98
|
min: 0
|
|
99
99
|
}, yDomain) : yDomain,
|
|
100
100
|
domainLimit: yDomainLimit,
|
|
101
101
|
range: yRange
|
|
102
|
-
}), [yScaleType, defaultYScaleType, yData, yCategoryPadding,
|
|
102
|
+
}), [yScaleType, defaultYScaleType, yData, yCategoryPadding, isHorizontalLayout, hasNegativeValues, yDomain, yDomainLimit, yRange]);
|
|
103
103
|
return /*#__PURE__*/_jsxs(CartesianChart, _extends({}, chartProps, {
|
|
104
104
|
ref: ref,
|
|
105
105
|
inset: inset,
|
package/esm/chart/bar/BarPlot.js
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
|
-
import { memo, useMemo } from 'react';
|
|
2
|
-
import {
|
|
1
|
+
import { memo, useEffect, useMemo, useState } from 'react';
|
|
2
|
+
import { useSharedValue } from 'react-native-reanimated';
|
|
3
|
+
import { Group, Skia, usePathInterpolation } from '@shopify/react-native-skia';
|
|
3
4
|
import { useCartesianChartContext } from '../ChartProvider';
|
|
4
|
-
import {
|
|
5
|
+
import { getStackGroups } from '../utils';
|
|
6
|
+
import { buildTransition, instantTransition } from '../utils/transition';
|
|
5
7
|
import { BarStackGroup } from './BarStackGroup';
|
|
6
8
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
9
|
+
const makeClipPath = area => {
|
|
10
|
+
const path = Skia.Path.Make();
|
|
11
|
+
path.addRect(area);
|
|
12
|
+
return path;
|
|
13
|
+
};
|
|
14
|
+
|
|
7
15
|
/**
|
|
8
16
|
* BarPlot component that handles multiple series with proper stacking coordination.
|
|
9
17
|
* Groups series by stack ID + y-axis ID combination and renders BarStackGroup for each group.
|
|
@@ -28,6 +36,7 @@ export const BarPlot = /*#__PURE__*/memo(_ref => {
|
|
|
28
36
|
transition
|
|
29
37
|
} = _ref;
|
|
30
38
|
const {
|
|
39
|
+
animate,
|
|
31
40
|
series: allSeries,
|
|
32
41
|
drawingArea
|
|
33
42
|
} = useCartesianChartContext();
|
|
@@ -38,50 +47,32 @@ export const BarPlot = /*#__PURE__*/memo(_ref => {
|
|
|
38
47
|
}
|
|
39
48
|
return allSeries;
|
|
40
49
|
}, [allSeries, seriesIds]);
|
|
41
|
-
const stackGroups = useMemo(() =>
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
// Create clip path for the entire chart area (shared by all bars)
|
|
66
|
-
const clipPath = useMemo(() => {
|
|
67
|
-
if (!drawingArea) return null;
|
|
68
|
-
const clip = Skia.Path.Make();
|
|
69
|
-
clip.addRect({
|
|
70
|
-
x: drawingArea.x,
|
|
71
|
-
y: drawingArea.y,
|
|
72
|
-
width: drawingArea.width,
|
|
73
|
-
height: drawingArea.height
|
|
74
|
-
});
|
|
75
|
-
return clip;
|
|
76
|
-
}, [drawingArea]);
|
|
77
|
-
if (!clipPath) {
|
|
78
|
-
return null;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// Note: Clipping is now handled here at the BarPlot level (one clip path for all bars!)
|
|
82
|
-
// This is much more efficient than creating a clip path for each individual bar
|
|
50
|
+
const stackGroups = useMemo(() => getStackGroups(targetSeries), [targetSeries]);
|
|
51
|
+
const clipUpdateTransition = useMemo(() => (transitions == null ? void 0 : transitions.update) !== undefined ? transitions.update : instantTransition, [transitions == null ? void 0 : transitions.update]);
|
|
52
|
+
const emptyPath = useMemo(() => Skia.Path.Make(), []);
|
|
53
|
+
const initialPath = useMemo(() => drawingArea ? makeClipPath(drawingArea) : emptyPath,
|
|
54
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
55
|
+
[]);
|
|
56
|
+
const [clipPaths, setClipPaths] = useState({
|
|
57
|
+
from: initialPath,
|
|
58
|
+
to: initialPath
|
|
59
|
+
});
|
|
60
|
+
const clipProgress = useSharedValue(0);
|
|
61
|
+
useEffect(() => {
|
|
62
|
+
if (!drawingArea) return;
|
|
63
|
+
const nextPath = makeClipPath(drawingArea);
|
|
64
|
+
setClipPaths(prev => ({
|
|
65
|
+
from: prev.to,
|
|
66
|
+
to: nextPath
|
|
67
|
+
}));
|
|
68
|
+
clipProgress.value = 0;
|
|
69
|
+
clipProgress.value = buildTransition(1, animate ? clipUpdateTransition : null);
|
|
70
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
71
|
+
}, [drawingArea, animate, clipUpdateTransition]);
|
|
72
|
+
const animatedClipPath = usePathInterpolation(clipProgress, [0, 1], [clipPaths.from, clipPaths.to]);
|
|
73
|
+
if (!drawingArea) return;
|
|
83
74
|
return /*#__PURE__*/_jsx(Group, {
|
|
84
|
-
clip:
|
|
75
|
+
clip: animatedClipPath,
|
|
85
76
|
children: stackGroups.map((group, stackIndex) => /*#__PURE__*/_jsx(BarStackGroup, {
|
|
86
77
|
BarComponent: defaultBarComponent,
|
|
87
78
|
BarStackComponent: BarStackComponent,
|