@coinbase/cds-mobile-visualization 3.4.0-beta.21 → 3.4.0-beta.23

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 +14 -0
  2. package/dts/chart/CartesianChart.d.ts +39 -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/PeriodSelector.d.ts +18 -6
  6. package/dts/chart/PeriodSelector.d.ts.map +1 -1
  7. package/dts/chart/area/Area.d.ts +7 -0
  8. package/dts/chart/area/Area.d.ts.map +1 -1
  9. package/dts/chart/area/AreaChart.d.ts +33 -9
  10. package/dts/chart/area/AreaChart.d.ts.map +1 -1
  11. package/dts/chart/area/DottedArea.d.ts.map +1 -1
  12. package/dts/chart/area/GradientArea.d.ts.map +1 -1
  13. package/dts/chart/area/SolidArea.d.ts.map +1 -1
  14. package/dts/chart/axis/Axis.d.ts +3 -1
  15. package/dts/chart/axis/Axis.d.ts.map +1 -1
  16. package/dts/chart/axis/XAxis.d.ts +6 -0
  17. package/dts/chart/axis/XAxis.d.ts.map +1 -1
  18. package/dts/chart/axis/YAxis.d.ts +1 -0
  19. package/dts/chart/axis/YAxis.d.ts.map +1 -1
  20. package/dts/chart/bar/Bar.d.ts +4 -2
  21. package/dts/chart/bar/Bar.d.ts.map +1 -1
  22. package/dts/chart/bar/BarChart.d.ts +49 -9
  23. package/dts/chart/bar/BarChart.d.ts.map +1 -1
  24. package/dts/chart/bar/BarPlot.d.ts.map +1 -1
  25. package/dts/chart/bar/BarStack.d.ts +30 -9
  26. package/dts/chart/bar/BarStack.d.ts.map +1 -1
  27. package/dts/chart/bar/BarStackGroup.d.ts +1 -1
  28. package/dts/chart/bar/BarStackGroup.d.ts.map +1 -1
  29. package/dts/chart/bar/DefaultBar.d.ts.map +1 -1
  30. package/dts/chart/bar/DefaultBarStack.d.ts.map +1 -1
  31. package/dts/chart/gradient/Gradient.d.ts +5 -0
  32. package/dts/chart/gradient/Gradient.d.ts.map +1 -1
  33. package/dts/chart/line/DottedLine.d.ts.map +1 -1
  34. package/dts/chart/line/Line.d.ts +7 -0
  35. package/dts/chart/line/Line.d.ts.map +1 -1
  36. package/dts/chart/line/LineChart.d.ts +8 -5
  37. package/dts/chart/line/LineChart.d.ts.map +1 -1
  38. package/dts/chart/line/ReferenceLine.d.ts +1 -0
  39. package/dts/chart/line/ReferenceLine.d.ts.map +1 -1
  40. package/dts/chart/line/SolidLine.d.ts.map +1 -1
  41. package/dts/chart/point/Point.d.ts +7 -0
  42. package/dts/chart/point/Point.d.ts.map +1 -1
  43. package/dts/chart/scrubber/DefaultScrubberBeacon.d.ts.map +1 -1
  44. package/dts/chart/scrubber/DefaultScrubberLabel.d.ts +2 -1
  45. package/dts/chart/scrubber/DefaultScrubberLabel.d.ts.map +1 -1
  46. package/dts/chart/scrubber/Scrubber.d.ts +8 -0
  47. package/dts/chart/scrubber/Scrubber.d.ts.map +1 -1
  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 +6 -5
  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/dts/chart/utils/transition.d.ts +7 -4
  65. package/dts/chart/utils/transition.d.ts.map +1 -1
  66. package/esm/chart/CartesianChart.js +107 -68
  67. package/esm/chart/Path.js +18 -14
  68. package/esm/chart/__stories__/ChartTransitions.stories.js +6 -10
  69. package/esm/chart/area/Area.js +19 -9
  70. package/esm/chart/area/AreaChart.js +18 -13
  71. package/esm/chart/area/DottedArea.js +23 -17
  72. package/esm/chart/area/GradientArea.js +11 -6
  73. package/esm/chart/area/SolidArea.js +3 -1
  74. package/esm/chart/area/__stories__/AreaChart.stories.js +30 -2
  75. package/esm/chart/axis/XAxis.js +14 -21
  76. package/esm/chart/axis/YAxis.js +4 -3
  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 +99 -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 +36 -21
  88. package/esm/chart/line/LineChart.js +13 -11
  89. package/esm/chart/line/SolidLine.js +3 -1
  90. package/esm/chart/line/__stories__/LineChart.stories.js +31 -0
  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/ScrubberBeaconGroup.js +24 -20
  96. package/esm/chart/scrubber/ScrubberProvider.js +29 -24
  97. package/esm/chart/scrubber/__stories__/Scrubber.stories.js +135 -1
  98. package/esm/chart/utils/axis.js +42 -14
  99. package/esm/chart/utils/bar.js +6 -4
  100. package/esm/chart/utils/chart.js +18 -5
  101. package/esm/chart/utils/context.js +7 -0
  102. package/esm/chart/utils/gradient.js +8 -4
  103. package/esm/chart/utils/path.js +90 -61
  104. package/esm/chart/utils/point.js +28 -18
  105. package/esm/chart/utils/transition.js +28 -10
  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
