@coinbase/cds-mobile-visualization 3.4.0-beta.22 → 3.4.0-beta.24
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 +12 -0
- package/dts/chart/CartesianChart.d.ts +58 -7
- package/dts/chart/CartesianChart.d.ts.map +1 -1
- package/dts/chart/Path.d.ts.map +1 -1
- package/dts/chart/area/Area.d.ts +7 -0
- package/dts/chart/area/Area.d.ts.map +1 -1
- package/dts/chart/area/AreaChart.d.ts +5 -5
- package/dts/chart/area/AreaChart.d.ts.map +1 -1
- package/dts/chart/area/DottedArea.d.ts.map +1 -1
- package/dts/chart/area/GradientArea.d.ts.map +1 -1
- package/dts/chart/area/SolidArea.d.ts.map +1 -1
- package/dts/chart/axis/Axis.d.ts +3 -1
- package/dts/chart/axis/Axis.d.ts.map +1 -1
- package/dts/chart/axis/XAxis.d.ts +6 -0
- package/dts/chart/axis/XAxis.d.ts.map +1 -1
- package/dts/chart/axis/YAxis.d.ts +1 -0
- package/dts/chart/axis/YAxis.d.ts.map +1 -1
- package/dts/chart/bar/Bar.d.ts +4 -2
- package/dts/chart/bar/Bar.d.ts.map +1 -1
- package/dts/chart/bar/BarChart.d.ts +49 -9
- package/dts/chart/bar/BarChart.d.ts.map +1 -1
- package/dts/chart/bar/BarPlot.d.ts.map +1 -1
- package/dts/chart/bar/BarStack.d.ts +30 -9
- package/dts/chart/bar/BarStack.d.ts.map +1 -1
- package/dts/chart/bar/BarStackGroup.d.ts +1 -1
- package/dts/chart/bar/BarStackGroup.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/gradient/Gradient.d.ts +5 -0
- package/dts/chart/gradient/Gradient.d.ts.map +1 -1
- package/dts/chart/line/DottedLine.d.ts.map +1 -1
- package/dts/chart/line/Line.d.ts +7 -0
- package/dts/chart/line/Line.d.ts.map +1 -1
- package/dts/chart/line/LineChart.d.ts +22 -8
- package/dts/chart/line/LineChart.d.ts.map +1 -1
- package/dts/chart/line/ReferenceLine.d.ts +1 -0
- package/dts/chart/line/ReferenceLine.d.ts.map +1 -1
- package/dts/chart/line/SolidLine.d.ts.map +1 -1
- package/dts/chart/point/Point.d.ts +7 -0
- package/dts/chart/point/Point.d.ts.map +1 -1
- package/dts/chart/scrubber/DefaultScrubberBeacon.d.ts.map +1 -1
- package/dts/chart/scrubber/DefaultScrubberLabel.d.ts +2 -1
- package/dts/chart/scrubber/DefaultScrubberLabel.d.ts.map +1 -1
- package/dts/chart/scrubber/Scrubber.d.ts +8 -0
- 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/scrubber/ScrubberBeaconGroup.d.ts.map +1 -1
- package/dts/chart/scrubber/ScrubberProvider.d.ts.map +1 -1
- package/dts/chart/utils/axis.d.ts +20 -9
- package/dts/chart/utils/axis.d.ts.map +1 -1
- package/dts/chart/utils/bar.d.ts +4 -3
- package/dts/chart/utils/bar.d.ts.map +1 -1
- package/dts/chart/utils/chart.d.ts +13 -0
- package/dts/chart/utils/chart.d.ts.map +1 -1
- package/dts/chart/utils/context.d.ts +21 -6
- package/dts/chart/utils/context.d.ts.map +1 -1
- package/dts/chart/utils/gradient.d.ts +3 -1
- package/dts/chart/utils/gradient.d.ts.map +1 -1
- package/dts/chart/utils/path.d.ts +20 -0
- package/dts/chart/utils/path.d.ts.map +1 -1
- package/dts/chart/utils/point.d.ts +7 -0
- package/dts/chart/utils/point.d.ts.map +1 -1
- package/esm/chart/CartesianChart.js +145 -81
- package/esm/chart/Path.js +10 -7
- package/esm/chart/__stories__/CartesianChart.stories.js +10 -0
- package/esm/chart/__stories__/ChartAccessibility.stories.js +721 -0
- package/esm/chart/area/Area.js +19 -9
- package/esm/chart/area/AreaChart.js +11 -9
- package/esm/chart/area/DottedArea.js +11 -6
- package/esm/chart/area/GradientArea.js +11 -6
- package/esm/chart/area/SolidArea.js +3 -1
- package/esm/chart/area/__stories__/AreaChart.stories.js +47 -5
- package/esm/chart/axis/XAxis.js +14 -21
- package/esm/chart/axis/YAxis.js +4 -3
- package/esm/chart/axis/__stories__/Axis.stories.js +65 -48
- package/esm/chart/bar/Bar.js +9 -5
- package/esm/chart/bar/BarChart.js +34 -31
- package/esm/chart/bar/BarPlot.js +7 -5
- package/esm/chart/bar/BarStack.js +176 -36
- package/esm/chart/bar/BarStackGroup.js +37 -27
- package/esm/chart/bar/DefaultBar.js +24 -8
- package/esm/chart/bar/DefaultBarStack.js +24 -10
- package/esm/chart/bar/__stories__/BarChart.stories.js +105 -3
- package/esm/chart/gradient/Gradient.js +2 -1
- package/esm/chart/line/DottedLine.js +3 -1
- package/esm/chart/line/Line.js +32 -19
- package/esm/chart/line/LineChart.js +31 -9
- package/esm/chart/line/SolidLine.js +3 -1
- package/esm/chart/line/__stories__/LineChart.stories.js +115 -46
- package/esm/chart/point/Point.js +2 -1
- package/esm/chart/scrubber/DefaultScrubberBeacon.js +1 -1
- package/esm/chart/scrubber/DefaultScrubberLabel.js +26 -10
- package/esm/chart/scrubber/Scrubber.js +47 -21
- package/esm/chart/scrubber/ScrubberAccessibilityView.js +177 -0
- package/esm/chart/scrubber/ScrubberBeaconGroup.js +24 -20
- package/esm/chart/scrubber/ScrubberProvider.js +29 -24
- package/esm/chart/scrubber/__stories__/Scrubber.stories.js +192 -6
- package/esm/chart/utils/axis.js +42 -14
- package/esm/chart/utils/bar.js +5 -4
- package/esm/chart/utils/chart.js +18 -5
- package/esm/chart/utils/context.js +7 -0
- package/esm/chart/utils/gradient.js +8 -4
- package/esm/chart/utils/path.js +90 -61
- package/esm/chart/utils/point.js +28 -18
- package/package.json +5 -5
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const _excluded = ["seriesId", "color", "label"],
|
|
2
|
-
_excluded2 = ["seriesId", "color", "label"]
|
|
2
|
+
_excluded2 = ["seriesId", "color", "label"],
|
|
3
|
+
_excluded3 = ["seriesId", "color"];
|
|
3
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; }
|
|
4
5
|
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
|
5
6
|
import { memo, useCallback, useMemo, useRef, useState } from 'react';
|
|
@@ -17,11 +18,15 @@ import { getLineData, unwrapAnimatedValue, useScrubberContext } from '../../util
|
|
|
17
18
|
import { DefaultScrubberBeacon, DefaultScrubberBeaconLabel, DefaultScrubberLabel, Scrubber } from '..';
|
|
18
19
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
19
20
|
const sampleData = [10, 22, 29, 45, 98, 45, 22, 52, 21, 4, 68, 20, 21, 58];
|
|
21
|
+
const chartAccessibilityLabel = "Price chart with " + sampleData.length + " data points. Swipe to navigate.";
|
|
22
|
+
const getScrubberAccessibilityLabel = index => "Point " + (index + 1) + ": " + sampleData[index];
|
|
20
23
|
const BasicScrubber = () => {
|
|
21
24
|
return /*#__PURE__*/_jsx(LineChart, {
|
|
22
25
|
enableScrubbing: true,
|
|
23
26
|
showArea: true,
|
|
24
27
|
showYAxis: true,
|
|
28
|
+
accessibilityLabel: chartAccessibilityLabel,
|
|
29
|
+
getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
|
|
25
30
|
height: 150,
|
|
26
31
|
series: [{
|
|
27
32
|
id: 'prices',
|
|
@@ -47,26 +52,35 @@ const BasicScrubber = () => {
|
|
|
47
52
|
})
|
|
48
53
|
});
|
|
49
54
|
};
|
|
55
|
+
const seriesFilterData = {
|
|
56
|
+
top: [15, 28, 32, 44, 46, 36, 40, 45, 48, 38],
|
|
57
|
+
upperMiddle: [12, 23, 21, 29, 34, 28, 31, 38, 42, 35],
|
|
58
|
+
lowerMiddle: [8, 15, 14, 25, 20, 18, 22, 28, 24, 30],
|
|
59
|
+
bottom: [4, 8, 11, 15, 16, 14, 16, 10, 12, 14]
|
|
60
|
+
};
|
|
50
61
|
const SeriesFilter = () => {
|
|
62
|
+
const getScrubberAccessibilityLabel = useCallback(index => "Point " + (index + 1) + ": top " + seriesFilterData.top[index] + ", lowerMiddle " + seriesFilterData.lowerMiddle[index], []);
|
|
51
63
|
return /*#__PURE__*/_jsx(LineChart, {
|
|
52
64
|
enableScrubbing: true,
|
|
65
|
+
accessibilityLabel: "Chart with multiple series. Swipe to navigate.",
|
|
66
|
+
getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
|
|
53
67
|
height: 150,
|
|
54
68
|
series: [{
|
|
55
69
|
id: 'top',
|
|
56
|
-
data:
|
|
70
|
+
data: seriesFilterData.top
|
|
57
71
|
}, {
|
|
58
72
|
id: 'upperMiddle',
|
|
59
|
-
data:
|
|
73
|
+
data: seriesFilterData.upperMiddle,
|
|
60
74
|
color: '#ef4444',
|
|
61
75
|
type: 'dotted'
|
|
62
76
|
}, {
|
|
63
77
|
id: 'lowerMiddle',
|
|
64
|
-
data:
|
|
78
|
+
data: seriesFilterData.lowerMiddle,
|
|
65
79
|
color: '#f59e0b',
|
|
66
80
|
curve: 'natural'
|
|
67
81
|
}, {
|
|
68
82
|
id: 'bottom',
|
|
69
|
-
data:
|
|
83
|
+
data: seriesFilterData.bottom,
|
|
70
84
|
color: '#800080',
|
|
71
85
|
curve: 'step',
|
|
72
86
|
showArea: true
|
|
@@ -80,6 +94,8 @@ const WithLabels = () => {
|
|
|
80
94
|
return /*#__PURE__*/_jsx(LineChart, {
|
|
81
95
|
enableScrubbing: true,
|
|
82
96
|
showArea: true,
|
|
97
|
+
accessibilityLabel: chartAccessibilityLabel,
|
|
98
|
+
getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
|
|
83
99
|
height: 150,
|
|
84
100
|
series: [{
|
|
85
101
|
id: 'prices',
|
|
@@ -96,6 +112,8 @@ const IdlePulse = () => {
|
|
|
96
112
|
return /*#__PURE__*/_jsx(LineChart, {
|
|
97
113
|
enableScrubbing: true,
|
|
98
114
|
showArea: true,
|
|
115
|
+
accessibilityLabel: chartAccessibilityLabel,
|
|
116
|
+
getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
|
|
99
117
|
height: 150,
|
|
100
118
|
series: [{
|
|
101
119
|
id: 'prices',
|
|
@@ -114,6 +132,8 @@ const ImperativePulse = () => {
|
|
|
114
132
|
children: [/*#__PURE__*/_jsx(LineChart, {
|
|
115
133
|
enableScrubbing: true,
|
|
116
134
|
showArea: true,
|
|
135
|
+
accessibilityLabel: chartAccessibilityLabel,
|
|
136
|
+
getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
|
|
117
137
|
height: 150,
|
|
118
138
|
series: [{
|
|
119
139
|
id: 'prices',
|
|
@@ -144,6 +164,8 @@ const BeaconStroke = () => {
|
|
|
144
164
|
children: /*#__PURE__*/_jsx(LineChart, {
|
|
145
165
|
enableScrubbing: true,
|
|
146
166
|
showArea: true,
|
|
167
|
+
accessibilityLabel: chartAccessibilityLabel,
|
|
168
|
+
getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
|
|
147
169
|
height: 150,
|
|
148
170
|
series: [{
|
|
149
171
|
id: 'prices',
|
|
@@ -171,6 +193,8 @@ const CustomBeacon = () => {
|
|
|
171
193
|
enableScrubbing: true,
|
|
172
194
|
showArea: true,
|
|
173
195
|
showYAxis: true,
|
|
196
|
+
accessibilityLabel: chartAccessibilityLabel,
|
|
197
|
+
getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
|
|
174
198
|
height: 150,
|
|
175
199
|
series: [{
|
|
176
200
|
id: 'prices',
|
|
@@ -248,7 +272,9 @@ const CustomBeaconLabel = () => {
|
|
|
248
272
|
enableScrubbing: true,
|
|
249
273
|
showArea: true,
|
|
250
274
|
showYAxis: true,
|
|
275
|
+
accessibilityLabel: "Temperature chart with 6 data points. Swipe to navigate.",
|
|
251
276
|
areaType: "dotted",
|
|
277
|
+
getScrubberAccessibilityLabel: index => "Point " + (index + 1) + ": " + [25, 30, 35, 45, 60, 100][index] + "\xB0F",
|
|
252
278
|
height: 150,
|
|
253
279
|
series: [{
|
|
254
280
|
id: 'Boston',
|
|
@@ -371,7 +397,9 @@ const PercentageBeaconLabels = () => {
|
|
|
371
397
|
children: /*#__PURE__*/_jsx(LineChart, {
|
|
372
398
|
enableScrubbing: true,
|
|
373
399
|
showArea: true,
|
|
400
|
+
accessibilityLabel: "NYC vs ATL comparison chart. Swipe to navigate.",
|
|
374
401
|
areaType: "dotted",
|
|
402
|
+
getScrubberAccessibilityLabel: index => "Point " + (index + 1),
|
|
375
403
|
height: 150,
|
|
376
404
|
inset: {
|
|
377
405
|
bottom: 8,
|
|
@@ -409,7 +437,9 @@ const PercentageBeaconLabels = () => {
|
|
|
409
437
|
children: /*#__PURE__*/_jsx(LineChart, {
|
|
410
438
|
enableScrubbing: true,
|
|
411
439
|
showArea: true,
|
|
440
|
+
accessibilityLabel: "NYC vs ATL comparison chart. Swipe to navigate.",
|
|
412
441
|
areaType: "dotted",
|
|
442
|
+
getScrubberAccessibilityLabel: index => "Point " + (index + 1),
|
|
413
443
|
height: 150,
|
|
414
444
|
inset: {
|
|
415
445
|
bottom: 8,
|
|
@@ -448,6 +478,8 @@ const HideBeaconLabels = () => {
|
|
|
448
478
|
enableScrubbing: true,
|
|
449
479
|
legend: true,
|
|
450
480
|
showArea: true,
|
|
481
|
+
accessibilityLabel: "Website visitors across 7 pages. Swipe to navigate.",
|
|
482
|
+
getScrubberAccessibilityLabel: index => "Page " + (index + 1) + ": " + [2400, 1398, 9800, 3908, 4800, 3800, 4300][index] + " views",
|
|
451
483
|
height: 200,
|
|
452
484
|
inset: {
|
|
453
485
|
top: 60
|
|
@@ -474,6 +506,8 @@ const LabelElevated = () => {
|
|
|
474
506
|
return /*#__PURE__*/_jsx(LineChart, {
|
|
475
507
|
enableScrubbing: true,
|
|
476
508
|
showArea: true,
|
|
509
|
+
accessibilityLabel: chartAccessibilityLabel,
|
|
510
|
+
getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
|
|
477
511
|
height: 200,
|
|
478
512
|
inset: {
|
|
479
513
|
top: 60
|
|
@@ -507,6 +541,8 @@ const CustomLabelComponent = () => {
|
|
|
507
541
|
return /*#__PURE__*/_jsx(LineChart, {
|
|
508
542
|
enableScrubbing: true,
|
|
509
543
|
showArea: true,
|
|
544
|
+
accessibilityLabel: chartAccessibilityLabel,
|
|
545
|
+
getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
|
|
510
546
|
height: 200,
|
|
511
547
|
inset: {
|
|
512
548
|
top: 16,
|
|
@@ -522,11 +558,15 @@ const CustomLabelComponent = () => {
|
|
|
522
558
|
})
|
|
523
559
|
});
|
|
524
560
|
};
|
|
561
|
+
const ethData = [5, 15, 18, 30, 65, 30, 15, 35, 15, 2, 45, 12, 15, 40];
|
|
525
562
|
const LabelFonts = () => {
|
|
563
|
+
const getScrubberAccessibilityLabel = useCallback(index => "Day " + (index + 1) + ": BTC " + sampleData[index] + ", ETH " + ethData[index], []);
|
|
526
564
|
return /*#__PURE__*/_jsx(LineChart, {
|
|
527
565
|
enableScrubbing: true,
|
|
528
566
|
showArea: true,
|
|
529
567
|
showYAxis: true,
|
|
568
|
+
accessibilityLabel: "BTC and ETH comparison chart. Swipe to navigate.",
|
|
569
|
+
getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
|
|
530
570
|
height: 150,
|
|
531
571
|
series: [{
|
|
532
572
|
id: 'btc',
|
|
@@ -535,7 +575,7 @@ const LabelFonts = () => {
|
|
|
535
575
|
color: assets.btc.color
|
|
536
576
|
}, {
|
|
537
577
|
id: 'eth',
|
|
538
|
-
data:
|
|
578
|
+
data: ethData,
|
|
539
579
|
label: 'ETH',
|
|
540
580
|
color: assets.eth.color
|
|
541
581
|
}],
|
|
@@ -555,6 +595,8 @@ const LabelBoundsInset = () => {
|
|
|
555
595
|
children: [/*#__PURE__*/_jsx(LineChart, {
|
|
556
596
|
enableScrubbing: true,
|
|
557
597
|
showArea: true,
|
|
598
|
+
accessibilityLabel: chartAccessibilityLabel,
|
|
599
|
+
getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
|
|
558
600
|
height: 150,
|
|
559
601
|
inset: {
|
|
560
602
|
left: 0,
|
|
@@ -571,6 +613,8 @@ const LabelBoundsInset = () => {
|
|
|
571
613
|
}), /*#__PURE__*/_jsx(LineChart, {
|
|
572
614
|
enableScrubbing: true,
|
|
573
615
|
showArea: true,
|
|
616
|
+
accessibilityLabel: chartAccessibilityLabel,
|
|
617
|
+
getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
|
|
574
618
|
height: 150,
|
|
575
619
|
inset: {
|
|
576
620
|
left: 0,
|
|
@@ -596,6 +640,8 @@ const CustomLine = () => {
|
|
|
596
640
|
return /*#__PURE__*/_jsx(LineChart, {
|
|
597
641
|
enableScrubbing: true,
|
|
598
642
|
showArea: true,
|
|
643
|
+
accessibilityLabel: chartAccessibilityLabel,
|
|
644
|
+
getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
|
|
599
645
|
height: 150,
|
|
600
646
|
series: [{
|
|
601
647
|
id: 'prices',
|
|
@@ -628,6 +674,8 @@ const HiddenScrubberWhenIdle = () => {
|
|
|
628
674
|
return /*#__PURE__*/_jsx(LineChart, {
|
|
629
675
|
enableScrubbing: true,
|
|
630
676
|
showArea: true,
|
|
677
|
+
accessibilityLabel: chartAccessibilityLabel,
|
|
678
|
+
getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
|
|
631
679
|
height: 150,
|
|
632
680
|
series: [{
|
|
633
681
|
id: 'prices',
|
|
@@ -644,6 +692,8 @@ const HideOverlay = () => {
|
|
|
644
692
|
return /*#__PURE__*/_jsx(LineChart, {
|
|
645
693
|
enableScrubbing: true,
|
|
646
694
|
showArea: true,
|
|
695
|
+
accessibilityLabel: chartAccessibilityLabel,
|
|
696
|
+
getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
|
|
647
697
|
height: 150,
|
|
648
698
|
series: [{
|
|
649
699
|
id: 'prices',
|
|
@@ -654,6 +704,139 @@ const HideOverlay = () => {
|
|
|
654
704
|
})
|
|
655
705
|
});
|
|
656
706
|
};
|
|
707
|
+
const matchupBlueData = [47, 50, 51, 52, 53, 53, 53, 53, 52, 51, 51, 52, 53, 55, 57, 58, 59, 61, 63, 65, 64, 64, 64, 64, 64, 63, 63, 63, 64, 66, 68, 70, 71, 72, 74, 76, 76, 75, 74, 73, 74, 75, 75, 78];
|
|
708
|
+
const matchupRedData = matchupBlueData.map(value => 100 - value);
|
|
709
|
+
const matchupTeamLabels = {
|
|
710
|
+
blue: 'BLUE',
|
|
711
|
+
red: 'RED'
|
|
712
|
+
};
|
|
713
|
+
const MatchupBeaconLabels = () => {
|
|
714
|
+
const theme = useTheme();
|
|
715
|
+
const MatchupScrubberBeaconLabel = /*#__PURE__*/memo(_ref7 => {
|
|
716
|
+
var _matchupTeamLabels$se;
|
|
717
|
+
let {
|
|
718
|
+
seriesId,
|
|
719
|
+
color
|
|
720
|
+
} = _ref7,
|
|
721
|
+
props = _objectWithoutPropertiesLoose(_ref7, _excluded3);
|
|
722
|
+
const {
|
|
723
|
+
getSeriesData,
|
|
724
|
+
series,
|
|
725
|
+
fontProvider
|
|
726
|
+
} = useCartesianChartContext();
|
|
727
|
+
const {
|
|
728
|
+
scrubberPosition
|
|
729
|
+
} = useScrubberContext();
|
|
730
|
+
const seriesData = useMemo(() => getLineData(getSeriesData(seriesId)), [getSeriesData, seriesId]);
|
|
731
|
+
const dataLength = useMemo(() => {
|
|
732
|
+
var _series$reduce3;
|
|
733
|
+
return (_series$reduce3 = series == null ? void 0 : series.reduce((max, currentSeries) => {
|
|
734
|
+
var _data$length3;
|
|
735
|
+
const data = getSeriesData(currentSeries.id);
|
|
736
|
+
return Math.max(max, (_data$length3 = data == null ? void 0 : data.length) != null ? _data$length3 : 0);
|
|
737
|
+
}, 0)) != null ? _series$reduce3 : 0;
|
|
738
|
+
}, [series, getSeriesData]);
|
|
739
|
+
const dataIndex = useDerivedValue(() => {
|
|
740
|
+
var _scrubberPosition$val3;
|
|
741
|
+
return (_scrubberPosition$val3 = scrubberPosition.value) != null ? _scrubberPosition$val3 : Math.max(0, dataLength - 1);
|
|
742
|
+
}, [scrubberPosition, dataLength]);
|
|
743
|
+
const teamLabel = (_matchupTeamLabels$se = matchupTeamLabels[seriesId]) != null ? _matchupTeamLabels$se : String(seriesId).toUpperCase();
|
|
744
|
+
const labelColor = color != null ? color : theme.color.fgPrimary;
|
|
745
|
+
const legalFontSize = theme.fontSize.legal;
|
|
746
|
+
const title3FontSize = theme.fontSize.title3;
|
|
747
|
+
const teamStyle = useMemo(() => ({
|
|
748
|
+
fontFamilies: ['Inter'],
|
|
749
|
+
fontSize: legalFontSize,
|
|
750
|
+
fontStyle: {
|
|
751
|
+
weight: FontWeight.Normal
|
|
752
|
+
},
|
|
753
|
+
color: Skia.Color(labelColor)
|
|
754
|
+
}), [labelColor, legalFontSize]);
|
|
755
|
+
const percentageStyle = useMemo(() => ({
|
|
756
|
+
fontFamilies: ['Inter'],
|
|
757
|
+
fontSize: title3FontSize,
|
|
758
|
+
fontStyle: {
|
|
759
|
+
weight: FontWeight.Bold
|
|
760
|
+
},
|
|
761
|
+
color: Skia.Color(labelColor)
|
|
762
|
+
}), [title3FontSize, labelColor]);
|
|
763
|
+
const matchupLabel = useDerivedValue(() => {
|
|
764
|
+
if (seriesData === undefined) {
|
|
765
|
+
return teamLabel;
|
|
766
|
+
}
|
|
767
|
+
const value = seriesData[dataIndex.value];
|
|
768
|
+
const builder = Skia.ParagraphBuilder.Make({
|
|
769
|
+
textAlign: TextAlign.Left
|
|
770
|
+
}, fontProvider);
|
|
771
|
+
builder.pushStyle(teamStyle);
|
|
772
|
+
builder.addText(teamLabel);
|
|
773
|
+
builder.addText('\n');
|
|
774
|
+
builder.pushStyle(percentageStyle);
|
|
775
|
+
builder.addText(value + "%");
|
|
776
|
+
const paragraph = builder.build();
|
|
777
|
+
paragraph.layout(240);
|
|
778
|
+
return paragraph;
|
|
779
|
+
}, [dataIndex, fontProvider, percentageStyle, seriesData, teamLabel, teamStyle]);
|
|
780
|
+
return /*#__PURE__*/_jsx(DefaultScrubberBeaconLabel, _extends({}, props, {
|
|
781
|
+
background: "transparent",
|
|
782
|
+
color: labelColor,
|
|
783
|
+
elevated: false,
|
|
784
|
+
inset: 0,
|
|
785
|
+
label: matchupLabel,
|
|
786
|
+
seriesId: seriesId
|
|
787
|
+
}));
|
|
788
|
+
});
|
|
789
|
+
const getScrubberAccessibilityLabel = useCallback(index => "Point " + (index + 1) + ": BLUE " + matchupBlueData[index] + "%, RED " + matchupRedData[index] + "%", []);
|
|
790
|
+
return /*#__PURE__*/_jsx(LineChart, {
|
|
791
|
+
enableScrubbing: true,
|
|
792
|
+
showArea: true,
|
|
793
|
+
accessibilityLabel: "BLUE vs RED matchup chart. Swipe to navigate.",
|
|
794
|
+
areaType: "dotted",
|
|
795
|
+
getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
|
|
796
|
+
height: 300,
|
|
797
|
+
inset: {
|
|
798
|
+
bottom: 8,
|
|
799
|
+
left: 8,
|
|
800
|
+
top: 8,
|
|
801
|
+
right: 0
|
|
802
|
+
},
|
|
803
|
+
series: [{
|
|
804
|
+
id: 'blue',
|
|
805
|
+
data: matchupBlueData,
|
|
806
|
+
color: "rgb(" + theme.spectrum.blue50 + ")",
|
|
807
|
+
label: 'BLUE'
|
|
808
|
+
}, {
|
|
809
|
+
id: 'red',
|
|
810
|
+
data: matchupRedData,
|
|
811
|
+
color: "rgb(" + theme.spectrum.red50 + ")",
|
|
812
|
+
label: 'RED'
|
|
813
|
+
}],
|
|
814
|
+
xAxis: {
|
|
815
|
+
range: _ref8 => {
|
|
816
|
+
let {
|
|
817
|
+
min,
|
|
818
|
+
max
|
|
819
|
+
} = _ref8;
|
|
820
|
+
return {
|
|
821
|
+
min,
|
|
822
|
+
max: max - 64
|
|
823
|
+
};
|
|
824
|
+
}
|
|
825
|
+
},
|
|
826
|
+
yAxis: {
|
|
827
|
+
domain: {
|
|
828
|
+
min: 0,
|
|
829
|
+
max: 100
|
|
830
|
+
}
|
|
831
|
+
},
|
|
832
|
+
children: /*#__PURE__*/_jsx(Scrubber, {
|
|
833
|
+
idlePulse: true,
|
|
834
|
+
BeaconLabelComponent: MatchupScrubberBeaconLabel,
|
|
835
|
+
beaconLabelHorizontalOffset: 16,
|
|
836
|
+
beaconLabelPreferredSide: "right"
|
|
837
|
+
})
|
|
838
|
+
});
|
|
839
|
+
};
|
|
657
840
|
const ExampleNavigator = () => {
|
|
658
841
|
const [currentIndex, setCurrentIndex] = useState(0);
|
|
659
842
|
const examples = useMemo(() => [{
|
|
@@ -707,6 +890,9 @@ const ExampleNavigator = () => {
|
|
|
707
890
|
}, {
|
|
708
891
|
title: 'Hide Overlay',
|
|
709
892
|
component: /*#__PURE__*/_jsx(HideOverlay, {})
|
|
893
|
+
}, {
|
|
894
|
+
title: 'Matchup Beacon Labels',
|
|
895
|
+
component: /*#__PURE__*/_jsx(MatchupBeaconLabels, {})
|
|
710
896
|
}], []);
|
|
711
897
|
const currentExample = examples[currentIndex];
|
|
712
898
|
const isFirstExample = currentIndex === 0;
|
package/esm/chart/utils/axis.js
CHANGED
|
@@ -47,7 +47,7 @@ export const toPointAnchor = placement => {
|
|
|
47
47
|
*/
|
|
48
48
|
|
|
49
49
|
/**
|
|
50
|
-
* Gets a D3 scale based on the axis configuration.
|
|
50
|
+
* Gets a D3 scale based on the cartesian axis configuration.
|
|
51
51
|
* Handles both numeric (linear/log) and categorical (band) scales.
|
|
52
52
|
*
|
|
53
53
|
* For numeric scales, the domain limit controls whether bounds are "nice" (human-friendly)
|
|
@@ -57,19 +57,27 @@ export const toPointAnchor = placement => {
|
|
|
57
57
|
* @returns The D3 scale function
|
|
58
58
|
* @throws An Error if bounds are invalid
|
|
59
59
|
*/
|
|
60
|
-
export const
|
|
60
|
+
export const getCartesianAxisScale = _ref => {
|
|
61
61
|
var _config$scaleType;
|
|
62
62
|
let {
|
|
63
63
|
config,
|
|
64
64
|
type,
|
|
65
65
|
range,
|
|
66
|
-
dataDomain
|
|
66
|
+
dataDomain,
|
|
67
|
+
layout = 'vertical'
|
|
67
68
|
} = _ref;
|
|
68
69
|
const scaleType = (_config$scaleType = config == null ? void 0 : config.scaleType) != null ? _config$scaleType : 'linear';
|
|
69
70
|
let adjustedRange = range;
|
|
70
71
|
|
|
71
|
-
//
|
|
72
|
-
|
|
72
|
+
// Determine if this axis needs range inversion for SVG coordinate system.
|
|
73
|
+
// SVG Y coordinates increase downward, so we need to invert for value axes
|
|
74
|
+
// where we want higher values at the top.
|
|
75
|
+
//
|
|
76
|
+
// For vertical layout: Y axis is the value axis -> invert (higher values at top)
|
|
77
|
+
// For horizontal layout: Y axis is the category axis -> don't invert (first category at top is natural)
|
|
78
|
+
// X axis never needs inversion (left-to-right is natural for both layouts)
|
|
79
|
+
const shouldInvertRange = type === 'y' && layout !== 'horizontal';
|
|
80
|
+
if (shouldInvertRange) {
|
|
73
81
|
adjustedRange = {
|
|
74
82
|
min: adjustedRange.max,
|
|
75
83
|
max: adjustedRange.min
|
|
@@ -121,6 +129,8 @@ export const getAxisConfig = function (type, axes, defaultId, defaultScaleType)
|
|
|
121
129
|
defaultScaleType = defaultAxisScaleType;
|
|
122
130
|
}
|
|
123
131
|
const defaultDomainLimit = type === 'x' ? 'strict' : 'nice';
|
|
132
|
+
const axisName = type === 'x' ? 'x-axis' : 'y-axis';
|
|
133
|
+
const axisDocUrl = type === 'x' ? 'https://cds.coinbase.com/components/charts/XAxis' : 'https://cds.coinbase.com/components/charts/YAxis';
|
|
124
134
|
if (!axes) {
|
|
125
135
|
return [{
|
|
126
136
|
id: defaultId,
|
|
@@ -137,16 +147,27 @@ export const getAxisConfig = function (type, axes, defaultId, defaultScaleType)
|
|
|
137
147
|
} = _ref2;
|
|
138
148
|
return id === undefined;
|
|
139
149
|
})) {
|
|
140
|
-
throw new Error(
|
|
150
|
+
throw new Error("When defining multiple " + axisName + ", each must have a unique id. See " + axisDocUrl + ".");
|
|
141
151
|
}
|
|
142
|
-
|
|
152
|
+
if (axesLength > 1) {
|
|
153
|
+
const ids = axes.map(_ref3 => {
|
|
154
|
+
let {
|
|
155
|
+
id
|
|
156
|
+
} = _ref3;
|
|
157
|
+
return id;
|
|
158
|
+
}).filter(id => id !== undefined);
|
|
159
|
+
if (new Set(ids).size !== ids.length) {
|
|
160
|
+
throw new Error("When defining multiple " + axisName + ", each must have a unique id. See " + axisDocUrl + ".");
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return axes.map(_ref4 => {
|
|
143
164
|
let {
|
|
144
165
|
id
|
|
145
|
-
} =
|
|
146
|
-
axis = _objectWithoutPropertiesLoose(
|
|
166
|
+
} = _ref4,
|
|
167
|
+
axis = _objectWithoutPropertiesLoose(_ref4, _excluded);
|
|
147
168
|
return _extends({
|
|
148
169
|
// defaults the axis id if only a single axis is provided
|
|
149
|
-
id: axesLength > 1 ? id != null ? id : defaultAxisId : id,
|
|
170
|
+
id: axesLength > 1 ? id != null ? id : defaultAxisId : id != null ? id : defaultId,
|
|
150
171
|
scaleType: defaultScaleType,
|
|
151
172
|
domainLimit: defaultDomainLimit
|
|
152
173
|
}, axis);
|
|
@@ -168,10 +189,14 @@ export const getAxisConfig = function (type, axes, defaultId, defaultScaleType)
|
|
|
168
189
|
* @param axisParam - The axis configuration
|
|
169
190
|
* @param series - Array of series objects (for stacking support)
|
|
170
191
|
* @param axisType - Whether this is an 'x' or 'y' axis
|
|
192
|
+
* @param layout - The chart layout orientation
|
|
171
193
|
* @returns The calculated axis bounds
|
|
172
194
|
*/
|
|
173
|
-
export const
|
|
195
|
+
export const getCartesianAxisDomain = function (axisParam, series, axisType, layout) {
|
|
174
196
|
var _finalDomain$min, _finalDomain$max;
|
|
197
|
+
if (layout === void 0) {
|
|
198
|
+
layout = 'vertical';
|
|
199
|
+
}
|
|
175
200
|
let dataDomain = null;
|
|
176
201
|
if (axisParam.data && Array.isArray(axisParam.data) && axisParam.data.length > 0) {
|
|
177
202
|
const firstItem = axisParam.data[0];
|
|
@@ -193,7 +218,10 @@ export const getAxisDomain = (axisParam, series, axisType) => {
|
|
|
193
218
|
}
|
|
194
219
|
|
|
195
220
|
// Calculate domain from series data
|
|
196
|
-
|
|
221
|
+
// In vertical layout: X is category (index), Y is value (value)
|
|
222
|
+
// In horizontal layout: Y is category (index), X is value (value)
|
|
223
|
+
const isCategoryAxis = layout !== 'horizontal' && axisType === 'x' || layout === 'horizontal' && axisType === 'y';
|
|
224
|
+
const seriesDomain = isCategoryAxis ? getChartDomain(series) : getChartRange(series);
|
|
197
225
|
|
|
198
226
|
// If data sets the domain, use that instead of the series domain
|
|
199
227
|
const preferredDataDomain = dataDomain != null ? dataDomain : seriesDomain;
|
|
@@ -487,7 +515,7 @@ const generateEvenlyDistributedTicks = (scale, tickInterval, possibleTickValues,
|
|
|
487
515
|
* });
|
|
488
516
|
* // Returns tick positions centered in each selected band
|
|
489
517
|
*/
|
|
490
|
-
export const getAxisTicksData =
|
|
518
|
+
export const getAxisTicksData = _ref5 => {
|
|
491
519
|
var _options$anchor;
|
|
492
520
|
let {
|
|
493
521
|
ticks,
|
|
@@ -497,7 +525,7 @@ export const getAxisTicksData = _ref4 => {
|
|
|
497
525
|
possibleTickValues,
|
|
498
526
|
tickInterval,
|
|
499
527
|
options
|
|
500
|
-
} =
|
|
528
|
+
} = _ref5;
|
|
501
529
|
const anchor = (_options$anchor = options == null ? void 0 : options.anchor) != null ? _options$anchor : 'middle';
|
|
502
530
|
|
|
503
531
|
// Handle band scales
|
package/esm/chart/utils/bar.js
CHANGED
|
@@ -6,7 +6,8 @@ import { defaultTransition } from './transition';
|
|
|
6
6
|
/**
|
|
7
7
|
* A bar-specific transition that extends Transition with stagger support.
|
|
8
8
|
* When `staggerDelay` is provided, bars will animate with increasing delays
|
|
9
|
-
* based on their
|
|
9
|
+
* based on their position along the category axis (vertical: left-to-right,
|
|
10
|
+
* horizontal: top-to-bottom).
|
|
10
11
|
*
|
|
11
12
|
* @example
|
|
12
13
|
* // Bars stagger in from left to right over 250ms, each animating for 750ms
|
|
@@ -17,10 +18,10 @@ import { defaultTransition } from './transition';
|
|
|
17
18
|
* Strips `staggerDelay` from a transition and computes a positional delay.
|
|
18
19
|
*
|
|
19
20
|
* @param transition - The transition config (may include staggerDelay)
|
|
20
|
-
* @param
|
|
21
|
+
* @param normalizedPosition - The bar's normalized position along the category axis (0–1)
|
|
21
22
|
* @returns A standard Transition with computed delay
|
|
22
23
|
*/
|
|
23
|
-
export const withStaggerDelayTransition = (transition,
|
|
24
|
+
export const withStaggerDelayTransition = (transition, normalizedPosition) => {
|
|
24
25
|
var _baseTransition$delay;
|
|
25
26
|
if (!transition) return null;
|
|
26
27
|
const {
|
|
@@ -29,7 +30,7 @@ export const withStaggerDelayTransition = (transition, normalizedX) => {
|
|
|
29
30
|
baseTransition = _objectWithoutPropertiesLoose(transition, _excluded);
|
|
30
31
|
if (!staggerDelay) return transition;
|
|
31
32
|
return _extends({}, baseTransition, {
|
|
32
|
-
delay: ((_baseTransition$delay = baseTransition == null ? void 0 : baseTransition.delay) != null ? _baseTransition$delay : 0) +
|
|
33
|
+
delay: ((_baseTransition$delay = baseTransition == null ? void 0 : baseTransition.delay) != null ? _baseTransition$delay : 0) + normalizedPosition * staggerDelay
|
|
33
34
|
});
|
|
34
35
|
};
|
|
35
36
|
|
package/esm/chart/utils/chart.js
CHANGED
|
@@ -46,15 +46,16 @@ export const getChartDomain = (series, min, max) => {
|
|
|
46
46
|
};
|
|
47
47
|
|
|
48
48
|
/**
|
|
49
|
-
* Creates a composite stack key that includes
|
|
50
|
-
* This ensures series with different
|
|
49
|
+
* Creates a composite stack key that includes stack ID and axis IDs.
|
|
50
|
+
* This ensures series with different scales don't get stacked together.
|
|
51
51
|
*/
|
|
52
52
|
const createStackKey = series => {
|
|
53
53
|
if (series.stackId === undefined) return undefined;
|
|
54
54
|
|
|
55
|
-
// Include
|
|
55
|
+
// Include axis IDs to prevent cross-scale stacking
|
|
56
|
+
const xAxisId = series.xAxisId || 'default';
|
|
56
57
|
const yAxisId = series.yAxisId || 'default';
|
|
57
|
-
return series.stackId + ":" + yAxisId;
|
|
58
|
+
return series.stackId + ":" + xAxisId + ":" + yAxisId;
|
|
58
59
|
};
|
|
59
60
|
|
|
60
61
|
/**
|
|
@@ -225,12 +226,24 @@ export const getChartRange = (series, min, max) => {
|
|
|
225
226
|
}
|
|
226
227
|
return range;
|
|
227
228
|
};
|
|
228
|
-
export const
|
|
229
|
+
export const defaultVerticalLayoutChartInset = {
|
|
229
230
|
top: 32,
|
|
230
231
|
left: 16,
|
|
231
232
|
bottom: 16,
|
|
232
233
|
right: 16
|
|
233
234
|
};
|
|
235
|
+
export const defaultHorizontalLayoutChartInset = {
|
|
236
|
+
top: 16,
|
|
237
|
+
left: 16,
|
|
238
|
+
bottom: 16,
|
|
239
|
+
right: 48
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* @deprecated Use `defaultVerticalLayoutChartInset` for vertical layout charts or
|
|
244
|
+
* `defaultHorizontalLayoutChartInset` for horizontal layout charts.
|
|
245
|
+
*/
|
|
246
|
+
export const defaultChartInset = defaultVerticalLayoutChartInset;
|
|
234
247
|
|
|
235
248
|
/**
|
|
236
249
|
* Normalize padding to include all sides with a value.
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { createContext, useContext } from 'react';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Chart layout for Cartesian charts.
|
|
5
|
+
* Describes the direction bars/areas grow.
|
|
6
|
+
* - 'vertical': Bars grow vertically (up/down). X is category axis, Y is value axis.
|
|
7
|
+
* - 'horizontal': Bars grow horizontally (left/right). Y is category axis, X is value axis.
|
|
8
|
+
*/
|
|
9
|
+
|
|
3
10
|
/**
|
|
4
11
|
* Context value for Cartesian (X/Y) coordinate charts.
|
|
5
12
|
* Contains axis-specific methods and properties for rectangular coordinate systems.
|
|
@@ -262,9 +262,13 @@ export const getBaseline = function (axisBounds, baseline) {
|
|
|
262
262
|
* @param fill - The color to use for the gradient
|
|
263
263
|
* @param peakOpacity - Opacity at the peak of the gradient
|
|
264
264
|
* @param baselineOpacity - Opacity at the baseline
|
|
265
|
-
* @
|
|
265
|
+
* @param axis - The axis the gradient maps to ('y' for vertical, 'x' for horizontal layout)
|
|
266
|
+
* @returns A gradient definition with stops in ascending order
|
|
266
267
|
*/
|
|
267
|
-
export const createGradient = (axisBounds, baselineValue, fill, peakOpacity, baselineOpacity)
|
|
268
|
+
export const createGradient = function (axisBounds, baselineValue, fill, peakOpacity, baselineOpacity, axis) {
|
|
269
|
+
if (axis === void 0) {
|
|
270
|
+
axis = 'y';
|
|
271
|
+
}
|
|
268
272
|
const {
|
|
269
273
|
min,
|
|
270
274
|
max
|
|
@@ -273,7 +277,7 @@ export const createGradient = (axisBounds, baselineValue, fill, peakOpacity, bas
|
|
|
273
277
|
const upperBound = Math.max(min, max);
|
|
274
278
|
if (lowerBound < baselineValue && baselineValue < upperBound) {
|
|
275
279
|
return {
|
|
276
|
-
axis
|
|
280
|
+
axis,
|
|
277
281
|
stops: [{
|
|
278
282
|
offset: lowerBound,
|
|
279
283
|
color: fill,
|
|
@@ -291,7 +295,7 @@ export const createGradient = (axisBounds, baselineValue, fill, peakOpacity, bas
|
|
|
291
295
|
}
|
|
292
296
|
const peakValue = Math.abs(min - baselineValue) > Math.abs(max - baselineValue) ? min : max;
|
|
293
297
|
return {
|
|
294
|
-
axis
|
|
298
|
+
axis,
|
|
295
299
|
stops: [{
|
|
296
300
|
offset: peakValue,
|
|
297
301
|
color: fill,
|