@coinbase/cds-mobile-visualization 3.4.0-beta.22 → 3.4.0-beta.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dts/chart/CartesianChart.d.ts +58 -7
  3. package/dts/chart/CartesianChart.d.ts.map +1 -1
  4. package/dts/chart/Path.d.ts.map +1 -1
  5. package/dts/chart/area/Area.d.ts +7 -0
  6. package/dts/chart/area/Area.d.ts.map +1 -1
  7. package/dts/chart/area/AreaChart.d.ts +5 -5
  8. package/dts/chart/area/AreaChart.d.ts.map +1 -1
  9. package/dts/chart/area/DottedArea.d.ts.map +1 -1
  10. package/dts/chart/area/GradientArea.d.ts.map +1 -1
  11. package/dts/chart/area/SolidArea.d.ts.map +1 -1
  12. package/dts/chart/axis/Axis.d.ts +3 -1
  13. package/dts/chart/axis/Axis.d.ts.map +1 -1
  14. package/dts/chart/axis/XAxis.d.ts +6 -0
  15. package/dts/chart/axis/XAxis.d.ts.map +1 -1
  16. package/dts/chart/axis/YAxis.d.ts +1 -0
  17. package/dts/chart/axis/YAxis.d.ts.map +1 -1
  18. package/dts/chart/bar/Bar.d.ts +4 -2
  19. package/dts/chart/bar/Bar.d.ts.map +1 -1
  20. package/dts/chart/bar/BarChart.d.ts +49 -9
  21. package/dts/chart/bar/BarChart.d.ts.map +1 -1
  22. package/dts/chart/bar/BarPlot.d.ts.map +1 -1
  23. package/dts/chart/bar/BarStack.d.ts +30 -9
  24. package/dts/chart/bar/BarStack.d.ts.map +1 -1
  25. package/dts/chart/bar/BarStackGroup.d.ts +1 -1
  26. package/dts/chart/bar/BarStackGroup.d.ts.map +1 -1
  27. package/dts/chart/bar/DefaultBar.d.ts.map +1 -1
  28. package/dts/chart/bar/DefaultBarStack.d.ts.map +1 -1
  29. package/dts/chart/gradient/Gradient.d.ts +5 -0
  30. package/dts/chart/gradient/Gradient.d.ts.map +1 -1
  31. package/dts/chart/line/DottedLine.d.ts.map +1 -1
  32. package/dts/chart/line/Line.d.ts +7 -0
  33. package/dts/chart/line/Line.d.ts.map +1 -1
  34. package/dts/chart/line/LineChart.d.ts +22 -8
  35. package/dts/chart/line/LineChart.d.ts.map +1 -1
  36. package/dts/chart/line/ReferenceLine.d.ts +1 -0
  37. package/dts/chart/line/ReferenceLine.d.ts.map +1 -1
  38. package/dts/chart/line/SolidLine.d.ts.map +1 -1
  39. package/dts/chart/point/Point.d.ts +7 -0
  40. package/dts/chart/point/Point.d.ts.map +1 -1
  41. package/dts/chart/scrubber/DefaultScrubberBeacon.d.ts.map +1 -1
  42. package/dts/chart/scrubber/DefaultScrubberLabel.d.ts +2 -1
  43. package/dts/chart/scrubber/DefaultScrubberLabel.d.ts.map +1 -1
  44. package/dts/chart/scrubber/Scrubber.d.ts +8 -0
  45. package/dts/chart/scrubber/Scrubber.d.ts.map +1 -1
  46. package/dts/chart/scrubber/ScrubberAccessibilityView.d.ts +12 -0
  47. package/dts/chart/scrubber/ScrubberAccessibilityView.d.ts.map +1 -0
  48. package/dts/chart/scrubber/ScrubberBeaconGroup.d.ts.map +1 -1
  49. package/dts/chart/scrubber/ScrubberProvider.d.ts.map +1 -1
  50. package/dts/chart/utils/axis.d.ts +20 -9
  51. package/dts/chart/utils/axis.d.ts.map +1 -1
  52. package/dts/chart/utils/bar.d.ts +4 -3
  53. package/dts/chart/utils/bar.d.ts.map +1 -1
  54. package/dts/chart/utils/chart.d.ts +13 -0
  55. package/dts/chart/utils/chart.d.ts.map +1 -1
  56. package/dts/chart/utils/context.d.ts +21 -6
  57. package/dts/chart/utils/context.d.ts.map +1 -1
  58. package/dts/chart/utils/gradient.d.ts +3 -1
  59. package/dts/chart/utils/gradient.d.ts.map +1 -1
  60. package/dts/chart/utils/path.d.ts +20 -0
  61. package/dts/chart/utils/path.d.ts.map +1 -1
  62. package/dts/chart/utils/point.d.ts +7 -0
  63. package/dts/chart/utils/point.d.ts.map +1 -1
  64. package/esm/chart/CartesianChart.js +145 -81
  65. package/esm/chart/Path.js +10 -7
  66. package/esm/chart/__stories__/CartesianChart.stories.js +10 -0
  67. package/esm/chart/__stories__/ChartAccessibility.stories.js +721 -0
  68. package/esm/chart/area/Area.js +19 -9
  69. package/esm/chart/area/AreaChart.js +11 -9
  70. package/esm/chart/area/DottedArea.js +11 -6
  71. package/esm/chart/area/GradientArea.js +11 -6
  72. package/esm/chart/area/SolidArea.js +3 -1
  73. package/esm/chart/area/__stories__/AreaChart.stories.js +47 -5
  74. package/esm/chart/axis/XAxis.js +14 -21
  75. package/esm/chart/axis/YAxis.js +4 -3
  76. package/esm/chart/axis/__stories__/Axis.stories.js +65 -48
  77. package/esm/chart/bar/Bar.js +9 -5
  78. package/esm/chart/bar/BarChart.js +34 -31
  79. package/esm/chart/bar/BarPlot.js +7 -5
  80. package/esm/chart/bar/BarStack.js +176 -36
  81. package/esm/chart/bar/BarStackGroup.js +37 -27
  82. package/esm/chart/bar/DefaultBar.js +24 -8
  83. package/esm/chart/bar/DefaultBarStack.js +24 -10
  84. package/esm/chart/bar/__stories__/BarChart.stories.js +105 -3
  85. package/esm/chart/gradient/Gradient.js +2 -1
  86. package/esm/chart/line/DottedLine.js +3 -1
  87. package/esm/chart/line/Line.js +32 -19
  88. package/esm/chart/line/LineChart.js +31 -9
  89. package/esm/chart/line/SolidLine.js +3 -1
  90. package/esm/chart/line/__stories__/LineChart.stories.js +115 -46
  91. package/esm/chart/point/Point.js +2 -1
  92. package/esm/chart/scrubber/DefaultScrubberBeacon.js +1 -1
  93. package/esm/chart/scrubber/DefaultScrubberLabel.js +26 -10
  94. package/esm/chart/scrubber/Scrubber.js +47 -21
  95. package/esm/chart/scrubber/ScrubberAccessibilityView.js +177 -0
  96. package/esm/chart/scrubber/ScrubberBeaconGroup.js +24 -20
  97. package/esm/chart/scrubber/ScrubberProvider.js +29 -24
  98. package/esm/chart/scrubber/__stories__/Scrubber.stories.js +192 -6
  99. package/esm/chart/utils/axis.js +42 -14
  100. package/esm/chart/utils/bar.js +5 -4
  101. package/esm/chart/utils/chart.js +18 -5
  102. package/esm/chart/utils/context.js +7 -0
  103. package/esm/chart/utils/gradient.js +8 -4
  104. package/esm/chart/utils/path.js +90 -61
  105. package/esm/chart/utils/point.js +28 -18
  106. package/package.json +5 -5