- const _excluded = ["series", "stacked", "AreaComponent", "curve", "fillOpacity", "type", "connectNulls", "transition", "LineComponent", "strokeWidth", "showXAxis", "showYAxis", "showLines", "lineType", "xAxis", "yAxis", "inset", "children"],
2
- _excluded2 = ["scaleType", "data", "categoryPadding", "domain", "domainLimit", "range"],
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", "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", "lineType"];
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) => {
@@ -22,6 +22,7 @@ export const AreaChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) =
22
22
  type,
23
23
  connectNulls,
24
24
  transition,
25
+ transitions,
25
26
  LineComponent,
26
27
  strokeWidth,
27
28
  showXAxis,
@@ -34,8 +35,6 @@ export const AreaChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) =
34
35
  children
35
36
  } = _ref,
36
37
  chartProps = _objectWithoutPropertiesLoose(_ref, _excluded);
37
- const calculatedInset = useMemo(() => getChartInset(inset, defaultChartInset), [inset]);
38
-
39
38
  // Convert AreaSeries to Series for Chart context
40
39
  const chartSeries = useMemo(() => {
41
40
  return series == null ? void 0 : series.map(s => ({
@@ -44,6 +43,7 @@ export const AreaChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) =
44
43
  label: s.label,
45
44
  color: s.color,
46
45
  gradient: s.gradient,
46
+ xAxisId: s.xAxisId,
47
47
  yAxisId: s.yAxisId,
48
48
  stackId: s.stackId
49
49
  }));
@@ -67,7 +67,8 @@ export const AreaChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) =
67
67
  categoryPadding: xCategoryPadding,
68
68
  domain: xDomain,
69
69
  domainLimit: xDomainLimit,
70
- range: xRange
70
+ range: xRange,
71
+ id: xAxisId
71
72
  } = _ref2,
72
73
  xAxisVisualProps = _objectWithoutPropertiesLoose(_ref2, _excluded2);
73
74
  const _ref3 = yAxis || {},
@@ -110,11 +111,13 @@ export const AreaChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) =
110
111
  };
111
112
  return /*#__PURE__*/_jsxs(CartesianChart, _extends({}, chartProps, {
112
113
  ref: ref,
113
- inset: calculatedInset,
114
+ inset: inset,
114
115
  series: seriesToRender,
115
116
  xAxis: xAxisConfig,
116
117
  yAxis: yAxisConfig,
117
- 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({
118
121
  axisId: yAxisId
119
122
  }, yAxisVisualProps)), series == null ? void 0 : series.map(_ref4 => {
120
123
  let {
@@ -128,13 +131,14 @@ export const AreaChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) =
128
131
  fillOpacity: fillOpacity,
129
132
  seriesId: id,
130
133
  transition: transition,
134
+ transitions: transitions,
131
135
  type: type
132
136
  }, areaPropsFromSeries), id);
133
137
  }), showLines && (series == null ? void 0 : series.map(_ref5 => {
134
138
  let {
135
- id,
139
+ id
140
+
136
141
  // Area type (don't pass to Line)
137
- lineType: seriesLineType
138
142
  } = _ref5,
139
143
  otherPropsFromSeries = _objectWithoutPropertiesLoose(_ref5, _excluded5);
140
144
  return /*#__PURE__*/_jsx(Line, _extends({
@@ -144,7 +148,8 @@ export const AreaChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) =
144
148
  seriesId: id,
145
149
  strokeWidth: strokeWidth,
146
150
  transition: transition,
147
- type: seriesLineType != null ? seriesLineType : lineType
151
+ transitions: transitions,
152
+ type: lineType
148
153
  }, otherPropsFromSeries), id);
149
154
  })), children]
