@coinbase/cds-mobile-visualization 3.4.0-beta.8 → 3.4.0

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 (170) hide show
  1. package/CHANGELOG.md +142 -0
  2. package/dts/chart/CartesianChart.d.ts +92 -7
  3. package/dts/chart/CartesianChart.d.ts.map +1 -1
  4. package/dts/chart/ChartContextBridge.d.ts.map +1 -1
  5. package/dts/chart/ChartProvider.d.ts +3 -0
  6. package/dts/chart/ChartProvider.d.ts.map +1 -1
  7. package/dts/chart/Path.d.ts +36 -13
  8. package/dts/chart/Path.d.ts.map +1 -1
  9. package/dts/chart/PeriodSelector.d.ts +21 -6
  10. package/dts/chart/PeriodSelector.d.ts.map +1 -1
  11. package/dts/chart/area/Area.d.ts +14 -11
  12. package/dts/chart/area/Area.d.ts.map +1 -1
  13. package/dts/chart/area/AreaChart.d.ts +33 -9
  14. package/dts/chart/area/AreaChart.d.ts.map +1 -1
  15. package/dts/chart/area/DottedArea.d.ts.map +1 -1
  16. package/dts/chart/area/GradientArea.d.ts.map +1 -1
  17. package/dts/chart/area/SolidArea.d.ts.map +1 -1
  18. package/dts/chart/axis/Axis.d.ts +22 -42
  19. package/dts/chart/axis/Axis.d.ts.map +1 -1
  20. package/dts/chart/axis/XAxis.d.ts +6 -0
  21. package/dts/chart/axis/XAxis.d.ts.map +1 -1
  22. package/dts/chart/axis/YAxis.d.ts +1 -0
  23. package/dts/chart/axis/YAxis.d.ts.map +1 -1
  24. package/dts/chart/bar/Bar.d.ts +51 -51
  25. package/dts/chart/bar/Bar.d.ts.map +1 -1
  26. package/dts/chart/bar/BarChart.d.ts +56 -11
  27. package/dts/chart/bar/BarChart.d.ts.map +1 -1
  28. package/dts/chart/bar/BarPlot.d.ts +2 -1
  29. package/dts/chart/bar/BarPlot.d.ts.map +1 -1
  30. package/dts/chart/bar/BarStack.d.ts +45 -20
  31. package/dts/chart/bar/BarStack.d.ts.map +1 -1
  32. package/dts/chart/bar/BarStackGroup.d.ts +2 -1
  33. package/dts/chart/bar/BarStackGroup.d.ts.map +1 -1
  34. package/dts/chart/bar/DefaultBar.d.ts.map +1 -1
  35. package/dts/chart/bar/DefaultBarStack.d.ts.map +1 -1
  36. package/dts/chart/gradient/Gradient.d.ts +5 -0
  37. package/dts/chart/gradient/Gradient.d.ts.map +1 -1
  38. package/dts/chart/index.d.ts +1 -0
  39. package/dts/chart/index.d.ts.map +1 -1
  40. package/dts/chart/legend/DefaultLegendEntry.d.ts +5 -0
  41. package/dts/chart/legend/DefaultLegendEntry.d.ts.map +1 -0
  42. package/dts/chart/legend/DefaultLegendShape.d.ts +5 -0
  43. package/dts/chart/legend/DefaultLegendShape.d.ts.map +1 -0
  44. package/dts/chart/legend/Legend.d.ts +168 -0
  45. package/dts/chart/legend/Legend.d.ts.map +1 -0
  46. package/dts/chart/legend/index.d.ts +4 -0
  47. package/dts/chart/legend/index.d.ts.map +1 -0
  48. package/dts/chart/line/DottedLine.d.ts.map +1 -1
  49. package/dts/chart/line/Line.d.ts +23 -19
  50. package/dts/chart/line/Line.d.ts.map +1 -1
  51. package/dts/chart/line/LineChart.d.ts +26 -9
  52. package/dts/chart/line/LineChart.d.ts.map +1 -1
  53. package/dts/chart/line/ReferenceLine.d.ts +1 -0
  54. package/dts/chart/line/ReferenceLine.d.ts.map +1 -1
  55. package/dts/chart/line/SolidLine.d.ts.map +1 -1
  56. package/dts/chart/point/Point.d.ts +26 -2
  57. package/dts/chart/point/Point.d.ts.map +1 -1
  58. package/dts/chart/scrubber/DefaultScrubberBeacon.d.ts +32 -2
  59. package/dts/chart/scrubber/DefaultScrubberBeacon.d.ts.map +1 -1
  60. package/dts/chart/scrubber/DefaultScrubberLabel.d.ts +2 -1
  61. package/dts/chart/scrubber/DefaultScrubberLabel.d.ts.map +1 -1
  62. package/dts/chart/scrubber/Scrubber.d.ts +86 -17
  63. package/dts/chart/scrubber/Scrubber.d.ts.map +1 -1
  64. package/dts/chart/scrubber/ScrubberAccessibilityView.d.ts +12 -0
  65. package/dts/chart/scrubber/ScrubberAccessibilityView.d.ts.map +1 -0
  66. package/dts/chart/scrubber/ScrubberBeaconGroup.d.ts +10 -0
  67. package/dts/chart/scrubber/ScrubberBeaconGroup.d.ts.map +1 -1
  68. package/dts/chart/scrubber/ScrubberBeaconLabelGroup.d.ts +16 -1
  69. package/dts/chart/scrubber/ScrubberBeaconLabelGroup.d.ts.map +1 -1
  70. package/dts/chart/scrubber/ScrubberProvider.d.ts.map +1 -1
  71. package/dts/chart/utils/axis.d.ts +45 -10
  72. package/dts/chart/utils/axis.d.ts.map +1 -1
  73. package/dts/chart/utils/bar.d.ts +190 -0
  74. package/dts/chart/utils/bar.d.ts.map +1 -1
  75. package/dts/chart/utils/chart.d.ts +32 -0
  76. package/dts/chart/utils/chart.d.ts.map +1 -1
  77. package/dts/chart/utils/context.d.ts +21 -6
  78. package/dts/chart/utils/context.d.ts.map +1 -1
  79. package/dts/chart/utils/gradient.d.ts +3 -1
  80. package/dts/chart/utils/gradient.d.ts.map +1 -1
  81. package/dts/chart/utils/path.d.ts +26 -0
  82. package/dts/chart/utils/path.d.ts.map +1 -1
  83. package/dts/chart/utils/point.d.ts +24 -12
  84. package/dts/chart/utils/point.d.ts.map +1 -1
  85. package/dts/chart/utils/scale.d.ts +11 -0
  86. package/dts/chart/utils/scale.d.ts.map +1 -1
  87. package/dts/chart/utils/scrubber.d.ts +2 -1
  88. package/dts/chart/utils/scrubber.d.ts.map +1 -1
  89. package/dts/chart/utils/transition.d.ts +63 -22
  90. package/dts/chart/utils/transition.d.ts.map +1 -1
  91. package/dts/sparkline/Sparkline.d.ts +2 -1
  92. package/dts/sparkline/Sparkline.d.ts.map +1 -1
  93. package/dts/sparkline/SparklineArea.d.ts +2 -1
  94. package/dts/sparkline/SparklineArea.d.ts.map +1 -1
  95. package/dts/sparkline/SparklineGradient.d.ts +2 -1
  96. package/dts/sparkline/SparklineGradient.d.ts.map +1 -1
  97. package/dts/sparkline/sparkline-interactive/SparklineInteractive.d.ts +2 -1
  98. package/dts/sparkline/sparkline-interactive/SparklineInteractive.d.ts.map +1 -1
  99. package/esm/chart/CartesianChart.js +176 -82
  100. package/esm/chart/ChartContextBridge.js +14 -3
  101. package/esm/chart/ChartProvider.js +2 -2
  102. package/esm/chart/Path.js +34 -29
  103. package/esm/chart/PeriodSelector.js +6 -2
  104. package/esm/chart/__stories__/CartesianChart.stories.js +27 -86
  105. package/esm/chart/__stories__/ChartAccessibility.stories.js +721 -0
  106. package/esm/chart/__stories__/ChartTransitions.stories.js +625 -0
  107. package/esm/chart/__stories__/PeriodSelector.stories.js +102 -4
  108. package/esm/chart/area/Area.js +21 -9
  109. package/esm/chart/area/AreaChart.js +18 -13
  110. package/esm/chart/area/DottedArea.js +28 -18
  111. package/esm/chart/area/GradientArea.js +14 -7
  112. package/esm/chart/area/SolidArea.js +6 -2
  113. package/esm/chart/area/__stories__/AreaChart.stories.js +47 -5
  114. package/esm/chart/axis/Axis.js +5 -41
  115. package/esm/chart/axis/XAxis.js +116 -47
  116. package/esm/chart/axis/YAxis.js +105 -26
  117. package/esm/chart/axis/__stories__/Axis.stories.js +324 -48
  118. package/esm/chart/bar/Bar.js +17 -15
  119. package/esm/chart/bar/BarChart.js +38 -33
  120. package/esm/chart/bar/BarPlot.js +40 -45
  121. package/esm/chart/bar/BarStack.js +92 -475
  122. package/esm/chart/bar/BarStackGroup.js +37 -27
  123. package/esm/chart/bar/DefaultBar.js +27 -18
  124. package/esm/chart/bar/DefaultBarStack.js +25 -9
  125. package/esm/chart/bar/__stories__/BarChart.stories.js +728 -54
  126. package/esm/chart/gradient/Gradient.js +2 -1
  127. package/esm/chart/index.js +1 -0
  128. package/esm/chart/legend/DefaultLegendEntry.js +42 -0
  129. package/esm/chart/legend/DefaultLegendShape.js +64 -0
  130. package/esm/chart/legend/Legend.js +59 -0
  131. package/esm/chart/legend/__stories__/Legend.stories.js +574 -0
  132. package/esm/chart/legend/index.js +3 -0
  133. package/esm/chart/line/DottedLine.js +6 -2
  134. package/esm/chart/line/Line.js +42 -38
  135. package/esm/chart/line/LineChart.js +36 -12
  136. package/esm/chart/line/SolidLine.js +6 -2
  137. package/esm/chart/line/__stories__/LineChart.stories.js +241 -594
  138. package/esm/chart/line/__stories__/ReferenceLine.stories.js +95 -1
  139. package/esm/chart/point/Point.js +35 -36
  140. package/esm/chart/scrubber/DefaultScrubberBeacon.js +41 -38
  141. package/esm/chart/scrubber/DefaultScrubberLabel.js +26 -10
  142. package/esm/chart/scrubber/Scrubber.js +67 -35
  143. package/esm/chart/scrubber/ScrubberAccessibilityView.js +177 -0
  144. package/esm/chart/scrubber/ScrubberBeaconGroup.js +30 -22
  145. package/esm/chart/scrubber/ScrubberBeaconLabelGroup.js +35 -8
  146. package/esm/chart/scrubber/ScrubberProvider.js +29 -24
  147. package/esm/chart/scrubber/__stories__/Scrubber.stories.js +946 -0
  148. package/esm/chart/utils/axis.js +88 -44
  149. package/esm/chart/utils/bar.js +820 -0
  150. package/esm/chart/utils/chart.js +34 -7
  151. package/esm/chart/utils/context.js +7 -0
  152. package/esm/chart/utils/gradient.js +8 -4
  153. package/esm/chart/utils/path.js +91 -61
  154. package/esm/chart/utils/point.js +92 -39
  155. package/esm/chart/utils/scale.js +13 -2
  156. package/esm/chart/utils/scrubber.js +12 -5
  157. package/esm/chart/utils/transition.js +108 -60
  158. package/esm/sparkline/Sparkline.js +2 -1
  159. package/esm/sparkline/SparklineArea.js +2 -1
  160. package/esm/sparkline/SparklineGradient.js +2 -1
  161. package/esm/sparkline/__figma__/Sparkline.figma.js +1 -1
  162. package/esm/sparkline/__stories__/Sparkline.stories.js +11 -7
  163. package/esm/sparkline/__stories__/SparklineGradient.stories.js +7 -4
  164. package/esm/sparkline/sparkline-interactive/SparklineInteractive.js +2 -1
  165. package/esm/sparkline/sparkline-interactive/__figma__/SparklineInteractive.figma.js +1 -1
  166. package/esm/sparkline/sparkline-interactive/__stories__/SparklineInteractive.stories.js +51 -26
  167. package/esm/sparkline/sparkline-interactive-header/__figma__/SparklineInteractiveHeader.figma.js +1 -1
  168. package/esm/sparkline/sparkline-interactive-header/__stories__/SparklineInteractiveHeader.stories.js +19 -9
  169. package/package.json +13 -10
  170. package/esm/chart/__stories__/Chart.stories.js +0 -77
