@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
@@ -2,6 +2,7 @@ function _extends() { return _extends = Object.assign ? Object.assign.bind() : f
2
2
  import { memo, useCallback, useMemo } from 'react';
3
3
  import { Example, ExampleScreen } from '@coinbase/cds-mobile/examples/ExampleScreen';
4
4
  import { useTheme } from '@coinbase/cds-mobile/hooks/useTheme';
5
+ import { BarPlot } from '../../bar';
5
6
  import { CartesianChart } from '../../CartesianChart';
6
7
  import { LineChart, SolidLine } from '../../line';
7
8
  import { Line } from '../../line/Line';
@@ -52,10 +53,14 @@ const Simple = () => {
52
53
  const pageViews = data.map(d => d.pv);
53
54
  const pageNames = data.map(d => d.name);
54
55
  const pageUniqueVisitors = data.map(d => d.uv);
56
+ const chartAccessibilityLabel = "Page views and unique visitors across " + pageNames.length + " pages. Swipe to navigate.";
57
+ const getScrubberAccessibilityLabel = useCallback(index => pageNames[index] + ": " + pageViews[index] + " views, " + pageUniqueVisitors[index] + " unique visitors", [pageNames, pageViews, pageUniqueVisitors]);
55
58
  return /*#__PURE__*/_jsx(LineChart, {
56
59
  enableScrubbing: true,
57
60
  showXAxis: true,
58
61
  showYAxis: true,
62
+ accessibilityLabel: chartAccessibilityLabel,
63
+ getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
59
64
  height: defaultChartHeight,
60
65
  inset: 32,
61
66
  series: [{
@@ -96,8 +101,8 @@ const Simple = () => {
96
101
  };
97
102
  const TimeOfDayAxesExample = () => {
98
103
  const theme = useTheme();
99
- const lineA = [5, 5, 10, 90, 85, 70, 30, 25, 25];
100
- const lineB = [90, 85, 70, 25, 23, 40, 45, 40, 50];
104
+ const lineA = useMemo(() => [5, 5, 10, 90, 85, 70, 30, 25, 25], []);
105
+ const lineB = useMemo(() => [90, 85, 70, 25, 23, 40, 45, 40, 50], []);
101
106
  const timeData = useMemo(() => [new Date(2023, 7, 31), new Date(2023, 7, 31, 12), new Date(2023, 8, 1), new Date(2023, 8, 1, 12), new Date(2023, 8, 2), new Date(2023, 8, 2, 12), new Date(2023, 8, 3), new Date(2023, 8, 3, 12), new Date(2023, 8, 4)].map(d => d.getTime()), []);
102
107
  const dateFormatter = useCallback(index => {
103
108
  return new Date(timeData[index]).toLocaleDateString('en-US', {
@@ -116,8 +121,12 @@ const TimeOfDayAxesExample = () => {
116
121
  const dateTicks = useMemo(() => {
117
122
  return timeData.map((d, index) => index).filter(d => d % 2 === 0);
118
123
  }, [timeData]);
124
+ const chartAccessibilityLabel = "Chart with " + lineA.length + " data points. Swipe to navigate.";
125
+ const getScrubberAccessibilityLabel = useCallback(index => "Point " + (index + 1) + ": lineA " + lineA[index] + ", lineB " + lineB[index], [lineA, lineB]);
119
126
  return /*#__PURE__*/_jsxs(LineChart, {
120
127
  enableScrubbing: true,
128
+ accessibilityLabel: chartAccessibilityLabel,
129
+ getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
121
130
  height: defaultChartHeight,
122
131
  series: [{
123
132
  id: 'lineA',
@@ -149,58 +158,166 @@ const TimeOfDayAxesExample = () => {
149
158
  }), /*#__PURE__*/_jsx(Scrubber, {})]
150
159
  });
151
160
  };
152
- const MultipleYAxesExample = () => /*#__PURE__*/_jsxs(CartesianChart, {
153
- enableScrubbing: true,
154
- height: defaultChartHeight,
155
- series: [{
156
- id: 'linear',
157
- yAxisId: 'linearAxis',
158
- data: [1, 10, 30, 50, 70, 90, 100],
159
- label: 'linear'
160
- }, {
161
- id: 'log',
162
- yAxisId: 'logAxis',
163
- data: [1, 10, 30, 50, 70, 90, 100],
164
- label: 'log'
165
- }],
166
- xAxis: {
167
- data: [1, 10, 30, 50, 70, 90, 100]
168
- },
169
- yAxis: [{
170
- id: 'linearAxis',
171
- scaleType: 'linear'
172
- }, {
173
- id: 'logAxis',
174
- scaleType: 'log'
175
- }],
176
- children: [/*#__PURE__*/_jsx(XAxis, {
177
- showLine: true,
178
- showTickMarks: true
179
- }), /*#__PURE__*/_jsx(YAxis, {
180
- showLine: true,
181
- showTickMarks: true,
182
- axisId: "logAxis",
183
- position: "left"
184
- }), /*#__PURE__*/_jsx(YAxis, {
185
- showLine: true,
186
- showTickMarks: true,
187
- axisId: "linearAxis",
188
- position: "left"
189
- }), /*#__PURE__*/_jsx(Line, {
190
- curve: "natural",
191
- seriesId: "linear"
192
- }), /*#__PURE__*/_jsx(Line, {
193
- curve: "natural",
194
- seriesId: "log"
195
- }), /*#__PURE__*/_jsx(Scrubber, {})]
196
- });
161
+ const multipleYAxesData = [1, 10, 30, 50, 70, 90, 100];
162
+ const MultipleYAxesExample = () => {
163
+ const getScrubberAccessibilityLabel = useCallback(index => "Point " + (index + 1) + ": linear " + multipleYAxesData[index] + ", log " + multipleYAxesData[index], []);
164
+ return /*#__PURE__*/_jsxs(CartesianChart, {
165
+ enableScrubbing: true,
166
+ accessibilityLabel: "Chart with linear and log axes. 7 data points. Swipe to navigate.",
167
+ getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
168
+ height: defaultChartHeight,
169
+ series: [{
170
+ id: 'linear',
171
+ yAxisId: 'linearAxis',
172
+ data: multipleYAxesData,
173
+ label: 'linear'
174
+ }, {
175
+ id: 'log',
176
+ yAxisId: 'logAxis',
177
+ data: multipleYAxesData,
178
+ label: 'log'
179
+ }],
180
+ xAxis: {
181
+ data: multipleYAxesData
182
+ },
183
+ yAxis: [{
184
+ id: 'linearAxis',
185
+ scaleType: 'linear'
186
+ }, {
187
+ id: 'logAxis',
188
+ scaleType: 'log'
189
+ }],
190
+ children: [/*#__PURE__*/_jsx(XAxis, {
191
+ showLine: true,
192
+ showTickMarks: true
193
+ }), /*#__PURE__*/_jsx(YAxis, {
194
+ showLine: true,
195
+ showTickMarks: true,
196
+ axisId: "logAxis",
197
+ position: "left"
198
+ }), /*#__PURE__*/_jsx(YAxis, {
199
+ showLine: true,
200
+ showTickMarks: true,
201
+ axisId: "linearAxis",
202
+ position: "left"
203
+ }), /*#__PURE__*/_jsx(Line, {
204
+ curve: "natural",
205
+ seriesId: "linear"
206
+ }), /*#__PURE__*/_jsx(Line, {
207
+ curve: "natural",
208
+ seriesId: "log"
209
+ }), /*#__PURE__*/_jsx(Scrubber, {})]
210
+ });
211
+ };
212
+ const AxesOnAllSides = () => {
213
+ const theme = useTheme();
214
+ const data = [30, 45, 60, 80, 55, 40, 65];
215
+ const labels = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
216
+ return /*#__PURE__*/_jsxs(CartesianChart, {
217
+ height: defaultChartHeight,
218
+ series: [{
219
+ id: 'data',
220
+ data,
221
+ color: theme.color.accentBoldBlue
222
+ }],
223
+ xAxis: {
224
+ data: labels
225
+ },
226
+ yAxis: {
227
+ domain: {
228
+ min: 0,
229
+ max: 100
230
+ }
231
+ },
232
+ children: [/*#__PURE__*/_jsx(XAxis, {
233
+ showLine: true,
234
+ showTickMarks: true,
235
+ label: "Bottom Axis",
236
+ position: "bottom",
237
+ ticks: labels.map((label, index) => index)
238
+ }), /*#__PURE__*/_jsx(XAxis, {
239
+ showLine: true,
240
+ showTickMarks: true,
241
+ label: "Top Axis",
242
+ position: "top",
243
+ ticks: labels.map((label, index) => index)
244
+ }), /*#__PURE__*/_jsx(YAxis, {
245
+ showLine: true,
246
+ showTickMarks: true,
247
+ label: "Left Axis",
248
+ position: "left"
249
+ }), /*#__PURE__*/_jsx(YAxis, {
250
+ showLine: true,
251
+ showTickMarks: true,
252
+ label: "Right Axis",
253
+ position: "right"
254
+ }), /*#__PURE__*/_jsx(Line, {
255
+ curve: "natural",
256
+ seriesId: "data"
257
+ })]
258
+ });
259
+ };
260
+ const CustomTickMarkSizes = () => {
261
+ const theme = useTheme();
262
+ const data = [25, 50, 75, 60, 45, 80, 35];
263
+ return /*#__PURE__*/_jsxs(CartesianChart, {
264
+ height: 300,
265
+ series: [{
266
+ id: 'data',
267
+ data,
268
+ color: theme.color.accentBoldGreen
269
+ }],
270
+ xAxis: {
271
+ data: ['A', 'B', 'C', 'D', 'E', 'F', 'G']
272
+ },
273
+ yAxis: {
274
+ domain: {
275
+ min: 0,
276
+ max: 100
277
+ }
278
+ },
279
+ children: [/*#__PURE__*/_jsx(XAxis, {
280
+ showLine: true,
281
+ showTickMarks: true,
282
+ label: "tickMarkSize=4 (default)",
283
+ tickMarkSize: 4
284
+ }), /*#__PURE__*/_jsx(XAxis, {
285
+ showLine: true,
286
+ showTickMarks: true,
287
+ height: 60,
288
+ label: "tickMarkSize=8",
289
+ position: "top",
290
+ tickMarkSize: 8
291
+ }), /*#__PURE__*/_jsx(YAxis, {
292
+ showLine: true,
293
+ showTickMarks: true,
294
+ label: "tickMarkSize=16",
295
+ position: "left",
296
+ tickMarkSize: 16,
297
+ width: 76
298
+ }), /*#__PURE__*/_jsx(YAxis, {
299
+ showLine: true,
300
+ showTickMarks: true,
301
+ label: "tickMarkSize=24",
302
+ position: "right",
303
+ tickMarkSize: 24,
304
+ width: 84
305
+ }), /*#__PURE__*/_jsx(Line, {
306
+ curve: "monotone",
307
+ seriesId: "data"
308
+ })]
309
+ });
310
+ };
197
311
  const DomainLimitType = _ref => {
198
312
  let {
199
313
  limit
200
314
  } = _ref;
201
- const exponentialData = [1, 2, 4, 8, 15, 30, 65, 140, 280, 580, 1200, 2400, 4800, 9500, 19000, 38000, 75000, 150000];
315
+ const exponentialData = useMemo(() => [1, 2, 4, 8, 15, 30, 65, 140, 280, 580, 1200, 2400, 4800, 9500, 19000, 38000, 75000, 150000], []);
316
+ const getScrubberAccessibilityLabel = useCallback(index => "Point " + (index + 1) + ": " + exponentialData[index], [exponentialData]);
202
317
  return /*#__PURE__*/_jsxs(CartesianChart, {
203
318
  enableScrubbing: true,
319
+ accessibilityLabel: "Exponential growth chart with " + exponentialData.length + " data points. Swipe to navigate.",
320
+ getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
204
321
  height: defaultChartHeight,
205
322
  series: [{
206
323
  id: 'growthLinear',
@@ -249,6 +366,97 @@ const DomainLimitType = _ref => {
249
366
  }), /*#__PURE__*/_jsx(Scrubber, {})]
250
367
  });
251
368
  };
369
+
370
+ // Band scale with tick filtering - show every other tick
371
+ const BandScaleTickFiltering = () => /*#__PURE__*/_jsxs(CartesianChart, {
372
+ height: defaultChartHeight,
373
+ inset: 8,
374
+ series: [{
375
+ id: 'data',
376
+ data: [10, 22, 29, 45, 98, 45, 22, 35, 42, 18, 55, 67]
377
+ }],
378
+ xAxis: {
379
+ scaleType: 'band',
380
+ data: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
381
+ },
382
+ yAxis: {
383
+ domain: {
384
+ min: 0
385
+ }
386
+ },
387
+ children: [/*#__PURE__*/_jsx(XAxis, {
388
+ showGrid: true,
389
+ showLine: true,
390
+ showTickMarks: true,
391
+ label: "ticks={(i) => i % 2 === 0}",
392
+ ticks: i => i % 2 === 0
393
+ }), /*#__PURE__*/_jsx(BarPlot, {})]
394
+ });
395
+
396
+ // Band scale with explicit ticks array
397
+ const BandScaleExplicitTicks = () => /*#__PURE__*/_jsxs(CartesianChart, {
398
+ height: defaultChartHeight,
399
+ inset: 8,
400
+ series: [{
401
+ id: 'data',
402
+ data: [10, 22, 29, 45, 98, 45, 22]
403
+ }],
404
+ xAxis: {
405
+ scaleType: 'band',
406
+ data: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
407
+ },
408
+ yAxis: {
409
+ domain: {
410
+ min: 0
411
+ }
412
+ },
413
+ children: [/*#__PURE__*/_jsx(XAxis, {
414
+ showGrid: true,
415
+ showLine: true,
416
+ showTickMarks: true,
417
+ label: "ticks={[0, 3, 6]} (first, middle, last)",
418
+ ticks: [0, 3, 6]
419
+ }), /*#__PURE__*/_jsx(BarPlot, {})]
420
+ });
421
+
422
+ // Line chart on band scale - comparing grid placements
423
+ const LineChartOnBandScale = _ref2 => {
424
+ let {
425
+ bandGridLinePlacement
426
+ } = _ref2;
427
+ const theme = useTheme();
428
+ return /*#__PURE__*/_jsxs(CartesianChart, {
429
+ height: 180,
430
+ inset: 8,
431
+ series: [{
432
+ id: 'line1',
433
+ data: [10, 22, 29, 45, 98, 45, 22],
434
+ color: theme.color.accentBoldBlue
435
+ }],
436
+ xAxis: {
437
+ scaleType: 'band',
438
+ data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
439
+ },
440
+ yAxis: {
441
+ domain: {
442
+ min: 0
443
+ }
444
+ },
445
+ children: [/*#__PURE__*/_jsx(XAxis, {
446
+ showGrid: true,
447
+ showLine: true,
448
+ showTickMarks: true,
449
+ bandGridLinePlacement: bandGridLinePlacement,
450
+ bandTickMarkPlacement: bandGridLinePlacement,
451
+ label: "bandGridLinePlacement: " + bandGridLinePlacement
452
+ }), /*#__PURE__*/_jsx(YAxis, {
453
+ showGrid: true,
454
+ position: "left"
455
+ }), /*#__PURE__*/_jsx(Line, {
456
+ seriesId: "line1"
457
+ })]
458
+ });
459
+ };
252
460
  const AxisStories = () => {
253
461
  return /*#__PURE__*/_jsxs(ExampleScreen, {
254
462
  children: [/*#__PURE__*/_jsx(Example, {
@@ -270,6 +478,74 @@ const AxisStories = () => {
270
478
  children: /*#__PURE__*/_jsx(DomainLimitType, {
271
479
  limit: "nice"
272
480
  })
481
+ }), /*#__PURE__*/_jsx(Example, {
482
+ title: "Band Axis Grid Alignment",
483
+ children: /*#__PURE__*/_jsxs(CartesianChart, {
484
+ height: 350,
485
+ inset: 8,
486
+ series: [{
487
+ id: 'prices',
488
+ data: [10, 22, 29, 45, 98, 45, 22]
489
+ }],
490
+ xAxis: {
491
+ scaleType: 'band',
492
+ data: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
493
+ },
494
+ yAxis: {
495
+ domain: {
496
+ min: 0
497
+ }
498
+ },
499
+ children: [/*#__PURE__*/_jsx(XAxis, {
500
+ showGrid: true,
501
+ showLine: true,
502
+ showTickMarks: true,
503
+ label: "Default"
504
+ }), /*#__PURE__*/_jsx(XAxis, {
505
+ showLine: true,
506
+ showTickMarks: true,
507
+ bandTickMarkPlacement: "start",
508
+ label: "Start"
509
+ }), /*#__PURE__*/_jsx(XAxis, {
510
+ showLine: true,
511
+ showTickMarks: true,
512
+ bandTickMarkPlacement: "end",
513
+ label: "End"
514
+ }), /*#__PURE__*/_jsx(XAxis, {
515
+ showLine: true,
516
+ showTickMarks: true,
517
+ bandTickMarkPlacement: "middle",
518
+ label: "Middle"
519
+ }), /*#__PURE__*/_jsx(XAxis, {
520
+ showLine: true,
521
+ showTickMarks: true,
522
+ bandTickMarkPlacement: "edges",
523
+ label: "Edges"
524
+ }), /*#__PURE__*/_jsx(BarPlot, {})]
525
+ })
526
+ }), /*#__PURE__*/_jsx(Example, {
527
+ title: "Band Scale - Tick Filtering",
528
+ children: /*#__PURE__*/_jsx(BandScaleTickFiltering, {})
529
+ }), /*#__PURE__*/_jsx(Example, {
530
+ title: "Band Scale - Explicit Ticks",
531
+ children: /*#__PURE__*/_jsx(BandScaleExplicitTicks, {})
532
+ }), /*#__PURE__*/_jsxs(Example, {
533
+ title: "Line Chart on Band Scale - Grid Positions",
534
+ children: [/*#__PURE__*/_jsx(LineChartOnBandScale, {
535
+ bandGridLinePlacement: "edges"
536
+ }), /*#__PURE__*/_jsx(LineChartOnBandScale, {
537
+ bandGridLinePlacement: "start"
538
+ }), /*#__PURE__*/_jsx(LineChartOnBandScale, {
539
+ bandGridLinePlacement: "middle"
540
+ }), /*#__PURE__*/_jsx(LineChartOnBandScale, {
541
+ bandGridLinePlacement: "end"
542
+ })]
543
+ }), /*#__PURE__*/_jsx(Example, {
544
+ title: "Axes on All Sides",
545
+ children: /*#__PURE__*/_jsx(AxesOnAllSides, {})
546
+ }), /*#__PURE__*/_jsx(Example, {
547
+ title: "Custom Tick Mark Sizes",
548
+ children: /*#__PURE__*/_jsx(CustomTickMarkSizes, {})
273
549
  })]
274
550
  });
275
551
  };
@@ -1,5 +1,6 @@
1
1
  import React, { memo, useMemo } from 'react';
2
2
  import { useTheme } from '@coinbase/cds-mobile/hooks/useTheme';
3
+ import { useCartesianChartContext } from '../ChartProvider';
3
4
  import { getBarPath } from '../utils';
4
5
  import { DefaultBar } from './DefaultBar';
5
6
  import { jsx as _jsx } from "react/jsx-runtime";
@@ -21,9 +22,10 @@ export const Bar = /*#__PURE__*/memo(_ref => {
21
22
  y,
22
23
  width,
23
24
  height,
24
- originY,
25
+ origin: originProp,
25
26
  dataX,
26
27
  dataY,
28
+ seriesId,
27
29
  BarComponent = DefaultBar,
28
30
  fill,
29
31
  fillOpacity = 1,
@@ -32,36 +34,36 @@ export const Bar = /*#__PURE__*/memo(_ref => {
32
34
  borderRadius = 4,
33
35
  roundTop = true,
34
36
  roundBottom = true,
37
+ minSize,
38
+ transitions,
35
39
  transition
36
40
  } = _ref;
37
41
  const theme = useTheme();
38
-
39
- // Use theme color as default if no fill is provided
40
- const effectiveFill = fill != null ? fill : theme.color.fgPrimary;
41
- const borderRadiusPixels = useMemo(() => borderRadius != null ? borderRadius : 0, [borderRadius]);
42
+ const {
43
+ layout
44
+ } = useCartesianChartContext();
42
45
  const barPath = useMemo(() => {
43
- return getBarPath(x, y, width, height, borderRadiusPixels, roundTop, roundBottom);
44
- }, [x, y, width, height, borderRadiusPixels, roundTop, roundBottom]);
45
- const effectiveOriginY = originY != null ? originY : y + height;
46
- if (!barPath) {
47
- return null;
48
- }
49
-
50
- // Always use the BarComponent for rendering
46
+ return getBarPath(x, y, width, height, borderRadius, roundTop, roundBottom, layout);
47
+ }, [x, y, width, height, borderRadius, roundTop, roundBottom, layout]);
48
+ const origin = useMemo(() => originProp != null ? originProp : layout === 'horizontal' ? x : y + height, [originProp, layout, x, y, height]);
49
+ if (!barPath) return;
51
50
  return /*#__PURE__*/_jsx(BarComponent, {
52
51
  borderRadius: borderRadius,
53
52
  d: barPath,
54
53
  dataX: dataX,
55
54
  dataY: dataY,
56
- fill: effectiveFill,
55
+ fill: fill != null ? fill : theme.color.fgPrimary,
57
56
  fillOpacity: fillOpacity,
58
57
  height: height,
59
- originY: effectiveOriginY,
58
+ minSize: minSize,
59
+ origin: origin,
60
60
  roundBottom: roundBottom,
61
61
  roundTop: roundTop,
62
+ seriesId: seriesId,
62
63
  stroke: stroke,
63
64
  strokeWidth: strokeWidth,
64
65
  transition: transition,
66
+ transitions: transitions,
65
67
  width: width,
66
68
  x: x,
67
69
  y: y
@@ -1,17 +1,17 @@
1
- const _excluded = ["series", "stacked", "showXAxis", "showYAxis", "xAxis", "yAxis", "inset", "children", "barPadding", "BarComponent", "fillOpacity", "stroke", "strokeWidth", "borderRadius", "roundBaseline", "BarStackComponent", "stackGap", "barMinSize", "stackMinSize", "transition"],
2
- _excluded2 = ["scaleType", "data", "categoryPadding", "domain", "domainLimit", "range"],
1
+ const _excluded = ["series", "stacked", "showXAxis", "showYAxis", "xAxis", "yAxis", "inset", "children", "barPadding", "BarComponent", "fillOpacity", "stroke", "strokeWidth", "borderRadius", "roundBaseline", "BarStackComponent", "stackGap", "barMinSize", "stackMinSize", "transitions", "transition"],
2
+ _excluded2 = ["scaleType", "data", "categoryPadding", "domain", "domainLimit", "range", "id"],
3
3
  _excluded3 = ["scaleType", "data", "categoryPadding", "domain", "domainLimit", "range", "id"];
4
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
5
  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; }
6
6
  import { forwardRef, memo, useMemo } from 'react';
7
7
  import { XAxis, YAxis } from '../axis';
8
8
  import { CartesianChart } from '../CartesianChart';
9
- import { defaultChartInset, defaultStackId, getChartInset } from '../utils';
9
+ import { defaultStackId } from '../utils';
10
10
  import { BarPlot } from './BarPlot';
11
11
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
12
12
  export const BarChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) => {
13
13
  let {
14
- series,
14
+ series: seriesProp,
15
15
  stacked,
16
16
  showXAxis,
17
17
  showYAxis,
@@ -30,24 +30,23 @@ export const BarChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) =>
30
30
  stackGap,
31
31
  barMinSize,
32
32
  stackMinSize,
33
+ transitions,
33
34
  transition
34
35
  } = _ref,
35
36
  chartProps = _objectWithoutPropertiesLoose(_ref, _excluded);
36
- const calculatedInset = useMemo(() => getChartInset(inset, defaultChartInset), [inset]);
37
- const transformedSeries = useMemo(() => {
38
- if (!stacked || !series) return series;
39
- return series.map(s => {
37
+ const series = useMemo(() => {
38
+ if (!stacked || !seriesProp) return seriesProp;
39
+ return seriesProp.map(s => {
40
40
  var _s$stackId;
41
41
  return _extends({}, s, {
42
42
  stackId: (_s$stackId = s.stackId) != null ? _s$stackId : defaultStackId
43
43
  });
44
44
  });
45
- }, [series, stacked]);
46
-
47
- // Unlike other charts with custom props per series, we do not need to pick out
48
- // the props from each series that shouldn't be passed to CartesianChart
49
- const seriesToRender = transformedSeries != null ? transformedSeries : series;
50
- const seriesIds = seriesToRender == null ? void 0 : seriesToRender.map(s => s.id);
45
+ }, [seriesProp, stacked]);
46
+ const seriesIds = useMemo(() => series == null ? void 0 : series.map(s => s.id), [series]);
47
+ const isHorizontalLayout = chartProps.layout === 'horizontal';
48
+ const defaultXScaleType = isHorizontalLayout ? 'linear' : 'band';
49
+ const defaultYScaleType = isHorizontalLayout ? 'band' : 'linear';
51
50
 
52
51
  // Split axis props into config props for Chart and visual props for axis components
53
52
  const _ref2 = xAxis || {},
@@ -57,7 +56,8 @@ export const BarChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) =>
57
56
  categoryPadding: xCategoryPadding,
58
57
  domain: xDomain,
59
58
  domainLimit: xDomainLimit,
60
- range: xRange
59
+ range: xRange,
60
+ id: xAxisId
61
61
  } = _ref2,
62
62
  xAxisVisualProps = _objectWithoutPropertiesLoose(_ref2, _excluded2);
63
63
  const _ref3 = yAxis || {},
@@ -71,14 +71,6 @@ export const BarChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) =>
71
71
  id: yAxisId
72
72
  } = _ref3,
73
73
  yAxisVisualProps = _objectWithoutPropertiesLoose(_ref3, _excluded3);
74
- const xAxisConfig = {
75
- scaleType: xScaleType != null ? xScaleType : 'band',
76
- data: xData,
77
- categoryPadding: xCategoryPadding,
78
- domain: xDomain,
79
- domainLimit: xDomainLimit,
80
- range: xRange
81
- };
82
74
  const hasNegativeValues = useMemo(() => {
83
75
  if (!series) return false;
84
76
  return series.some(s => {
@@ -86,25 +78,37 @@ export const BarChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) =>
86
78
  return (_s$data = s.data) == null ? void 0 : _s$data.some(value => typeof value === 'number' && value < 0 || Array.isArray(value) && value.some(v => typeof v === 'number' && v < 0));
87
79
  });
88
80
  }, [series]);
81
+ const xAxisConfig = useMemo(() => ({
82
+ scaleType: xScaleType != null ? xScaleType : defaultXScaleType,
83
+ data: xData,
84
+ categoryPadding: xCategoryPadding,
85
+ domain: isHorizontalLayout && !hasNegativeValues ? _extends({
86
+ min: 0
87
+ }, xDomain) : xDomain,
88
+ domainLimit: xDomainLimit,
89
+ range: xRange
90
+ }), [xScaleType, defaultXScaleType, xData, xCategoryPadding, isHorizontalLayout, hasNegativeValues, xDomain, xDomainLimit, xRange]);
89
91
 
90
- // Set default min domain to 0 for area chart, but only if there are no negative values
91
- const yAxisConfig = {
92
- scaleType: yScaleType,
92
+ // Set default min domain to 0 for bar chart, but only if there are no negative values.
93
+ const yAxisConfig = useMemo(() => ({
94
+ scaleType: yScaleType != null ? yScaleType : defaultYScaleType,
93
95
  data: yData,
94
96
  categoryPadding: yCategoryPadding,
95
- domain: hasNegativeValues ? yDomain : _extends({
97
+ domain: !isHorizontalLayout && !hasNegativeValues ? _extends({
96
98
  min: 0
97
- }, yDomain),
99
+ }, yDomain) : yDomain,
98
100
  domainLimit: yDomainLimit,
99
101
  range: yRange
100
- };
102
+ }), [yScaleType, defaultYScaleType, yData, yCategoryPadding, isHorizontalLayout, hasNegativeValues, yDomain, yDomainLimit, yRange]);
101
103
  return /*#__PURE__*/_jsxs(CartesianChart, _extends({}, chartProps, {
102
104
  ref: ref,
103
- inset: calculatedInset,
104
- series: seriesToRender,
105
+ inset: inset,
106
+ series: series,
105
107
  xAxis: xAxisConfig,
106
108
  yAxis: yAxisConfig,
107
- children: [showXAxis && /*#__PURE__*/_jsx(XAxis, _extends({}, xAxisVisualProps)), showYAxis && /*#__PURE__*/_jsx(YAxis, _extends({
109
+ children: [showXAxis && /*#__PURE__*/_jsx(XAxis, _extends({
110
+ axisId: xAxisId
111
+ }, xAxisVisualProps)), showYAxis && /*#__PURE__*/_jsx(YAxis, _extends({
108
112
  axisId: yAxisId
109
113
  }, yAxisVisualProps)), /*#__PURE__*/_jsx(BarPlot, {
110
114
  BarComponent: BarComponent,
@@ -119,7 +123,8 @@ export const BarChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) =>
119
123
  stackMinSize: stackMinSize,
120
124
  stroke: stroke,
121
125
  strokeWidth: strokeWidth,
122
- transition: transition
126
+ transition: transition,
127
+ transitions: transitions
123
128
  }), children]
124
129
  }));
125
130
  }));