150
155
  }));
@@ -1,15 +1,15 @@
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';
5
5
  import { useTheme } from '@coinbase/cds-mobile/hooks/useTheme';
6
- import { Group, Skia } from '@shopify/react-native-skia';
6
+ import { Group } from '@shopify/react-native-skia';
7
7
  import { useCartesianChartContext } from '../ChartProvider';
8
8
  import { Gradient } from '../gradient';
9
9
  import { Path } from '../Path';
10
10
  import { createGradient, getBaseline } from '../utils';
11
11
  import { getDottedAreaPath } from '../utils/path';
12
- import { usePathTransition } from '../utils/transition';
12
+ import { defaultTransition, usePathTransition } from '../utils/transition';
13
13
  import { jsx as _jsx } from "react/jsx-runtime";
14
14
  /**
15
15
  * A customizable dotted area gradient component.
@@ -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,17 @@ 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
- const yAxisConfig = getYAxis(yAxisId);
44
+ const shouldAnimate = animateProp != null ? animateProp : animate;
45
+ const valueAxisConfig = layout !== 'horizontal' ? getYAxis(yAxisId) : getXAxis(xAxisId);
46
+ const gradientAxis = layout !== 'horizontal' ? 'y' : 'x';
42
47
  const fill = useMemo(() => fillProp != null ? fillProp : theme.color.fgPrimary, [fillProp, theme.color.fgPrimary]);
48
+ const updateTransition = useMemo(() => {
49
+ return (transitions == null ? void 0 : transitions.update) !== undefined ? transitions.update : transition !== undefined ? transition : defaultTransition;
50
+ }, [transitions == null ? void 0 : transitions.update, transition]);
43
51
  const dottedPath = useMemo(() => {
44
52
  if (!drawingArea) return '';
45
53
  return getDottedAreaPath({
@@ -49,27 +57,24 @@ export const DottedArea = /*#__PURE__*/memo(_ref => {
49
57
  height: drawingArea.height
50
58
  }, patternSize, dotSize);
51
59
  }, [drawingArea, patternSize, dotSize]);