@@ -21,33 +21,42 @@ export const Area = /*#__PURE__*/memo(_ref => {
21
21
  animate
22
22
  } = _ref;
23
23
  const {
24
+ layout,
24
25
  getSeries,
25
26
  getSeriesData,
26
27
  getXScale,
27
28
  getYScale,
28
- getXAxis
29
+ getXAxis,
30
+ getYAxis
29
31
  } = useCartesianChartContext();
30
32
  const matchedSeries = useMemo(() => getSeries(seriesId), [seriesId, getSeries]);
31
33
  const gradient = useMemo(() => gradientProp != null ? gradientProp : matchedSeries == null ? void 0 : matchedSeries.gradient, [gradientProp, matchedSeries == null ? void 0 : matchedSeries.gradient]);
32
34
  const fill = useMemo(() => fillProp != null ? fillProp : matchedSeries == null ? void 0 : matchedSeries.color, [fillProp, matchedSeries == null ? void 0 : matchedSeries.color]);
33
35
  const sourceData = useMemo(() => getSeriesData(seriesId), [seriesId, getSeriesData]);
34
- const xAxis = getXAxis();
35
- const xScale = getXScale();
36
+ const xAxis = getXAxis(matchedSeries == null ? void 0 : matchedSeries.xAxisId);
37
+ const xScale = getXScale(matchedSeries == null ? void 0 : matchedSeries.xAxisId);
36
38
  const yScale = getYScale(matchedSeries == null ? void 0 : matchedSeries.yAxisId);
39
+ const yAxis = getYAxis(matchedSeries == null ? void 0 : matchedSeries.yAxisId);
40
+ const categoryAxisIsX = useMemo(() => {
41
+ return layout !== 'horizontal';
42
+ }, [layout]);
43
+ const categoryAxis = useMemo(() => {
44
+ return categoryAxisIsX ? xAxis : yAxis;
45
+ }, [categoryAxisIsX, xAxis, yAxis]);
37
46
  const area = useMemo(() => {
38
47
  if (!sourceData || sourceData.length === 0 || !xScale || !yScale) return '';
39
-
40
- // Get numeric x-axis data if available
41
- const xData = xAxis != null && xAxis.data && Array.isArray(xAxis.data) && typeof xAxis.data[0] === 'number' ? xAxis.data : undefined;
48
+ const indexData = categoryAxis != null && categoryAxis.data && Array.isArray(categoryAxis.data) && typeof categoryAxis.data[0] === 'number' ? categoryAxis.data : undefined;
42
49
  return getAreaPath({
43
50
  data: sourceData,
44
51
  xScale,
45
52
  yScale,
46
53
  curve,
47
- xData,
48
- connectNulls
54
+ xData: categoryAxisIsX ? indexData : undefined,
55
+ yData: !categoryAxisIsX ? indexData : undefined,
56
+ connectNulls,
57
+ layout
49
58
  });
50
- }, [sourceData, xScale, yScale, curve, xAxis == null ? void 0 : xAxis.data, connectNulls]);
59
+ }, [sourceData, xScale, yScale, curve, categoryAxis, categoryAxisIsX, connectNulls, layout]);
51
60
  const AreaComponent = useMemo(() => {
52
61
  if (AreaComponentProp) {
53
62
  return AreaComponentProp;
@@ -72,6 +81,7 @@ export const Area = /*#__PURE__*/memo(_ref => {
72
81
  gradient: gradient,
73
82
  transition: transition,
74
83
  transitions: transitions,
84
+ xAxisId: matchedSeries == null ? void 0 : matchedSeries.xAxisId,
75
85
  yAxisId: matchedSeries == null ? void 0 : matchedSeries.yAxisId
76
86
  });
77
87
  });
@@ -1,15 +1,15 @@
1
1
  const _excluded = ["series", "stacked", "AreaComponent", "curve", "fillOpacity", "type", "connectNulls", "transition", "transitions", "LineComponent", "strokeWidth", "showXAxis", "showYAxis", "showLines", "lineType", "xAxis", "yAxis", "inset", "children"],
2
- _excluded2 = ["scaleType", "data", "categoryPadding", "domain", "domainLimit", "range"],
2
+ _excluded2 = ["scaleType", "data", "categoryPadding", "domain", "domainLimit", "range", "id"],
3
3
  _excluded3 = ["scaleType", "data", "categoryPadding", "domain", "domainLimit", "range", "id"],
4
- _excluded4 = ["id", "data", "label", "color", "yAxisId", "opacity", "LineComponent", "stackId"],
5
- _excluded5 = ["id", "data", "label", "color", "yAxisId", "fill", "fillOpacity", "stackId", "type"];
4
+ _excluded4 = ["id", "data", "label", "color", "xAxisId", "yAxisId", "opacity", "LineComponent", "stackId"],
5
+ _excluded5 = ["id", "data", "label", "color", "xAxisId", "yAxisId", "fill", "fillOpacity", "stackId", "type"];
6
6
  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); }