@@ -0,0 +1,721 @@
1
+ const _excluded = ["label"],
2
+ _excluded2 = ["style"];
3
+ 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
+ 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
+ import { forwardRef, memo, useCallback, useMemo, useState } from 'react';
6
+ import { assets } from '@coinbase/cds-common/internal/data/assets';
7
+ import { sparklineInteractiveData } from '@coinbase/cds-common/internal/visualizations/SparklineInteractiveData';
8
+ import { useTabsContext } from '@coinbase/cds-common/tabs/TabsContext';
9
+ import { useTheme } from '@coinbase/cds-mobile';
10
+ import { IconButton } from '@coinbase/cds-mobile/buttons';
11
+ import { ExampleScreen } from '@coinbase/cds-mobile/examples/ExampleScreen';
12
+ import { Box, HStack, VStack } from '@coinbase/cds-mobile/layout';
13
+ import { RemoteImage } from '@coinbase/cds-mobile/media';
14
+ import { SectionHeader } from '@coinbase/cds-mobile/section-header/SectionHeader';
15
+ import { SegmentedTab } from '@coinbase/cds-mobile/tabs/SegmentedTab';
16
+ import { Text } from '@coinbase/cds-mobile/typography';
17
+ import { FontWeight, Skia, TextAlign } from '@shopify/react-native-skia';
18
+ import { XAxis, YAxis } from '../axis';
19
+ import { BarChart } from '../bar/BarChart';
20
+ import { BarPlot } from '../bar/BarPlot';
21
+ import { CartesianChart } from '../CartesianChart';
22
+ import { Legend } from '../legend';
23
+ import { Line, ReferenceLine, SolidLine } from '../line';
24
+ import { LineChart } from '../line/LineChart';
25
+ import { PeriodSelector, PeriodSelectorActiveIndicator } from '../PeriodSelector';
26
+ import { Scrubber } from '../scrubber';
27
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
28
+ const ThinSolidLine = /*#__PURE__*/memo(props => /*#__PURE__*/_jsx(SolidLine, _extends({}, props, {
29
+ strokeWidth: 1
30
+ })));
31
+ const BasicLineChart = /*#__PURE__*/memo(function BasicLineChart() {
32
+ const theme = useTheme();
33
+ const data = useMemo(() => [2, 4, 3, 6, 5, 8, 7], []);
34
+ const categories = useMemo(() => ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], []);
35
+ const getScrubberAccessibilityLabel = useCallback(index => categories[index] + ": " + data[index], [categories, data]);
36
+ return /*#__PURE__*/_jsx(LineChart, {
37
+ enableScrubbing: true,
38
+ showArea: true,
39
+ showXAxis: true,
40
+ showYAxis: true,
41
+ accessibilityLabel: "Line chart with " + data.length + " days of data. Swipe to navigate.",
42
+ getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
43
+ height: 180,
44
+ inset: {
45
+ top: 16,
46
+ right: 16,
47
+ bottom: 0,
48
+ left: 0
49
+ },
50
+ series: [{
51
+ id: 'line',
52
+ data,
53
+ color: theme.color.accentBoldBlue
54
+ }],
55
+ xAxis: {
56
+ data: categories,
57
+ showGrid: true
58
+ },
59
+ yAxis: {
60
+ domain: {
61
+ min: 0
62
+ },
63
+ showGrid: true
64
+ },
65
+ children: /*#__PURE__*/_jsx(Scrubber, {
66
+ hideOverlay: true
67
+ })
68
+ });
69
+ });
70
+ const DataFormatLineChart = /*#__PURE__*/memo(function DataFormatLineChart() {
71
+ const theme = useTheme();
72
+ const yData = useMemo(() => [2, 5.5, 2, 8.5, 1.5, 5], []);
73
+ const xData = useMemo(() => [1, 2, 3, 5, 8, 10], []);
74
+ const chartAccessibilityLabel = "Chart with uneven X values " + xData.join(', ') + ". " + yData.length + " data points.";
75
+ const getScrubberAccessibilityLabel = useCallback(index => "Point " + (index + 1) + ": X value " + xData[index] + ", Y value " + yData[index], [xData, yData]);
76
+ return /*#__PURE__*/_jsx(LineChart, {
77
+ enableScrubbing: true,
78
+ points: true,
79
+ showArea: true,
80
+ showXAxis: true,
81
+ showYAxis: true,
82
+ accessibilityLabel: chartAccessibilityLabel,
83
+ curve: "natural",
84
+ getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
85
+ height: 180,
86
+ inset: {
87
+ top: 16,
88
+ right: 16,
89
+ bottom: 0,
90
+ left: 0
91
+ },
92
+ series: [{
93
+ id: 'line',
94
+ data: yData,
95
+ color: theme.color.accentBoldGreen
96
+ }],
97
+ xAxis: {
98
+ data: xData,
99
+ showLine: true,
100
+ showTickMarks: true,
101
+ showGrid: true
102
+ },
103
+ yAxis: {
104
+ domain: {
105
+ min: 0
106
+ },
107
+ position: 'left',
108
+ showLine: true,
109
+ showTickMarks: true,
110
+ showGrid: true
111
+ },
112
+ children: /*#__PURE__*/_jsx(Scrubber, {
113
+ hideOverlay: true
114
+ })
115
+ });
116
+ });
117
+ const AccessibilityBarChart = /*#__PURE__*/memo(function AccessibilityBarChart() {
118
+ const theme = useTheme();
119
+ const categories = useMemo(() => ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'], []);
120
+ const values = useMemo(() => [40, 65, 55, 80, 72, 90], []);
121
+ const getScrubberAccessibilityLabel = useCallback(index => categories[index] + ": " + values[index], [categories, values]);
122
+ return /*#__PURE__*/_jsx(BarChart, {
123
+ enableScrubbing: true,
124
+ showXAxis: true,
125
+ showYAxis: true,
126
+ accessibilityLabel: "Bar chart with " + values.length + " months. Swipe to navigate.",
127
+ getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
128
+ height: 180,
129
+ inset: {
130
+ top: 16,
131
+ right: 16,
132
+ bottom: 0,
133
+ left: 0
134
+ },
135
+ series: [{
136
+ id: 'bars',
137
+ data: values,
138
+ color: theme.color.accentBoldPurple
139
+ }],
140
+ xAxis: {
141
+ data: categories,
142
+ showGrid: true
143
+ },
144
+ yAxis: {
145
+ domain: {
146
+ min: 0
147
+ },
148
+ showGrid: true
149
+ }
150
+ });
151
+ });
152
+ const AccessibilityHorizontalBarChart = /*#__PURE__*/memo(function AccessibilityHorizontalBarChart() {
153
+ const theme = useTheme();
154
+ const dataset = useMemo(() => [{
155
+ month: 'Jan',
156
+ rainfall: 21
157
+ }, {
158
+ month: 'Feb',
159
+ rainfall: 28
160
+ }, {
161
+ month: 'Mar',
162
+ rainfall: 41
163
+ }, {
164
+ month: 'Apr',
165
+ rainfall: 73
166
+ }, {
167
+ month: 'May',
168
+ rainfall: 99
169
+ }, {
170
+ month: 'June',
171
+ rainfall: 144
172
+ }, {
173
+ month: 'July',
174
+ rainfall: 319
175
+ }, {
176
+ month: 'Aug',
177
+ rainfall: 249
178
+ }, {
179
+ month: 'Sept',
180
+ rainfall: 131
181
+ }, {
182
+ month: 'Oct',
183
+ rainfall: 55
184
+ }, {
185
+ month: 'Nov',
186
+ rainfall: 48
187
+ }, {
188
+ month: 'Dec',
189
+ rainfall: 25
190
+ }], []);
191
+ const getScrubberAccessibilityLabel = useCallback(index => dataset[index].month + ": " + dataset[index].rainfall + "mm rainfall", [dataset]);
192
+ return /*#__PURE__*/_jsx(BarChart, {
193
+ enableScrubbing: true,
194
+ showXAxis: true,
195
+ showYAxis: true,
196
+ accessibilityLabel: "Horizontal bar chart showing Seoul rainfall by month. " + dataset.length + " months. Swipe to navigate.",
197
+ borderRadius: 2,
198
+ getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
199
+ height: 400,
200
+ inset: {
201
+ top: 16,
202
+ right: 16,
203
+ bottom: 0,
204
+ left: 0
205
+ },
206
+ layout: "horizontal",
207
+ series: [{
208
+ id: 'seoul',
209
+ label: 'Seoul rainfall',
210
+ data: dataset.map(d => d.rainfall),
211
+ color: theme.color.accentBoldBlue
212
+ }],
213
+ xAxis: {
214
+ label: 'rainfall (mm)',
215
+ GridLineComponent: props => /*#__PURE__*/_jsx(SolidLine, _extends({}, props, {
216
+ strokeWidth: 1
217
+ })),
218
+ showGrid: true,
219
+ showLine: true,
220
+ showTickMarks: true
221
+ },
222
+ yAxis: {
223
+ position: 'left',
224
+ data: dataset.map(d => d.month),
225
+ showLine: true,
226
+ showTickMarks: true,
227
+ bandTickMarkPlacement: 'edges'
228
+ }
229
+ });
230
+ });
231
+ const ServiceAvailability = /*#__PURE__*/memo(function ServiceAvailability() {
232
+ const theme = useTheme();
233
+ const availabilityEvents = useMemo(() => [{
234
+ date: new Date('2022-01-01'),
235
+ availability: 79
236
+ }, {
237
+ date: new Date('2022-01-03'),
238
+ availability: 81
239
+ }, {
240
+ date: new Date('2022-01-04'),
241
+ availability: 82
242
+ }, {
243
+ date: new Date('2022-01-06'),
244
+ availability: 91
245
+ }, {
246
+ date: new Date('2022-01-07'),
247
+ availability: 92
248
+ }, {
249
+ date: new Date('2022-01-10'),
250
+ availability: 86
251
+ }], []);
252
+ const getScrubberAccessibilityLabel = useCallback(index => "Point " + (index + 1) + ": " + availabilityEvents[index].availability + "% availability on " + availabilityEvents[index].date.toLocaleDateString(), [availabilityEvents]);
253
+ return /*#__PURE__*/_jsxs(CartesianChart, {
254
+ enableScrubbing: true,
255
+ accessibilityLabel: "Service availability chart with " + availabilityEvents.length + " data points. Swipe to navigate.",
256
+ getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
257
+ height: 200,
258
+ scrubberAccessibilityLabelStep: 1,
259
+ series: [{
260
+ id: 'availability',
261
+ data: availabilityEvents.map(event => event.availability),
262
+ gradient: {
263
+ stops: _ref => {
264
+ let {
265
+ min,
266
+ max
267
+ } = _ref;
268
+ return [{
269
+ offset: min,
270
+ color: theme.color.fgNegative
271
+ }, {
272
+ offset: 85,
273
+ color: theme.color.fgNegative
274
+ }, {
275
+ offset: 85,
276
+ color: theme.color.fgWarning
277
+ }, {
278
+ offset: 90,
279
+ color: theme.color.fgWarning
280
+ }, {
281
+ offset: 90,
282
+ color: theme.color.fgPositive
283
+ }, {
284
+ offset: max,
285
+ color: theme.color.fgPositive
286
+ }];
287
+ }
288
+ }
289
+ }],
290
+ xAxis: {
291
+ data: availabilityEvents.map(event => event.date.getTime())
292
+ },
293
+ yAxis: {
294
+ domain: _ref2 => {
295
+ let {
296
+ min,
297
+ max
298
+ } = _ref2;
299
+ return {
300
+ min: Math.max(min - 2, 0),
301
+ max: Math.min(max + 2, 100)
302
+ };
303
+ }
304
+ },
305
+ children: [/*#__PURE__*/_jsx(XAxis, {
306
+ showGrid: true,
307
+ showLine: true,
308
+ showTickMarks: true,
309
+ tickLabelFormatter: value => new Date(value).toLocaleDateString()
310
+ }), /*#__PURE__*/_jsx(YAxis, {
311
+ showGrid: true,
312
+ showLine: true,
313
+ showTickMarks: true,
314
+ position: "left",
315
+ tickLabelFormatter: value => value + "%"
316
+ }), /*#__PURE__*/_jsx(Line, {
317
+ curve: "stepAfter",
318
+ points: props => _extends({}, props, {
319
+ fill: theme.color.bg,
320
+ stroke: props.fill
321
+ }),
322
+ seriesId: "availability"
323
+ }), /*#__PURE__*/_jsx(Scrubber, {
324
+ hideOverlay: true
325
+ })]
326
+ });
327
+ });
328
+ const BasicPricesWithManyPoints = /*#__PURE__*/memo(function BasicPricesWithManyPoints() {
329
+ const theme = useTheme();
330
+ const data = useMemo(() => [10, 22, 29, 45, 98, 45, 22, 52, 21, 4, 68, 20, 21, 58, 10, 22, 29, 45, 98, 45, 22, 52, 21, 4, 68, 20, 21, 58], []);
331
+ const getScrubberAccessibilityLabel = useCallback(index => "Point " + (index + 1) + ": " + data[index], [data]);
332
+ return /*#__PURE__*/_jsx(LineChart, {
333
+ enableScrubbing: true,
334
+ showArea: true,
335
+ accessibilityLabel: "Line chart with " + data.length + " data points. Swipe to navigate.",
336
+ getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
337
+ height: 200,
338
+ scrubberAccessibilityLabelStep: 1,
339
+ series: [{
340
+ id: 'prices',
341
+ data,
342
+ color: theme.color.accentBoldBlue
343
+ }],
344
+ children: /*#__PURE__*/_jsx(Scrubber, {
345
+ hideOverlay: true
346
+ })
347
+ });
348
+ });
349
+ const PositiveAndNegativeCashFlow = /*#__PURE__*/memo(function PositiveAndNegativeCashFlow() {
350
+ const theme = useTheme();
351
+ const categories = useMemo(() => Array.from({
352
+ length: 31
353
+ }, (_, i) => "3/" + (i + 1)), []);
354
+ const gains = useMemo(() => [5, 0, 6, 18, 0, 5, 12, 0, 12, 22, 28, 18, 0, 12, 6, 0, 0, 24, 0, 0, 4, 0, 18, 0, 0, 14, 10, 16, 0, 0, 0], []);
355
+ const losses = useMemo(() => [-4, 0, -8, -12, -6, 0, 0, 0, -18, 0, -12, 0, -9, -6, 0, 0, 0, 0, -22, -8, 0, 0, -10, -14, 0, 0, 0, 0, 0, -12, -10], []);
356
+ const series = useMemo(() => [{
357
+ id: 'gains',
358
+ data: gains,
359
+ color: theme.color.fgPositive,
360
+ stackId: 'bars'
361
+ }, {
362
+ id: 'losses',
363
+ data: losses,
364
+ color: theme.color.fgNegative,
365
+ stackId: 'bars'
366
+ }], [gains, losses, theme.color.fgNegative, theme.color.fgPositive]);
367
+ const getScrubberAccessibilityLabel = useCallback(index => {
368
+ const net = gains[index] + losses[index];
369
+ const netStr = net >= 0 ? "+$" + net + "M" : "-$" + Math.abs(net) + "M";
370
+ return categories[index] + ": " + netStr;
371
+ }, [categories, gains, losses]);
372
+ return /*#__PURE__*/_jsxs(CartesianChart, {
373
+ enableScrubbing: true,
374
+ accessibilityLabel: "Cash flow chart: " + categories.length + " days with gains and losses. Swipe to navigate.",
375
+ getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
376
+ height: 280,
377
+ inset: 32,
378
+ series: series,
379
+ xAxis: {
380
+ data: categories,
381
+ scaleType: 'band'
382
+ },
383
+ children: [/*#__PURE__*/_jsx(XAxis, {}), /*#__PURE__*/_jsx(YAxis, {
384
+ showGrid: true,
385
+ GridLineComponent: ThinSolidLine,
386
+ tickLabelFormatter: value => "$" + value + "M"
387
+ }), /*#__PURE__*/_jsx(BarPlot, {}), /*#__PURE__*/_jsx(ReferenceLine, {
388
+ LineComponent: SolidLine,
389
+ dataY: 0
390
+ })]
391
+ });
392
+ });
393
+ const LegendPosition = /*#__PURE__*/memo(function LegendPosition() {
394
+ const theme = useTheme();
395
+ const categories = useMemo(() => ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'], []);
396
+ const revenueData = useMemo(() => [455, 520, 380, 455, 285, 235], []);
397
+ const profitMarginData = useMemo(() => [23, 20, 16, 38, 12, 9], []);
398
+ const getScrubberAccessibilityLabel = useCallback(index => categories[index] + ": Revenue $" + revenueData[index] + "k, Profit Margin " + profitMarginData[index] + "%", [categories, profitMarginData, revenueData]);
399
+ return /*#__PURE__*/_jsxs(CartesianChart, {
400
+ enableScrubbing: true,
401
+ accessibilityLabel: "Bar chart showing Revenue and Profit Margin by month. January through June. Swipe to navigate.",
402
+ getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
403
+ height: 200,
404
+ inset: {
405
+ bottom: 8,
406
+ left: 0,
407
+ right: 0,
408
+ top: 8
409
+ },
410
+ legend: /*#__PURE__*/_jsx(Legend, {
411
+ accessibilityLabel: "Chart legend: Revenue and Profit Margin",
412
+ justifyContent: "flex-end"
413
+ }),
414
+ legendPosition: "bottom",
415
+ series: [{
416
+ id: 'revenue',
417
+ label: 'Revenue',
418
+ data: revenueData,
419
+ yAxisId: 'revenue',
420
+ color: "rgb(" + theme.spectrum.yellow40 + ")",
421
+ legendShape: 'squircle'
422
+ }, {
423
+ id: 'profitMargin',
424
+ label: 'Profit Margin',
425
+ data: profitMarginData,
426
+ yAxisId: 'profitMargin',
427
+ color: theme.color.fgPositive,
428
+ legendShape: 'squircle'
429
+ }],
430
+ xAxis: {
431
+ data: categories,
432
+ scaleType: 'band',
433
+ range: _ref3 => {
434
+ let {
435
+ min,
436
+ max
437
+ } = _ref3;
438
+ return {
439
+ min,
440
+ max: max - 128
441
+ };
442
+ }
443
+ },
444
+ yAxis: [{
445
+ id: 'revenue',
446
+ domain: {
447
+ min: 0
448
+ }
449
+ }, {
450
+ id: 'profitMargin',
451
+ domain: {
452
+ max: 100,
453
+ min: 0
454
+ }
455
+ }],
456
+ children: [/*#__PURE__*/_jsx(XAxis, {
457
+ showLine: true,
458
+ showTickMarks: true
459
+ }), /*#__PURE__*/_jsx(YAxis, {
460
+ showGrid: true,
461
+ showLine: true,
462
+ showTickMarks: true,
463
+ axisId: "revenue",
464
+ position: "left",
465
+ requestedTickCount: 5,
466
+ tickLabelFormatter: value => "$" + value + "k",
467
+ width: 60
468
+ }), /*#__PURE__*/_jsx(YAxis, {
469
+ showLine: true,
470
+ showTickMarks: true,
471
+ axisId: "profitMargin",
472
+ position: "right",
473
+ requestedTickCount: 5,
474
+ tickLabelFormatter: value => value + "%"
475
+ }), /*#__PURE__*/_jsx(BarPlot, {})]
476
+ });
477
+ });
478
+ const AssetPriceWithDottedArea = /*#__PURE__*/memo(function AssetPriceWithDottedArea() {
479
+ const theme = useTheme();
480
+ const fontMgr = useMemo(() => Skia.TypefaceFontProvider.Make(), []);
481
+ const tabs = useMemo(() => [{
482
+ id: 'hour',
483
+ label: '1H'
484
+ }, {
485
+ id: 'day',
486
+ label: '1D'
487
+ }, {
488
+ id: 'week',
489
+ label: '1W'
490
+ }, {
491
+ id: 'month',
492
+ label: '1M'
493
+ }, {
494
+ id: 'year',
495
+ label: '1Y'
496
+ }, {
497
+ id: 'all',
498
+ label: 'All'
499
+ }], []);
500
+ const [timePeriod, setTimePeriod] = useState(tabs[0]);
501
+ const sparklineTimePeriodData = useMemo(() => sparklineInteractiveData[timePeriod.id], [timePeriod]);
502
+ const sparklineTimePeriodDataValues = useMemo(() => sparklineTimePeriodData.map(d => d.value), [sparklineTimePeriodData]);
503
+ const sparklineTimePeriodDataTimestamps = useMemo(() => sparklineTimePeriodData.map(d => d.date), [sparklineTimePeriodData]);
504
+ const currentPrice = sparklineTimePeriodDataValues[sparklineTimePeriodDataValues.length - 1];
505
+ const priceFormatter = useMemo(() => new Intl.NumberFormat('en-US', {
506
+ style: 'currency',
507
+ currency: 'USD'
508
+ }), []);
509
+ const formatPrice = useCallback(price => priceFormatter.format(price), [priceFormatter]);
510
+ const formatDate = useCallback(date => {
511
+ const dayOfWeek = date.toLocaleDateString('en-US', {
512
+ weekday: 'short'
513
+ });
514
+ const monthDay = date.toLocaleDateString('en-US', {
515
+ month: 'short',
516
+ day: 'numeric'
517
+ });
518
+ const time = date.toLocaleTimeString('en-US', {
519
+ hour: 'numeric',
520
+ minute: '2-digit',
521
+ hour12: true
522
+ });
523
+ return dayOfWeek + ", " + monthDay + ", " + time;
524
+ }, []);
525
+ const chartAccessibilityLabel = useMemo(() => "Bitcoin price chart for " + timePeriod.label + " period. Current price: " + formatPrice(currentPrice) + ".", [currentPrice, formatPrice, timePeriod.label]);
526
+ const getScrubberAccessibilityLabel = useCallback(index => {
527
+ const price = formatPrice(sparklineTimePeriodDataValues[index]);
528
+ const date = formatDate(sparklineTimePeriodDataTimestamps[index]);
529
+ return price + " " + date;
530
+ }, [formatDate, formatPrice, sparklineTimePeriodDataTimestamps, sparklineTimePeriodDataValues]);
531
+ const BTCTab = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref4, ref) => {
532
+ let {
533
+ label
534
+ } = _ref4,
535
+ props = _objectWithoutPropertiesLoose(_ref4, _excluded);
536
+ const {
537
+ activeTab
538
+ } = useTabsContext();
539
+ const isActive = (activeTab == null ? void 0 : activeTab.id) === props.id;
540
+ return /*#__PURE__*/_jsx(SegmentedTab, _extends({
541
+ ref: ref,
542
+ label: /*#__PURE__*/_jsx(Text, {
543
+ font: "label1",
544
+ style: {
545
+ color: isActive ? assets.btc.color : undefined
546
+ },
547
+ children: label
548
+ })
549
+ }, props));
550
+ }));
551
+ const BTCActiveIndicator = /*#__PURE__*/memo(_ref5 => {
552
+ let {
553
+ style
554
+ } = _ref5,
555
+ props = _objectWithoutPropertiesLoose(_ref5, _excluded2);
556
+ return /*#__PURE__*/_jsx(PeriodSelectorActiveIndicator, _extends({}, props, {
557
+ style: [style, {
558
+ backgroundColor: assets.btc.color + "1A"
559
+ }]
560
+ }));
561
+ });
562
+ const onPeriodChange = useCallback(period => setTimePeriod(period || tabs[0]), [tabs]);
563
+ return /*#__PURE__*/_jsxs(VStack, {
564
+ gap: 2,
565
+ children: [/*#__PURE__*/_jsx(SectionHeader, {
566
+ balance: /*#__PURE__*/_jsx(Text, {
567
+ font: "title2",
568
+ children: formatPrice(currentPrice)
569
+ }),
570
+ end: /*#__PURE__*/_jsx(VStack, {
571
+ justifyContent: "center",
572
+ children: /*#__PURE__*/_jsx(RemoteImage, {
573
+ shape: "circle",
574
+ size: "xl",
575
+ source: assets.btc.imageUrl
576
+ })
577
+ }),
578
+ title: /*#__PURE__*/_jsx(Text, {
579
+ font: "title1",
580
+ children: "Bitcoin"
581
+ })
582
+ }), /*#__PURE__*/_jsx(LineChart, {
583
+ enableScrubbing: true,
584
+ showArea: true,
585
+ accessibilityLabel: chartAccessibilityLabel,
586
+ areaType: "dotted",
587
+ getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
588
+ height: 200,
589
+ inset: {
590
+ top: 52
591
+ },
592
+ series: [{
593
+ id: 'btc',
594
+ data: sparklineTimePeriodDataValues,
595
+ color: assets.btc.color
596
+ }],
597
+ children: /*#__PURE__*/_jsx(Scrubber, {
598
+ hideOverlay: true,
599
+ idlePulse: true,
600
+ labelElevated: true,
601
+ label: d => {
602
+ const date = formatDate(sparklineTimePeriodDataTimestamps[d]);
603
+ const price = formatPrice(sparklineTimePeriodDataValues[d]);
604
+ const regularStyle = {
605
+ fontFamilies: ['Inter'],
606
+ fontSize: 14,
607
+ fontStyle: {
608
+ weight: FontWeight.Normal
609
+ },
610
+ color: Skia.Color(theme.color.fgMuted)
611
+ };
612
+ const boldStyle = _extends({}, regularStyle, {
613
+ fontStyle: {
614
+ weight: FontWeight.Bold
615
+ }
616
+ });
617
+ const builder = Skia.ParagraphBuilder.Make({
618
+ textAlign: TextAlign.Left
619
+ }, fontMgr);
620
+ builder.pushStyle(boldStyle);
621
+ builder.addText(price);
622
+ builder.pushStyle(regularStyle);
623
+ builder.addText(" " + date);
624
+ const para = builder.build();
625
+ para.layout(512);
626
+ return para;
627
+ }
628
+ })
629
+ }), /*#__PURE__*/_jsx(PeriodSelector, {
630
+ TabComponent: BTCTab,
631
+ TabsActiveIndicatorComponent: BTCActiveIndicator,
632
+ activeTab: timePeriod,
633
+ onChange: onPeriodChange,
634
+ tabs: tabs
635
+ })]
636
+ });
637
+ });
638
+ function ExampleNavigator() {
639
+ const [currentIndex, setCurrentIndex] = useState(0);
640
+ const examples = useMemo(() => [{
641
+ title: 'Basic Line Chart',
642
+ component: /*#__PURE__*/_jsx(BasicLineChart, {})
643
+ }, {
644
+ title: 'Data Format (Uneven X)',
645
+ component: /*#__PURE__*/_jsx(DataFormatLineChart, {})
646
+ }, {
647
+ title: 'Bar Chart',
648
+ component: /*#__PURE__*/_jsx(AccessibilityBarChart, {})
649
+ }, {
650
+ title: 'Horizontal Bar Chart',
651
+ component: /*#__PURE__*/_jsx(AccessibilityHorizontalBarChart, {})
652
+ }, {
653
+ title: 'Service Availability',
654
+ component: /*#__PURE__*/_jsx(ServiceAvailability, {})
655
+ }, {
656
+ title: 'Basic Prices (28 pts, step 1)',
657
+ component: /*#__PURE__*/_jsx(BasicPricesWithManyPoints, {})
658
+ }, {
659
+ title: 'Positive/Negative Cash Flow',
660
+ component: /*#__PURE__*/_jsx(PositiveAndNegativeCashFlow, {})
661
+ }, {
662
+ title: 'Legend Position',
663
+ component: /*#__PURE__*/_jsx(LegendPosition, {})
664
+ }, {
665
+ title: 'Bitcoin Price (Dotted Area)',
666
+ component: /*#__PURE__*/_jsx(AssetPriceWithDottedArea, {})
667
+ }], []);
668
+ const currentExample = examples[currentIndex];
669
+ const handlePrevious = useCallback(() => {
670
+ setCurrentIndex(prev => (prev - 1 + examples.length) % examples.length);
671
+ }, [examples.length]);
672
+ const handleNext = useCallback(() => {
673
+ setCurrentIndex(prev => (prev + 1 + examples.length) % examples.length);
674
+ }, [examples.length]);
675
+ return /*#__PURE__*/_jsx(ExampleScreen, {
676
+ paddingX: 0,
677
+ children: /*#__PURE__*/_jsxs(VStack, {
678
+ gap: 4,
679
+ children: [/*#__PURE__*/_jsxs(HStack, {
680
+ alignItems: "center",
681
+ justifyContent: "space-between",
682
+ padding: 2,
683
+ children: [/*#__PURE__*/_jsx(IconButton, {
684
+ accessibilityHint: "Navigate to previous example",
685
+ accessibilityLabel: "Previous",
686
+ name: "arrowLeft",
687
+ onPress: handlePrevious,
688
+ variant: "secondary"
689
+ }), /*#__PURE__*/_jsxs(VStack, {
690
+ alignItems: "center",
691
+ children: [/*#__PURE__*/_jsx(Text, {
692
+ font: "title3",
693
+ children: currentExample.title
694
+ }), /*#__PURE__*/_jsxs(Text, {
695
+ color: "fgMuted",
696
+ font: "label1",
697
+ children: [currentIndex + 1, " / ", examples.length]
698
+ })]
699
+ }), /*#__PURE__*/_jsx(IconButton, {
700
+ accessibilityHint: "Navigate to next example",
701
+ accessibilityLabel: "Next",
702
+ name: "arrowRight",
703
+ onPress: handleNext,
704
+ variant: "secondary"
705
+ })]
706
+ }), /*#__PURE__*/_jsxs(VStack, {
707
+ gap: 2,
708
+ padding: 2,
709
+ children: [/*#__PURE__*/_jsx(Text, {
710
+ color: "fgMuted",
711
+ font: "label2",
712
+ children: "Swipe to navigate chart segments."
713
+ }), /*#__PURE__*/_jsx(Box, {
714
+ padding: 1,
715
+ children: currentExample.component
716
+ })]
717
+ })]
718
+ })
719
+ });
720
+ }
721
+ export default ExampleNavigator;