52
- const animatedClipPath = usePathTransition({
60
+ const clipPath = usePathTransition({
53
61
  currentPath: d,
54
62
  transitions: {
55
- update: transition
63
+ update: shouldAnimate ? updateTransition : null
56
64
  }
57
65
  });
58
- const staticClipPath = useMemo(() => {
59
- var _Skia$Path$MakeFromSV;
60
- if (!d) return;
61
- return (_Skia$Path$MakeFromSV = Skia.Path.MakeFromSVGString(d)) != null ? _Skia$Path$MakeFromSV : undefined;
62
- }, [d]);
63
66
  const gradient = useMemo(() => {
64
67
  if (gradientProp) return gradientProp;
65
- if (!yAxisConfig) return;
66
- const baselineValue = getBaseline(yAxisConfig.domain, baseline);
67
- return createGradient(yAxisConfig.domain, baselineValue, fill, peakOpacity, baselineOpacity);
68
- }, [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]);
72
+
73
+ // Update transition is used for clip path, we skip update animation on Path itself
69
74
  return /*#__PURE__*/_jsx(Group, {
70
- clip: animate ? animatedClipPath : staticClipPath,
75
+ clip: clipPath,
71
76
  children: /*#__PURE__*/_jsx(Path, _extends({
72
- animate: animateProp != null ? animateProp : animate,
77
+ animate: shouldAnimate,
73
78
  d: dottedPath,
74
79
  fill: fill,
75
80
  transition: transition,
@@ -77,6 +82,7 @@ export const DottedArea = /*#__PURE__*/memo(_ref => {
77
82
  }, pathProps, {
78
83
  children: gradient && /*#__PURE__*/_jsx(Gradient, {
79
84
  gradient: gradient,
85
+ xAxisId: xAxisId,
80
86
  yAxisId: yAxisId
81
87
  })
82
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
  }));
@@ -59,12 +59,12 @@ const AreaChartStories = () => {
59
59
  enableScrubbing: true,
60
60
  showLines: true,
61
61
  showYAxis: true,
62
- height: 400,
62
+ height: 150,
63
63
  series: [{
64
64
  id: 'pageViews',
65
65
  data: [24, 13, -98, 39, 48, 38, 43]
66
66
  }],
67
- type: "solid",
67
+ type: "gradient",
68
68
  yAxis: {
69
69
  showGrid: true
70
70
  },
@@ -94,6 +94,34 @@ const AreaChartStories = () => {
94
94
  type: 'gradient'
95
95
  }]
96
96
  })
97
+ }), /*#__PURE__*/_jsx(Example, {
98
+ title: "Horizontal Layout",
99
+ children: /*#__PURE__*/_jsx(AreaChart, {
100
+ enableScrubbing: true,
101
+ showLines: true,
102
+ showXAxis: true,
103
+ showYAxis: true,
104
+ height: 280,
105
+ layout: "horizontal",
106
+ series: [{
107
+ id: 'volume',
108
+ data: [68, 54, 43, 29, 18],
109
+ label: 'Volume'
110
+ }],
111
+ type: "gradient",
112
+ xAxis: {
113
+ domain: {
114
+ min: 0,
115
+ max: 80
116
+ },
117
+ tickLabelFormatter: value => value + "%"
118
+ },
119
+ yAxis: {
120
+ data: ['BTC', 'ETH', 'SOL', 'DOGE', 'ADA'],
121
+ scaleType: 'band'
122
+ },
123
+ children: /*#__PURE__*/_jsx(Scrubber, {})
124
+ })
97
125
  })]
98
126
  });
99
127
  };
@@ -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);
@@ -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,7 +22,7 @@ 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,
27
28
  seriesId,
@@ -37,14 +38,17 @@ export const Bar = /*#__PURE__*/memo(_ref => {
37
38
  transition
38
39
  } = _ref;
39
40
  const theme = useTheme();
41
+ const {
42
+ layout
43
+ } = useCartesianChartContext();
40
44
 
41
45
  // Use theme color as default if no fill is provided
42
46
  const effectiveFill = fill != null ? fill : theme.color.fgPrimary;
43
47
  const borderRadiusPixels = useMemo(() => borderRadius != null ? borderRadius : 0, [borderRadius]);
44
48
  const barPath = useMemo(() => {
45
- return getBarPath(x, y, width, height, borderRadiusPixels, roundTop, roundBottom);
46
- }, [x, y, width, height, borderRadiusPixels, roundTop, roundBottom]);
47
- const effectiveOriginY = originY != null ? originY : y + height;
49
+ return getBarPath(x, y, width, height, borderRadiusPixels, roundTop, roundBottom, layout);
50
+ }, [x, y, width, height, borderRadiusPixels, roundTop, roundBottom, layout]);
51
+ const effectiveOrigin = originProp != null ? originProp : layout === 'horizontal' ? x : y + height;
48
52
  if (!barPath) {
49
53
  return null;
50
54
  }
@@ -58,7 +62,7 @@ export const Bar = /*#__PURE__*/memo(_ref => {
58
62
  fill: effectiveFill,
59
63
  fillOpacity: fillOpacity,
60
64
  height: height,
61
- originY: effectiveOriginY,
65
+ origin: effectiveOrigin,
62
66
  roundBottom: roundBottom,
63
67
  roundTop: roundTop,
64
68
  seriesId: seriesId,
@@ -1,17 +1,17 @@
1
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"],
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,
@@ -34,21 +34,19 @@ export const BarChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) =>
34
34
  transition
35
35
  } = _ref,
36
36
  chartProps = _objectWithoutPropertiesLoose(_ref, _excluded);