7
7
  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; }
8
8
  import { forwardRef, memo, useMemo } from 'react';
9
9
  import { XAxis, YAxis } from '../axis';
10
10
  import { CartesianChart } from '../CartesianChart';
11
11
  import { Line } from '../line/Line';
12
- import { defaultChartInset, defaultStackId, getChartInset } from '../utils';
12
+ import { defaultStackId } from '../utils';
13
13
  import { Area } from './Area';
14
14
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
15
15
  export const AreaChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) => {
@@ -35,8 +35,6 @@ export const AreaChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) =
35
35
  children
36
36
  } = _ref,
37
37
  chartProps = _objectWithoutPropertiesLoose(_ref, _excluded);
38
- const calculatedInset = useMemo(() => getChartInset(inset, defaultChartInset), [inset]);
39
-
40
38
  // Convert AreaSeries to Series for Chart context
41
39
  const chartSeries = useMemo(() => {
42
40
  return series == null ? void 0 : series.map(s => ({
@@ -45,6 +43,7 @@ export const AreaChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) =
45
43
  label: s.label,
46
44
  color: s.color,
47
45
  gradient: s.gradient,
46
+ xAxisId: s.xAxisId,
48
47
  yAxisId: s.yAxisId,
49
48
  stackId: s.stackId
50
49
  }));
@@ -68,7 +67,8 @@ export const AreaChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) =
68
67
  categoryPadding: xCategoryPadding,
69
68
  domain: xDomain,
70
69
  domainLimit: xDomainLimit,
71
- range: xRange
70
+ range: xRange,
71
+ id: xAxisId
72
72
  } = _ref2,
73
73
  xAxisVisualProps = _objectWithoutPropertiesLoose(_ref2, _excluded2);
74
74
  const _ref3 = yAxis || {},
@@ -111,11 +111,13 @@ export const AreaChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) =
111
111
  };
