@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,574 @@
1
+ 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); }
2
+ import { memo, useCallback, useMemo, useState } from 'react';
3
+ import { ScrollView } from 'react-native';
4
+ import { Chip } from '@coinbase/cds-mobile/chips';
5
+ import { Example, ExampleScreen } from '@coinbase/cds-mobile/examples/ExampleScreen';
6
+ import { useTheme } from '@coinbase/cds-mobile/hooks/useTheme';
7
+ import { Box, HStack, VStack } from '@coinbase/cds-mobile/layout';
8
+ import { TextLabel1, TextLabel2 } from '@coinbase/cds-mobile/typography';
9
+ import { Canvas, Group, Path as SkiaPath, Skia } from '@shopify/react-native-skia';
10
+ import { XAxis, YAxis } from '../../axis';
11
+ import { BarChart, BarPlot, DefaultBar } from '../../bar';
12
+ import { CartesianChart } from '../../CartesianChart';
13
+ import { LineChart } from '../../line';
14
+ import { Scrubber } from '../../scrubber';
15
+ import { getDottedAreaPath } from '../../utils/path';
16
+ import { DefaultLegendShape } from '../DefaultLegendShape';
17
+ import { Legend } from '../Legend';
18
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
19
+ const spectrumColors = ['blue40', 'green40', 'orange40', 'yellow40', 'gray40', 'indigo40', 'pink40', 'purple40', 'red40', 'teal40'];
20
+ const shapes = ['pill', 'circle', 'squircle', 'square'];
21
+ const Shapes = () => {
22
+ const theme = useTheme();
23
+ return /*#__PURE__*/_jsx(VStack, {
24
+ gap: 2,
25
+ children: shapes.map(shape => /*#__PURE__*/_jsx(HStack, {
26
+ gap: 1,
27
+ children: spectrumColors.map(color => /*#__PURE__*/_jsx(Box, {
28
+ style: {
29
+ width: 10,
30
+ justifyContent: 'center'
31
+ },
32
+ children: /*#__PURE__*/_jsx(DefaultLegendShape, {
33
+ color: "rgb(" + theme.spectrum[color] + ")",
34
+ shape: shape
35
+ })
36
+ }, color))
37
+ }, shape))
38
+ });
39
+ };
40
+ const BasicLegend = () => {
41
+ const theme = useTheme();
42
+ const pages = useMemo(() => ['Page A', 'Page B', 'Page C', 'Page D', 'Page E', 'Page F', 'Page G'], []);
43
+ const pageViews = useMemo(() => [2400, 1398, 9800, 3908, 4800, 3800, 4300], []);
44
+ const uniqueVisitors = useMemo(() => [4000, 3000, 2000, 2780, 1890, 2390, 3490], []);
45
+ const numberFormatter = useCallback(value => new Intl.NumberFormat('en-US', {
46
+ maximumFractionDigits: 0
47
+ }).format(value), []);
48
+ const chartAccessibilityLabel = "Website traffic across " + pages.length + " pages showing page views and unique visitors.";
49
+ return /*#__PURE__*/_jsx(LineChart, {
50
+ enableScrubbing: true,
51
+ legend: true,
52
+ showArea: true,
53
+ accessibilityLabel: chartAccessibilityLabel,
54
+ height: 150,
55
+ legendPosition: "right",
56
+ series: [{
57
+ id: 'pageViews',
58
+ data: pageViews,
59
+ color: "rgb(" + theme.spectrum.green40 + ")",
60
+ label: 'Page Views'
61
+ }, {
62
+ id: 'uniqueVisitors',
63
+ data: uniqueVisitors,
64
+ color: "rgb(" + theme.spectrum.purple40 + ")",
65
+ label: 'Unique Visitors',
66
+ areaType: 'dotted'
67
+ }],
68
+ width: "100%",
69
+ xAxis: {
70
+ data: pages
71
+ },
72
+ yAxis: {
73
+ showGrid: true,
74
+ tickLabelFormatter: numberFormatter
75
+ },
76
+ children: /*#__PURE__*/_jsx(Scrubber, {})
77
+ });
78
+ };
79
+ const Position = () => {
80
+ const theme = useTheme();
81
+ return /*#__PURE__*/_jsxs(CartesianChart, {
82
+ height: 200,
83
+ inset: {
84
+ bottom: 8,
85
+ left: 0,
86
+ right: 0,
87
+ top: 8
88
+ },
89
+ legend: /*#__PURE__*/_jsx(Legend, {
90
+ justifyContent: "flex-end"
91
+ }),
92
+ legendPosition: "bottom",
93
+ series: [{
94
+ id: 'revenue',
95
+ label: 'Revenue',
96
+ data: [455, 520, 380, 455, 285, 235],
97
+ yAxisId: 'revenue',
98
+ color: "rgb(" + theme.spectrum.yellow40 + ")",
99
+ legendShape: 'squircle'
100
+ }, {
101
+ id: 'profitMargin',
102
+ label: 'Profit Margin',
103
+ data: [23, 20, 16, 38, 12, 9],
104
+ yAxisId: 'profitMargin',
105
+ color: theme.color.fgPositive,
106
+ legendShape: 'squircle'
107
+ }],
108
+ width: "100%",
109
+ xAxis: {
110
+ data: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
111
+ scaleType: 'band'
112
+ },
113
+ yAxis: [{
114
+ id: 'revenue',
115
+ domain: {
116
+ min: 0
117
+ }
118
+ }, {
119
+ id: 'profitMargin',
120
+ domain: {
121
+ max: 100,
122
+ min: 0
123
+ }
124
+ }],
125
+ children: [/*#__PURE__*/_jsx(XAxis, {
126
+ showLine: true,
127
+ showTickMarks: true
128
+ }), /*#__PURE__*/_jsx(YAxis, {
129
+ showGrid: true,
130
+ showLine: true,
131
+ showTickMarks: true,
132
+ axisId: "revenue",
133
+ position: "left",
134
+ requestedTickCount: 5,
135
+ tickLabelFormatter: value => "$" + value + "k",
136
+ width: 60
137
+ }), /*#__PURE__*/_jsx(YAxis, {
138
+ showLine: true,
139
+ showTickMarks: true,
140
+ axisId: "profitMargin",
141
+ position: "right",
142
+ requestedTickCount: 5,
143
+ tickLabelFormatter: value => value + "%"
144
+ }), /*#__PURE__*/_jsx(BarPlot, {})]
145
+ });
146
+ };
147
+ const ShapeVariants = () => {
148
+ const theme = useTheme();
149
+ const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'];
150
+ return /*#__PURE__*/_jsx(LineChart, {
151
+ legend: true,
152
+ showArea: true,
153
+ height: 200,
154
+ legendPosition: "left",
155
+ series: [{
156
+ id: 'pill',
157
+ label: 'Pill',
158
+ data: [120, 150, 130, 170, 160, 190],
159
+ color: "rgb(" + theme.spectrum.blue40 + ")",
160
+ legendShape: 'pill'
161
+ }, {
162
+ id: 'circle',
163
+ label: 'Circle',
164
+ data: [80, 110, 95, 125, 115, 140],
165
+ color: "rgb(" + theme.spectrum.green40 + ")",
166
+ legendShape: 'circle'
167
+ }, {
168
+ id: 'square',
169
+ label: 'Square',
170
+ data: [60, 85, 70, 100, 90, 115],
171
+ color: "rgb(" + theme.spectrum.orange40 + ")",
172
+ legendShape: 'square'
173
+ }, {
174
+ id: 'squircle',
175
+ label: 'Squircle',
176
+ data: [40, 60, 50, 75, 65, 85],
177
+ color: "rgb(" + theme.spectrum.purple40 + ")",
178
+ legendShape: 'squircle'
179
+ }],
180
+ width: "100%",
181
+ xAxis: {
182
+ data: months
183
+ },
184
+ yAxis: {
185
+ domain: {
186
+ min: 0
187
+ },
188
+ showGrid: true
189
+ }
190
+ });
191
+ };
192
+ const DynamicData = () => {
193
+ var _seriesConfig$0$data$, _seriesConfig$0$data;
194
+ const theme = useTheme();
195
+ const [scrubberPosition, setScrubberPosition] = useState();
196
+ const timeLabels = useMemo(() => ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], []);
197
+ const seriesConfig = useMemo(() => [{
198
+ id: 'candidate-a',
199
+ label: 'Candidate A',
200
+ data: [48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 38],
201
+ color: "rgb(" + theme.spectrum.blue40 + ")",
202
+ legendShape: 'circle'
203
+ }, {
204
+ id: 'candidate-b',
205
+ label: 'Candidate B',
206
+ data: [null, null, null, 6, 10, 14, 18, 22, 26, 29, 32, 35],
207
+ color: "rgb(" + theme.spectrum.orange40 + ")",
208
+ legendShape: 'circle'
209
+ }, {
210
+ id: 'candidate-c',
211
+ label: 'Candidate C',
212
+ data: [52, 53, 54, 49, 46, 43, 40, 37, 34, 32, 30, 27],
213
+ color: "rgb(" + theme.spectrum.gray40 + ")",
214
+ legendShape: 'circle'
215
+ }], [theme.spectrum.blue40, theme.spectrum.gray40, theme.spectrum.orange40]);
216
+ const dataLength = (_seriesConfig$0$data$ = (_seriesConfig$0$data = seriesConfig[0].data) == null ? void 0 : _seriesConfig$0$data.length) != null ? _seriesConfig$0$data$ : 0;
217
+ const dataIndex = scrubberPosition != null ? scrubberPosition : dataLength - 1;
218
+ const chartAccessibilityLabel = "Candidate polling data over " + timeLabels.length + " months showing support percentages for 3 candidates.";
219
+ const ValueLegendEntry = useCallback(_ref => {
220
+ var _seriesData$data;
221
+ let {
222
+ seriesId,
223
+ label,
224
+ color,
225
+ shape
226
+ } = _ref;
227
+ const seriesData = seriesConfig.find(s => s.id === seriesId);
228
+ const rawValue = seriesData == null || (_seriesData$data = seriesData.data) == null ? void 0 : _seriesData$data[dataIndex];
229
+ const formattedValue = rawValue === null || rawValue === undefined ? '--' : Math.round(rawValue) + "%";
230
+ return /*#__PURE__*/_jsxs(HStack, {
231
+ gap: 1,
232
+ style: {
233
+ alignItems: 'center'
234
+ },
235
+ children: [/*#__PURE__*/_jsx(DefaultLegendShape, {
236
+ color: color,
237
+ shape: shape
238
+ }), /*#__PURE__*/_jsx(TextLabel2, {
239
+ children: label
240
+ }), /*#__PURE__*/_jsx(TextLabel1, {
241
+ children: formattedValue
242
+ })]
243
+ });
244
+ }, [seriesConfig, dataIndex]);
245
+ return /*#__PURE__*/_jsx(LineChart, {
246
+ enableScrubbing: true,
247
+ showArea: true,
248
+ accessibilityLabel: chartAccessibilityLabel,
249
+ height: 250,
250
+ legend: /*#__PURE__*/_jsx(Legend, {
251
+ EntryComponent: ValueLegendEntry,
252
+ justifyContent: "flex-start",
253
+ paddingX: 2
254
+ }),
255
+ legendPosition: "top",
256
+ onScrubberPositionChange: setScrubberPosition,
257
+ series: seriesConfig,
258
+ width: "100%",
259
+ xAxis: {
260
+ data: timeLabels
261
+ },
262
+ yAxis: {
263
+ domain: {
264
+ max: 100,
265
+ min: 0
266
+ },
267
+ showGrid: true,
268
+ tickLabelFormatter: value => value + "%"
269
+ },
270
+ children: /*#__PURE__*/_jsx(Scrubber, {})
271
+ });
272
+ };
273
+ const Interactive = () => {
274
+ const theme = useTheme();
275
+ const [emphasizedId, setEmphasizedId] = useState(null);
276
+ const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
277
+ const seriesConfig = useMemo(() => [{
278
+ id: 'revenue',
279
+ label: 'Revenue',
280
+ data: [120, 150, 180, 165, 190, 210, 240, 220, 260, 280, 310, 350],
281
+ baseColor: 'blue'
282
+ }, {
283
+ id: 'expenses',
284
+ label: 'Expenses',
285
+ data: [80, 95, 110, 105, 120, 130, 145, 140, 155, 165, 180, 195],
286
+ baseColor: 'orange'
287
+ }, {
288
+ id: 'profit',
289
+ label: 'Profit',
290
+ data: [40, 55, 70, 60, 70, 80, 95, 80, 105, 115, 130, 155],
291
+ baseColor: 'green'
292
+ }], []);
293
+ const handleToggle = useCallback(seriesId => {
294
+ setEmphasizedId(prev => prev === seriesId ? null : seriesId);
295
+ }, []);
296
+ const ChipLegendEntry = /*#__PURE__*/memo(function ChipLegendEntry(_ref2) {
297
+ var _config$baseColor;
298
+ let {
299
+ seriesId,
300
+ label
301
+ } = _ref2;
302
+ const isEmphasized = emphasizedId === seriesId;
303
+ const config = seriesConfig.find(s => s.id === seriesId);
304
+ const baseColor = (_config$baseColor = config == null ? void 0 : config.baseColor) != null ? _config$baseColor : 'gray';
305
+ const color10 = theme.spectrum[baseColor + "10"];
306
+ const color50 = theme.spectrum[baseColor + "50"];
307
+ const color90 = theme.spectrum[baseColor + "90"];
308
+ return /*#__PURE__*/_jsx(Chip, {
309
+ compact: true,
310
+ accessibilityLabel: (isEmphasized ? 'Remove emphasis from' : 'Emphasize') + " " + label + " series",
311
+ background: "transparent",
312
+ onPress: () => handleToggle(seriesId),
313
+ style: {
314
+ backgroundColor: "rgb(" + (isEmphasized ? color90 : color10) + ")",
315
+ borderWidth: 0,
316
+ borderRadius: theme.borderRadius[1000]
317
+ },
318
+ children: /*#__PURE__*/_jsxs(HStack, {
319
+ gap: 1,
320
+ style: {
321
+ alignItems: 'center'
322
+ },
323
+ children: [/*#__PURE__*/_jsx(DefaultLegendShape, {
324
+ color: "rgb(" + color50 + ")"
325
+ }), /*#__PURE__*/_jsx(TextLabel2, {
326
+ color: isEmphasized ? 'bg' : 'fg',
327
+ children: label
328
+ })]
329
+ })
330
+ });
331
+ });
332
+ const series = useMemo(() => {
333
+ return seriesConfig.map(config => {
334
+ const isEmphasized = emphasizedId === config.id;
335
+ const isDimmed = emphasizedId !== null && !isEmphasized;
336
+ return {
337
+ id: config.id,
338
+ label: config.label,
339
+ data: config.data,
340
+ color: "rgb(" + theme.spectrum[config.baseColor + "40"] + ")",
341
+ opacity: isDimmed ? 0.3 : 1
342
+ };
343
+ });
344
+ }, [emphasizedId, seriesConfig, theme]);
345
+ return /*#__PURE__*/_jsx(LineChart, {
346
+ showArea: true,
347
+ height: 300,
348
+ legend: /*#__PURE__*/_jsx(Legend, {
349
+ EntryComponent: ChipLegendEntry,
350
+ gap: 1,
351
+ paddingTop: 1
352
+ }),
353
+ legendPosition: "top",
354
+ series: series,
355
+ width: "100%",
356
+ xAxis: {
357
+ data: months
358
+ },
359
+ yAxis: {
360
+ domain: {
361
+ min: 0
362
+ },
363
+ showGrid: true,
364
+ tickLabelFormatter: value => "$" + value + "k"
365
+ }
366
+ });
367
+ };
368
+ const Accessible = () => {
369
+ const theme = useTheme();
370
+ const months = useMemo(() => ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'], []);
371
+ return /*#__PURE__*/_jsx(LineChart, {
372
+ legend: true,
373
+ showArea: true,
374
+ height: 200,
375
+ legendAccessibilityLabel: "Financial performance chart, legend",
376
+ legendPosition: "bottom",
377
+ series: [{
378
+ id: 'revenue',
379
+ label: 'Revenue',
380
+ data: [120, 150, 180, 165, 190, 210],
381
+ color: "rgb(" + theme.spectrum.green40 + ")"
382
+ }, {
383
+ id: 'expenses',
384
+ label: 'Expenses',
385
+ data: [80, 95, 110, 105, 120, 130],
386
+ color: "rgb(" + theme.spectrum.orange40 + ")"
387
+ }],
388
+ width: "100%",
389
+ xAxis: {
390
+ data: months
391
+ },
392
+ yAxis: {
393
+ domain: {
394
+ min: 0
395
+ },
396
+ showGrid: true
397
+ }
398
+ });
399
+ };
400
+ const LegendShapes = () => {
401
+ const theme = useTheme();
402
+ const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
403
+
404
+ // Actual revenue (first 9 months)
405
+ const actualRevenue = [320, 380, 420, 390, 450, 480, 520, 490, 540, null, null, null];
406
+
407
+ // Forecasted revenue (last 3 months)
408
+ const forecastRevenue = [null, null, null, null, null, null, null, null, null, 580, 620, 680];
409
+ const numberFormatter = useCallback(value => "$" + new Intl.NumberFormat('en-US', {
410
+ maximumFractionDigits: 0
411
+ }).format(value) + "k", []);
412
+
413
+ // Pattern settings for dotted fill
414
+ const patternSize = 4;
415
+ const dotSize = 1;
416
+
417
+ // Custom legend indicator that matches the dotted bar pattern
418
+ const DottedLegendIndicator = useMemo(() => {
419
+ // Create a small dotted pattern for the legend indicator
420
+ const indicatorSize = 10;
421
+ const legendPatternSize = patternSize / 2;
422
+ const legendDotSize = dotSize / 2;
423
+ const dottedPath = getDottedAreaPath({
424
+ x: 1,
425
+ y: 1,
426
+ width: indicatorSize - 2,
427
+ height: indicatorSize - 2
428
+ }, legendPatternSize, legendDotSize);
429
+ const skiaPath = Skia.Path.MakeFromSVGString(dottedPath);
430
+ // Create squircle path for clipping
431
+ const squirclePath = Skia.Path.Make();
432
+ squirclePath.addRRect(Skia.RRectXY(Skia.XYWHRect(1, 1, 8, 8), 2, 2));
433
+ return /*#__PURE__*/_jsxs(Canvas, {
434
+ style: {
435
+ width: indicatorSize,
436
+ height: indicatorSize
437
+ },
438
+ children: [/*#__PURE__*/_jsx(Group, {
439
+ clip: squirclePath,
440
+ children: skiaPath && /*#__PURE__*/_jsx(SkiaPath, {
441
+ color: theme.color.fgPositive,
442
+ path: skiaPath,
443
+ style: "fill"
444
+ })
445
+ }), /*#__PURE__*/_jsx(SkiaPath, {
446
+ color: theme.color.fgPositive,
447
+ path: squirclePath,
448
+ strokeWidth: 2,
449
+ style: "stroke"
450
+ })]
451
+ });
452
+ }, [theme.color.fgPositive]);
453
+
454
+ // Custom bar component that renders bars with dotted pattern fill
455
+ const DottedBarComponent = useMemo(() => {
456
+ return /*#__PURE__*/memo(function DottedBar(props) {
457
+ const {
458
+ x,
459
+ y,
460
+ width,
461
+ height,
462
+ fill,
463
+ d
464
+ } = props;
465
+
466
+ // Generate dotted path for this bar's bounds
467
+ const dottedPath = useMemo(() => {
468
+ return getDottedAreaPath({
469
+ x,
470
+ y,
471
+ width,
472
+ height
473
+ }, patternSize, dotSize);
474
+ }, [x, y, width, height]);
475
+
476
+ // Create Skia paths
477
+ const barClipPath = useMemo(() => {
478
+ var _Skia$Path$MakeFromSV;
479
+ return d ? (_Skia$Path$MakeFromSV = Skia.Path.MakeFromSVGString(d)) != null ? _Skia$Path$MakeFromSV : undefined : undefined;
480
+ }, [d]);
481
+ const dotsSkiaPath = useMemo(() => {
482
+ var _Skia$Path$MakeFromSV2;
483
+ return (_Skia$Path$MakeFromSV2 = Skia.Path.MakeFromSVGString(dottedPath)) != null ? _Skia$Path$MakeFromSV2 : undefined;
484
+ }, [dottedPath]);
485
+ return /*#__PURE__*/_jsxs(_Fragment, {
486
+ children: [/*#__PURE__*/_jsx(Group, {
487
+ clip: barClipPath,
488
+ children: dotsSkiaPath && /*#__PURE__*/_jsx(SkiaPath, {
489
+ color: fill,
490
+ path: dotsSkiaPath,
491
+ style: "fill"
492
+ })
493
+ }), /*#__PURE__*/_jsx(DefaultBar, _extends({}, props, {
494
+ fill: undefined,
495
+ stroke: fill,
496
+ strokeWidth: 2
497
+ }))]
498
+ });
499
+ });
500
+ }, []);
501
+ return /*#__PURE__*/_jsx(BarChart, {
502
+ legend: true,
503
+ showXAxis: true,
504
+ showYAxis: true,
505
+ height: 250,
506
+ inset: 0,
507
+ legendPosition: "top",
508
+ series: [{
509
+ id: 'actual',
510
+ label: 'Historical',
511
+ data: actualRevenue,
512
+ color: theme.color.fgPositive,
513
+ legendShape: 'squircle',
514
+ stackId: 'revenue'
515
+ }, {
516
+ id: 'forecast',
517
+ label: 'Forecasted',
518
+ data: forecastRevenue,
519
+ color: theme.color.fgPositive,
520
+ legendShape: DottedLegendIndicator,
521
+ stackId: 'revenue',
522
+ BarComponent: DottedBarComponent
523
+ }],
524
+ xAxis: {
525
+ data: months,
526
+ scaleType: 'band',
527
+ showLine: true,
528
+ showTickMarks: true
529
+ },
530
+ yAxis: {
531
+ domain: {
532
+ min: 0
533
+ },
534
+ showGrid: true,
535
+ showLine: true,
536
+ showTickMarks: true,
537
+ position: 'left',
538
+ tickLabelFormatter: numberFormatter,
539
+ width: 60
540
+ }
541
+ });
542
+ };
543
+ const LegendStories = () => {
544
+ return /*#__PURE__*/_jsx(ScrollView, {
545
+ children: /*#__PURE__*/_jsxs(ExampleScreen, {
546
+ children: [/*#__PURE__*/_jsx(Example, {
547
+ title: "Shapes",
548
+ children: /*#__PURE__*/_jsx(Shapes, {})
549
+ }), /*#__PURE__*/_jsx(Example, {
550
+ title: "Basic Legend",
551
+ children: /*#__PURE__*/_jsx(BasicLegend, {})
552
+ }), /*#__PURE__*/_jsx(Example, {
553
+ title: "Position",
554
+ children: /*#__PURE__*/_jsx(Position, {})
555
+ }), /*#__PURE__*/_jsx(Example, {
556
+ title: "Shape Variants",
557
+ children: /*#__PURE__*/_jsx(ShapeVariants, {})
558
+ }), /*#__PURE__*/_jsx(Example, {
559
+ title: "Dynamic Data",
560
+ children: /*#__PURE__*/_jsx(DynamicData, {})
561
+ }), /*#__PURE__*/_jsx(Example, {
562
+ title: "Interactive Legend",
563
+ children: /*#__PURE__*/_jsx(Interactive, {})
564
+ }), /*#__PURE__*/_jsx(Example, {
565
+ title: "Legend Shapes",
566
+ children: /*#__PURE__*/_jsx(LegendShapes, {})
567
+ }), /*#__PURE__*/_jsx(Example, {
568
+ title: "Accessible Legend",
569
+ children: /*#__PURE__*/_jsx(Accessible, {})
570
+ })]
571
+ })
572
+ });
573
+ };
574
+ export default LegendStories;
@@ -0,0 +1,3 @@
1
+ export * from './DefaultLegendEntry';
2
+ export * from './DefaultLegendShape';
3
+ export * from './Legend';
@@ -1,4 +1,4 @@
1
- const _excluded = ["fill", "stroke", "dashIntervals", "strokeCap", "strokeJoin", "strokeOpacity", "strokeWidth", "gradient", "yAxisId", "d", "animate", "transition"];
1
+ const _excluded = ["fill", "stroke", "dashIntervals", "strokeCap", "strokeJoin", "strokeOpacity", "strokeWidth", "gradient", "xAxisId", "yAxisId", "d", "animate", "transitions", "transition"];
2
2
  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); }
3
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
4
  import { memo } from 'react';
@@ -21,9 +21,11 @@ export const DottedLine = /*#__PURE__*/memo(_ref => {
21
21
  strokeOpacity = 1,
22
22
  strokeWidth = 2,
23
23
  gradient,
24
+ xAxisId,
24
25
  yAxisId,
25
26
  d,
26
27
  animate,
28
+ transitions,
27
29
  transition
28
30
  } = _ref,
29
31
  props = _objectWithoutPropertiesLoose(_ref, _excluded);
@@ -38,12 +40,14 @@ export const DottedLine = /*#__PURE__*/memo(_ref => {
38
40
  strokeJoin: strokeJoin,
39
41
  strokeOpacity: strokeOpacity,
40
42
  strokeWidth: strokeWidth,
41
- transition: transition
43
+ transition: transition,
44
+ transitions: transitions
42
45
  }, props, {
43
46
  children: [/*#__PURE__*/_jsx(DashPathEffect, {
44
47
  intervals: dashIntervals
45
48
  }), gradient && /*#__PURE__*/_jsx(Gradient, {
46
49
  gradient: gradient,
50
+ xAxisId: xAxisId,
47
51
  yAxisId: yAxisId
48
52
  })]
49
53
  }));