37
- const calculatedInset = useMemo(() => getChartInset(inset, defaultChartInset), [inset]);
38
- const transformedSeries = useMemo(() => {
39
- if (!stacked || !series) return series;
40
- return series.map(s => {
37
+ const series = useMemo(() => {
38
+ if (!stacked || !seriesProp) return seriesProp;
39
+ return seriesProp.map(s => {
41
40
  var _s$stackId;
42
41
  return _extends({}, s, {
43
42
  stackId: (_s$stackId = s.stackId) != null ? _s$stackId : defaultStackId
44
43
  });
45
44
  });
46
- }, [series, stacked]);
47
-
48
- // Unlike other charts with custom props per series, we do not need to pick out
49
- // the props from each series that shouldn't be passed to CartesianChart
50
- const seriesToRender = transformedSeries != null ? transformedSeries : series;
51
- 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 isHorizontal = chartProps.layout === 'horizontal';
48
+ const defaultXScaleType = isHorizontal ? 'linear' : 'band';
49
+ const defaultYScaleType = isHorizontal ? 'band' : 'linear';
52
50
 
53
51
  // Split axis props into config props for Chart and visual props for axis components
54
52
  const _ref2 = xAxis || {},
@@ -58,7 +56,8 @@ export const BarChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) =>
58
56
  categoryPadding: xCategoryPadding,
59
57
  domain: xDomain,
60
58
  domainLimit: xDomainLimit,
61
- range: xRange
59
+ range: xRange,
60
+ id: xAxisId
62
61
  } = _ref2,
63
62
  xAxisVisualProps = _objectWithoutPropertiesLoose(_ref2, _excluded2);
64
63
  const _ref3 = yAxis || {},
@@ -72,14 +71,6 @@ export const BarChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) =>
72
71
  id: yAxisId
73
72
  } = _ref3,
74
73
  yAxisVisualProps = _objectWithoutPropertiesLoose(_ref3, _excluded3);
75
- const xAxisConfig = {
76
- scaleType: xScaleType != null ? xScaleType : 'band',
77
- data: xData,
78
- categoryPadding: xCategoryPadding,
79
- domain: xDomain,
80
- domainLimit: xDomainLimit,
81
- range: xRange
82
- };
83
74
  const hasNegativeValues = useMemo(() => {
84
75
  if (!series) return false;
85
76
  return series.some(s => {
@@ -87,25 +78,37 @@ export const BarChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) =>
87
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));
88
79
  });
89
80
  }, [series]);
81
+ const xAxisConfig = useMemo(() => ({
82
+ scaleType: xScaleType != null ? xScaleType : defaultXScaleType,
83
+ data: xData,
84
+ categoryPadding: xCategoryPadding,
85
+ domain: isHorizontal && !hasNegativeValues ? _extends({
86
+ min: 0
87
+ }, xDomain) : xDomain,
88
+ domainLimit: xDomainLimit,
89
+ range: xRange
90
+ }), [xScaleType, defaultXScaleType, xData, xCategoryPadding, isHorizontal, hasNegativeValues, xDomain, xDomainLimit, xRange]);
90
91
 
91
- // Set default min domain to 0 for area chart, but only if there are no negative values
92
- const yAxisConfig = {
93
- 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,
94
95
  data: yData,
95
96
  categoryPadding: yCategoryPadding,
96
- domain: hasNegativeValues ? yDomain : _extends({
97
+ domain: !isHorizontal && !hasNegativeValues ? _extends({
97
98
  min: 0
98
- }, yDomain),
99
+ }, yDomain) : yDomain,
99
100
  domainLimit: yDomainLimit,
100
101
  range: yRange
101
- };
102
+ }), [yScaleType, defaultYScaleType, yData, yCategoryPadding, isHorizontal, hasNegativeValues, yDomain, yDomainLimit, yRange]);
102
103
  return /*#__PURE__*/_jsxs(CartesianChart, _extends({}, chartProps, {
103
104
  ref: ref,
104
- inset: calculatedInset,
105
- series: seriesToRender,
105
+ inset: inset,
106
+ series: series,
106
107
  xAxis: xAxisConfig,
107
108
  yAxis: yAxisConfig,
108
- 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({
109
112
  axisId: yAxisId
110
113
  }, yAxisVisualProps)), /*#__PURE__*/_jsx(BarPlot, {
111
114
  BarComponent: BarComponent,