112
112
  return /*#__PURE__*/_jsxs(CartesianChart, _extends({}, chartProps, {
113
113
  ref: ref,
114
- inset: calculatedInset,
114
+ inset: inset,
115
115
  series: seriesToRender,
116
116
  xAxis: xAxisConfig,
117
117
  yAxis: yAxisConfig,
118
- children: [showXAxis && /*#__PURE__*/_jsx(XAxis, _extends({}, xAxisVisualProps)), showYAxis && /*#__PURE__*/_jsx(YAxis, _extends({
118
+ children: [showXAxis && /*#__PURE__*/_jsx(XAxis, _extends({
119
+ axisId: xAxisId
120
+ }, xAxisVisualProps)), showYAxis && /*#__PURE__*/_jsx(YAxis, _extends({
119
121
  axisId: yAxisId
120
122
  }, yAxisVisualProps)), series == null ? void 0 : series.map(_ref4 => {
121
123
  let {
@@ -1,4 +1,4 @@
1
- const _excluded = ["d", "fill", "patternSize", "dotSize", "peakOpacity", "baselineOpacity", "baseline", "yAxisId", "gradient", "animate", "transitions", "transition"];
1
+ const _excluded = ["d", "fill", "patternSize", "dotSize", "peakOpacity", "baselineOpacity", "baseline", "xAxisId", "yAxisId", "gradient", "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, useMemo } from 'react';
@@ -25,6 +25,7 @@ export const DottedArea = /*#__PURE__*/memo(_ref => {
25
25
  peakOpacity = 1,
26
26
  baselineOpacity = 0,
27
27
  baseline,
28
+ xAxisId,
28
29
  yAxisId,
29
30
  gradient: gradientProp,
30
31
  animate: animateProp,
@@ -36,10 +37,13 @@ export const DottedArea = /*#__PURE__*/memo(_ref => {
36
37
  const {
37
38
  drawingArea,
38
39
  animate,
40
+ layout,
41
+ getXAxis,
39
42
  getYAxis
40
43
  } = useCartesianChartContext();
41
44
  const shouldAnimate = animateProp != null ? animateProp : animate;
42
- const yAxisConfig = getYAxis(yAxisId);
45
+ const valueAxisConfig = layout !== 'horizontal' ? getYAxis(yAxisId) : getXAxis(xAxisId);
46
+ const gradientAxis = layout !== 'horizontal' ? 'y' : 'x';
43
47
  const fill = useMemo(() => fillProp != null ? fillProp : theme.color.fgPrimary, [fillProp, theme.color.fgPrimary]);
44
48
  const updateTransition = useMemo(() => {
45
49
  return (transitions == null ? void 0 : transitions.update) !== undefined ? transitions.update : transition !== undefined ? transition : defaultTransition;
@@ -61,10 +65,10 @@ export const DottedArea = /*#__PURE__*/memo(_ref => {
61
65
  });
62
66
  const gradient = useMemo(() => {
63
67
  if (gradientProp) return gradientProp;
64
- if (!yAxisConfig) return;
65
- const baselineValue = getBaseline(yAxisConfig.domain, baseline);
66
- return createGradient(yAxisConfig.domain, baselineValue, fill, peakOpacity, baselineOpacity);
67
- }, [gradientProp, yAxisConfig, fill, baseline, peakOpacity, baselineOpacity]);
68
+ if (!valueAxisConfig) return;
69
+ const baselineValue = getBaseline(valueAxisConfig.domain, baseline);
70
+ return createGradient(valueAxisConfig.domain, baselineValue, fill, peakOpacity, baselineOpacity, gradientAxis);
71
+ }, [gradientProp, valueAxisConfig, fill, baseline, peakOpacity, baselineOpacity, gradientAxis]);
68
72
 
69
73
  // Update transition is used for clip path, we skip update animation on Path itself
70
74
  return /*#__PURE__*/_jsx(Group, {
@@ -78,6 +82,7 @@ export const DottedArea = /*#__PURE__*/memo(_ref => {
78
82
  }, pathProps, {
79
83
  children: gradient && /*#__PURE__*/_jsx(Gradient, {
80
84
  gradient: gradient,
85
+ xAxisId: xAxisId,
81
86
  yAxisId: yAxisId
82
87
  })
83
88
  }))
@@ -1,4 +1,4 @@
1
- const _excluded = ["d", "fill", "fillOpacity", "gradient", "peakOpacity", "baselineOpacity", "baseline", "yAxisId", "animate", "transitions", "transition"];
1
+ const _excluded = ["d", "fill", "fillOpacity", "gradient", "peakOpacity", "baselineOpacity", "baseline", "xAxisId", "yAxisId", "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, useMemo } from 'react';
@@ -22,6 +22,7 @@ export const GradientArea = /*#__PURE__*/memo(_ref => {
22
22
  peakOpacity = 0.3,
23
23
  baselineOpacity = 0,
24
24
  baseline,
25
+ xAxisId,
25
26
  yAxisId,
26
27
  animate,
27
28
  transitions,
@@ -29,17 +30,20 @@ export const GradientArea = /*#__PURE__*/memo(_ref => {
29
30
  } = _ref,
30
31
  pathProps = _objectWithoutPropertiesLoose(_ref, _excluded);
31
32
  const {
33
+ layout,
34
+ getXAxis,
32
35
  getYAxis
33
36
  } = useCartesianChartContext();
34
37
  const theme = useTheme();
35
- const yAxisConfig = getYAxis(yAxisId);
38
+ const valueAxisConfig = layout !== 'horizontal' ? getYAxis(yAxisId) : getXAxis(xAxisId);
39
+ const gradientAxis = layout !== 'horizontal' ? 'y' : 'x';
36
40
  const fill = useMemo(() => fillProp != null ? fillProp : theme.color.fgPrimary, [fillProp, theme.color.fgPrimary]);
37
41
  const gradient = useMemo(() => {
38
42
  if (gradientProp) return gradientProp;
39
- if (!yAxisConfig) return;
40
- const baselineValue = getBaseline(yAxisConfig.domain, baseline);
41
- return createGradient(yAxisConfig.domain, baselineValue, fill, peakOpacity, baselineOpacity);
42
- }, [gradientProp, yAxisConfig, fill, baseline, peakOpacity, baselineOpacity]);
43
+ if (!valueAxisConfig) return;
44
+ const baselineValue = getBaseline(valueAxisConfig.domain, baseline);
45
+ return createGradient(valueAxisConfig.domain, baselineValue, fill, peakOpacity, baselineOpacity, gradientAxis);
46
+ }, [gradientProp, valueAxisConfig, fill, baseline, peakOpacity, baselineOpacity, gradientAxis]);
43
47
  return /*#__PURE__*/_jsx(Path, _extends({
44
48
  animate: animate,
45
49
  d: d,
@@ -50,6 +54,7 @@ export const GradientArea = /*#__PURE__*/memo(_ref => {
50
54
  }, pathProps, {
51
55
  children: gradient && /*#__PURE__*/_jsx(Gradient, {
52
56
  gradient: gradient,
57
+ xAxisId: xAxisId,
53
58
  yAxisId: yAxisId
54
59
  })
55
60
  }));
@@ -1,4 +1,4 @@
1
- const _excluded = ["d", "fill", "fillOpacity", "yAxisId", "animate", "transitions", "transition", "gradient"];
1
+ const _excluded = ["d", "fill", "fillOpacity", "xAxisId", "yAxisId", "animate", "transitions", "transition", "gradient"];
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';
@@ -16,6 +16,7 @@ export const SolidArea = /*#__PURE__*/memo(_ref => {
16
16
  d,
17
17
  fill,
18
18
  fillOpacity = 1,
19
+ xAxisId,
19
20
  yAxisId,
20
21
  animate,
21
22
  transitions,
@@ -34,6 +35,7 @@ export const SolidArea = /*#__PURE__*/memo(_ref => {
34
35
  }, pathProps, {
35
36
  children: gradient && /*#__PURE__*/_jsx(Gradient, {
36
37
  gradient: gradient,
38
+ xAxisId: xAxisId,
37
39
  yAxisId: yAxisId
38
40
  })
39
41
  }));
@@ -1,17 +1,22 @@
1
+ import { useCallback } from 'react';
1
2
  import { Example, ExampleScreen } from '@coinbase/cds-mobile/examples/ExampleScreen';
2
3
  import { useTheme } from '@coinbase/cds-mobile/hooks/useTheme';
3
4
  import { DottedLine } from '../../line';
4
5
  import { Scrubber } from '../../scrubber/Scrubber';
5
6
  import { AreaChart } from '..';
6
7
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
8
+ const basicData = [24, 13, 98, 39, 48, 38, 43];
7
9
  const BasicExample = () => {
10
+ const getScrubberAccessibilityLabel = useCallback(index => "Point " + (index + 1) + ": " + basicData[index], []);
8
11
  return /*#__PURE__*/_jsx(AreaChart, {
9
12
  enableScrubbing: true,
10
13
  showYAxis: true,
14
+ accessibilityLabel: "Area chart with " + basicData.length + " data points. Swipe to navigate.",
15
+ getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
11
16
  height: 400,
12
17
  series: [{
13
18
  id: 'pageViews',
14
- data: [24, 13, 98, 39, 48, 38, 43]
19
+ data: basicData
15
20
  }],
16
21
  yAxis: {
17
22
  showGrid: true,
@@ -22,21 +27,26 @@ const BasicExample = () => {
22
27
  children: /*#__PURE__*/_jsx(Scrubber, {})
23
28
  });
24
29
  };
30
+ const currentRewardsData = [100, 150, 200, 280, 380, 500, 650, 820, 1020, 1250, 1510, 1800, 2120, 2470, 2850, 3260, 3700, 4170];
31
+ const potentialRewardsData = [150, 220, 300, 400, 520, 660, 820, 1000, 1200, 1420, 1660, 1920, 2200, 2500, 2820, 3160, 3520, 3900];
25
32
  const StackedExample = () => {
26
33
  const theme = useTheme();
34
+ const getScrubberAccessibilityLabel = useCallback(index => "Point " + (index + 1) + ": current " + currentRewardsData[index] + ", potential " + potentialRewardsData[index], []);
27
35
  return /*#__PURE__*/_jsx(AreaChart, {
28
36
  enableScrubbing: true,
29
37
  showLines: true,
30
38
  stacked: true,
39
+ accessibilityLabel: "Stacked rewards chart with " + currentRewardsData.length + " data points. Swipe to navigate.",
31
40
  curve: "natural",
41
+ getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
32
42
  height: 256,
33
43
  series: [{
34
44
  id: 'currentRewards',
35
- data: [100, 150, 200, 280, 380, 500, 650, 820, 1020, 1250, 1510, 1800, 2120, 2470, 2850, 3260, 3700, 4170],
45
+ data: currentRewardsData,
36
46
  color: theme.color.fg
37
47
  }, {
38
48
  id: 'potentialRewards',
39
- data: [150, 220, 300, 400, 520, 660, 820, 1000, 1200, 1420, 1660, 1920, 2200, 2500, 2820, 3160, 3520, 3900],
49
+ data: potentialRewardsData,
40
50
  color: theme.color.fgPositive,
41
51
  type: 'dotted',
42
52
  LineComponent: DottedLine
@@ -59,12 +69,14 @@ const AreaChartStories = () => {
59
69
  enableScrubbing: true,
60
70
  showLines: true,
61
71
  showYAxis: true,
62
- height: 400,
72
+ accessibilityLabel: "Area chart with negative values. 7 data points. Swipe to navigate.",
73
+ getScrubberAccessibilityLabel: index => "Point " + (index + 1) + ": " + [24, 13, -98, 39, 48, 38, 43][index],
74
+ height: 150,
63
75
  series: [{
64
76
  id: 'pageViews',
65
77
  data: [24, 13, -98, 39, 48, 38, 43]
66
78
  }],
67
- type: "solid",
79
+ type: "gradient",
68
80
  yAxis: {
69
81
  showGrid: true
70
82
  },
@@ -94,6 +106,36 @@ const AreaChartStories = () => {
94
106
  type: 'gradient'
95
107
  }]
96
108
  })
109
+ }), /*#__PURE__*/_jsx(Example, {
110
+ title: "Horizontal Layout",
111
+ children: /*#__PURE__*/_jsx(AreaChart, {
112
+ enableScrubbing: true,
113
+ showLines: true,
114
+ showXAxis: true,
115
+ showYAxis: true,
116
+ accessibilityLabel: "Volume by asset. 5 data points. Swipe to navigate.",
117
+ getScrubberAccessibilityLabel: index => ['BTC', 'ETH', 'SOL', 'DOGE', 'ADA'][index] + ": " + [68, 54, 43, 29, 18][index] + "%",
118
+ height: 280,
119
+ layout: "horizontal",
120
+ series: [{
121
+ id: 'volume',
122
+ data: [68, 54, 43, 29, 18],
123
+ label: 'Volume'
124
+ }],
125
+ type: "gradient",
126
+ xAxis: {
127
+ domain: {
128
+ min: 0,
129
+ max: 80
130
+ },
131
+ tickLabelFormatter: value => value + "%"
132
+ },
133
+ yAxis: {
134
+ data: ['BTC', 'ETH', 'SOL', 'DOGE', 'ADA'],
135
+ scaleType: 'band'
136
+ },
137
+ children: /*#__PURE__*/_jsx(Scrubber, {})
138
+ })
97
139
  })]
98
140
  });
99
141
  };
@@ -1,4 +1,4 @@
1
- const _excluded = ["position", "showGrid", "requestedTickCount", "ticks", "tickLabelFormatter", "TickLabelComponent", "GridLineComponent", "LineComponent", "TickMarkLineComponent", "tickMarkLabelGap", "minTickLabelGap", "showTickMarks", "showLine", "tickMarkSize", "tickInterval", "tickMinStep", "tickMaxStep", "label", "labelGap", "height", "bandGridLinePlacement", "bandTickMarkPlacement"];
1
+ const _excluded = ["axisId", "position", "showGrid", "requestedTickCount", "ticks", "tickLabelFormatter", "TickLabelComponent", "GridLineComponent", "LineComponent", "TickMarkLineComponent", "tickMarkLabelGap", "minTickLabelGap", "showTickMarks", "showLine", "tickMarkSize", "tickInterval", "tickMinStep", "tickMaxStep", "label", "labelGap", "height", "bandGridLinePlacement", "bandTickMarkPlacement"];
2
2
  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; }
3
3
  import { memo, useCallback, useEffect, useId, useMemo } from 'react';
4
4
  import { useTheme } from '@coinbase/cds-mobile/hooks/useTheme';
@@ -15,6 +15,7 @@ const AXIS_HEIGHT = 32;
15
15
  const LABEL_SIZE = 20;
16
16
  export const XAxis = /*#__PURE__*/memo(_ref => {
17
17
  let {
18
+ axisId,
18
19
  position = 'bottom',
19
20
  showGrid,
20
21
  requestedTickCount,
@@ -44,14 +45,15 @@ export const XAxis = /*#__PURE__*/memo(_ref => {
44
45
  const {
45
46
  animate,
46
47
  drawingArea,
48
+ layout,
47
49
  getXScale,
48
50
  getXAxis,
49
51
  registerAxis,
50
52
  unregisterAxis,
51
53
  getAxisBounds
52
54
  } = useCartesianChartContext();
53
- const xScale = getXScale();
54
- const xAxis = getXAxis();
55
+ const xScale = getXScale(axisId);
56
+ const xAxis = getXAxis(axisId);
55
57
  const axisBounds = getAxisBounds(registrationId);
56
58
  useEffect(() => {
57
59
  registerAxis(registrationId, position, height);
@@ -62,15 +64,12 @@ export const XAxis = /*#__PURE__*/memo(_ref => {
62
64
  // If we have string labels and no custom formatter, use the labels
63
65
  const axisData = xAxis == null ? void 0 : xAxis.data;
64
66
  const hasStringLabels = axisData && Array.isArray(axisData) && typeof axisData[0] === 'string';
65
- let finalValue = value;
66
-
67
- // For band scales with string data, value is an index
68
- if (hasStringLabels && typeof value === 'number' && axisData[value] !== undefined) {
69
- finalValue = axisData[value];
67
+ if (hasStringLabels && !tickLabelFormatter && axisData[value] !== undefined) {
68
+ return axisData[value];
70
69
  }
71
70
 
72
- // Use the formatter (if provided) or the value itself
73
- return (_tickLabelFormatter = tickLabelFormatter == null ? void 0 : tickLabelFormatter(finalValue)) != null ? _tickLabelFormatter : finalValue;
71
+ // Otherwise passes raw index to formatter
72
+ return (_tickLabelFormatter = tickLabelFormatter == null ? void 0 : tickLabelFormatter(value)) != null ? _tickLabelFormatter : value;
74
73
  }, [xAxis == null ? void 0 : xAxis.data, tickLabelFormatter]);
75
74
  const ticksData = useMemo(() => {
76
75
  if (!xScale) return [];
@@ -89,27 +88,21 @@ export const XAxis = /*#__PURE__*/memo(_ref => {
89
88
  const domain = xScale.domain();
90
89
  categories = domain.map(String);
91
90
  }
92
- let possibleTickValues;
93
-
94
- // If we have discrete data, we can use the indices as possible tick values
95
- if (axisData && Array.isArray(axisData) && (typeof axisData[0] === 'string' || typeof axisData[0] === 'number' && isCategoricalScale(xScale))) {
96
- possibleTickValues = Array.from({
97
- length: axisData.length
98
- }, (_, i) => i);
99
- }
100
91
  return getAxisTicksData({
101
92
  scaleFunction: xScale,
102
93
  ticks,
103
- requestedTickCount,
94
+ requestedTickCount: requestedTickCount != null ? requestedTickCount : layout === 'horizontal' ? 5 : undefined,
104
95
  categories,
105
- possibleTickValues,
96
+ possibleTickValues: axisData && Array.isArray(axisData) && typeof axisData[0] === 'string' ? Array.from({
97
+ length: axisData.length
98
+ }, (_, i) => i) : undefined,
106
99
  tickInterval: tickInterval,
107
100
  options: {
108
101
  minStep: tickMinStep,
109
102
  maxStep: tickMaxStep
110
103
  }
111
104
  });
112
- }, [ticks, xScale, requestedTickCount, tickInterval, tickMinStep, tickMaxStep, xAxis == null ? void 0 : xAxis.data]);
105
+ }, [ticks, xScale, requestedTickCount, tickInterval, tickMinStep, tickMaxStep, xAxis == null ? void 0 : xAxis.data, layout]);
113
106
  const isBandScale = useMemo(() => {
114
107
  if (!xScale) return false;
115
108
  return isCategoricalScale(xScale);
@@ -18,7 +18,7 @@ export const YAxis = /*#__PURE__*/memo(_ref => {
18
18
  axisId,
19
19
  position = 'right',
20
20
  showGrid,
21
- requestedTickCount = 5,
21
+ requestedTickCount,
22
22
  ticks,
23
23
  tickLabelFormatter,
24
24
  TickLabelComponent = DefaultAxisTickLabel,
@@ -43,6 +43,7 @@ export const YAxis = /*#__PURE__*/memo(_ref => {
43
43
  const {
44
44
  animate,
45
45
  drawingArea,
46
+ layout,
46
47
  getYScale,
47
48
  getYAxis,
48
49
  registerAxis,
@@ -94,12 +95,12 @@ export const YAxis = /*#__PURE__*/memo(_ref => {
94
95
  return getAxisTicksData({
95
96
  scaleFunction: yScale,
96
97
  ticks,
97
- requestedTickCount: tickInterval !== undefined ? undefined : requestedTickCount != null ? requestedTickCount : 5,
98
+ requestedTickCount: tickInterval !== undefined ? undefined : requestedTickCount != null ? requestedTickCount : layout === 'horizontal' ? undefined : 5,
98
99
  categories,
99
100
  possibleTickValues: axisData && Array.isArray(axisData) && typeof axisData[0] === 'number' ? axisData : undefined,
100
101
  tickInterval: tickInterval
101
102
  });
102
- }, [ticks, yScale, requestedTickCount, tickInterval, yAxis == null ? void 0 : yAxis.data]);
103
+ }, [ticks, yScale, requestedTickCount, tickInterval, yAxis == null ? void 0 : yAxis.data, layout]);
103
104
  const isBandScale = useMemo(() => {
104
105
  if (!yScale) return false;
105
106
  return isCategoricalScale(yScale);
@@ -53,10 +53,14 @@ const Simple = () => {
53
53
  const pageViews = data.map(d => d.pv);
54
54
  const pageNames = data.map(d => d.name);
55
55
  const pageUniqueVisitors = data.map(d => d.uv);
56
+ const chartAccessibilityLabel = "Page views and unique visitors across " + pageNames.length + " pages. Swipe to navigate.";
57
+ const getScrubberAccessibilityLabel = useCallback(index => pageNames[index] + ": " + pageViews[index] + " views, " + pageUniqueVisitors[index] + " unique visitors", [pageNames, pageViews, pageUniqueVisitors]);
56
58
  return /*#__PURE__*/_jsx(LineChart, {
57
59
  enableScrubbing: true,
58
60
  showXAxis: true,
59
61
  showYAxis: true,
62
+ accessibilityLabel: chartAccessibilityLabel,
63
+ getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
60
64
  height: defaultChartHeight,
61
65
  inset: 32,
62
66
  series: [{
@@ -97,8 +101,8 @@ const Simple = () => {
97
101
  };
98
102
  const TimeOfDayAxesExample = () => {
99
103
  const theme = useTheme();
100
- const lineA = [5, 5, 10, 90, 85, 70, 30, 25, 25];
101
- const lineB = [90, 85, 70, 25, 23, 40, 45, 40, 50];
104
+ const lineA = useMemo(() => [5, 5, 10, 90, 85, 70, 30, 25, 25], []);
105
+ const lineB = useMemo(() => [90, 85, 70, 25, 23, 40, 45, 40, 50], []);
102
106
  const timeData = useMemo(() => [new Date(2023, 7, 31), new Date(2023, 7, 31, 12), new Date(2023, 8, 1), new Date(2023, 8, 1, 12), new Date(2023, 8, 2), new Date(2023, 8, 2, 12), new Date(2023, 8, 3), new Date(2023, 8, 3, 12), new Date(2023, 8, 4)].map(d => d.getTime()), []);
103
107
  const dateFormatter = useCallback(index => {
104
108
  return new Date(timeData[index]).toLocaleDateString('en-US', {
@@ -117,8 +121,12 @@ const TimeOfDayAxesExample = () => {
117
121
  const dateTicks = useMemo(() => {
118
122
  return timeData.map((d, index) => index).filter(d => d % 2 === 0);
119
123
  }, [timeData]);
124
+ const chartAccessibilityLabel = "Chart with " + lineA.length + " data points. Swipe to navigate.";
125
+ const getScrubberAccessibilityLabel = useCallback(index => "Point " + (index + 1) + ": lineA " + lineA[index] + ", lineB " + lineB[index], [lineA, lineB]);
120
126
  return /*#__PURE__*/_jsxs(LineChart, {
121
127
  enableScrubbing: true,
128
+ accessibilityLabel: chartAccessibilityLabel,
129
+ getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
122
130
  height: defaultChartHeight,
123
131
  series: [{
124
132
  id: 'lineA',
@@ -150,51 +158,57 @@ const TimeOfDayAxesExample = () => {
150
158
  }), /*#__PURE__*/_jsx(Scrubber, {})]
151
159
  });
152
160
  };
153
- const MultipleYAxesExample = () => /*#__PURE__*/_jsxs(CartesianChart, {
154
- enableScrubbing: true,
155
- height: defaultChartHeight,
156
- series: [{
157
- id: 'linear',
158
- yAxisId: 'linearAxis',
159
- data: [1, 10, 30, 50, 70, 90, 100],
160
- label: 'linear'
161
- }, {
162
- id: 'log',
163
- yAxisId: 'logAxis',
164
- data: [1, 10, 30, 50, 70, 90, 100],
165
- label: 'log'
166
- }],
167
- xAxis: {
168
- data: [1, 10, 30, 50, 70, 90, 100]
169
- },
170
- yAxis: [{
171
- id: 'linearAxis',
172
- scaleType: 'linear'
173
- }, {
174
- id: 'logAxis',
175
- scaleType: 'log'
176
- }],
177
- children: [/*#__PURE__*/_jsx(XAxis, {
178
- showLine: true,
179
- showTickMarks: true
180
- }), /*#__PURE__*/_jsx(YAxis, {
181
- showLine: true,
182
- showTickMarks: true,
183
- axisId: "logAxis",
184
- position: "left"
185
- }), /*#__PURE__*/_jsx(YAxis, {
186
- showLine: true,
187
- showTickMarks: true,
188
- axisId: "linearAxis",
189
- position: "left"
190
- }), /*#__PURE__*/_jsx(Line, {
191
- curve: "natural",
192
- seriesId: "linear"
193
- }), /*#__PURE__*/_jsx(Line, {
194
- curve: "natural",
195
- seriesId: "log"
196
- }), /*#__PURE__*/_jsx(Scrubber, {})]
197
- });
161
+ const multipleYAxesData = [1, 10, 30, 50, 70, 90, 100];
162
+ const MultipleYAxesExample = () => {
163
+ const getScrubberAccessibilityLabel = useCallback(index => "Point " + (index + 1) + ": linear " + multipleYAxesData[index] + ", log " + multipleYAxesData[index], []);
164
+ return /*#__PURE__*/_jsxs(CartesianChart, {
165
+ enableScrubbing: true,
166
+ accessibilityLabel: "Chart with linear and log axes. 7 data points. Swipe to navigate.",
167
+ getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
168
+ height: defaultChartHeight,
169
+ series: [{
170
+ id: 'linear',
171
+ yAxisId: 'linearAxis',
172
+ data: multipleYAxesData,
173
+ label: 'linear'
174
+ }, {
175
+ id: 'log',
176
+ yAxisId: 'logAxis',
177
+ data: multipleYAxesData,
178
+ label: 'log'
179
+ }],
180
+ xAxis: {
181
+ data: multipleYAxesData
182
+ },
183
+ yAxis: [{
184
+ id: 'linearAxis',
185
+ scaleType: 'linear'
186
+ }, {
187
+ id: 'logAxis',
188
+ scaleType: 'log'
189
+ }],
190
+ children: [/*#__PURE__*/_jsx(XAxis, {
191
+ showLine: true,
192
+ showTickMarks: true
193
+ }), /*#__PURE__*/_jsx(YAxis, {
194
+ showLine: true,
195
+ showTickMarks: true,
196
+ axisId: "logAxis",
197
+ position: "left"
198
+ }), /*#__PURE__*/_jsx(YAxis, {
199
+ showLine: true,
200
+ showTickMarks: true,
201
+ axisId: "linearAxis",
202
+ position: "left"
203
+ }), /*#__PURE__*/_jsx(Line, {
204
+ curve: "natural",
205
+ seriesId: "linear"
206
+ }), /*#__PURE__*/_jsx(Line, {
207
+ curve: "natural",
208
+ seriesId: "log"
209
+ }), /*#__PURE__*/_jsx(Scrubber, {})]
210
+ });
211
+ };
198
212
  const AxesOnAllSides = () => {
199
213
  const theme = useTheme();
200
214
  const data = [30, 45, 60, 80, 55, 40, 65];
@@ -298,9 +312,12 @@ const DomainLimitType = _ref => {
298
312
  let {
299
313
  limit
300
314
  } = _ref;
301
- const exponentialData = [1, 2, 4, 8, 15, 30, 65, 140, 280, 580, 1200, 2400, 4800, 9500, 19000, 38000, 75000, 150000];
315
+ const exponentialData = useMemo(() => [1, 2, 4, 8, 15, 30, 65, 140, 280, 580, 1200, 2400, 4800, 9500, 19000, 38000, 75000, 150000], []);
316
+ const getScrubberAccessibilityLabel = useCallback(index => "Point " + (index + 1) + ": " + exponentialData[index], [exponentialData]);
302
317
  return /*#__PURE__*/_jsxs(CartesianChart, {
303
318
  enableScrubbing: true,
319
+ accessibilityLabel: "Exponential growth chart with " + exponentialData.length + " data points. Swipe to navigate.",
320
+ getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
304
321
  height: defaultChartHeight,
305
322
  series: [{
306
323
  id: 'growthLinear',