@coinbase/cds-mobile-visualization 3.4.0-beta.5 → 3.4.0-beta.7

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 (179) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dts/chart/CartesianChart.d.ts +57 -33
  3. package/dts/chart/CartesianChart.d.ts.map +1 -1
  4. package/dts/chart/ChartContextBridge.d.ts +28 -0
  5. package/dts/chart/ChartContextBridge.d.ts.map +1 -0
  6. package/dts/chart/Path.d.ts +77 -34
  7. package/dts/chart/Path.d.ts.map +1 -1
  8. package/dts/chart/PeriodSelector.d.ts +1 -1
  9. package/dts/chart/PeriodSelector.d.ts.map +1 -1
  10. package/dts/chart/area/Area.d.ts +42 -27
  11. package/dts/chart/area/Area.d.ts.map +1 -1
  12. package/dts/chart/area/AreaChart.d.ts +51 -10
  13. package/dts/chart/area/AreaChart.d.ts.map +1 -1
  14. package/dts/chart/area/DottedArea.d.ts +21 -2
  15. package/dts/chart/area/DottedArea.d.ts.map +1 -1
  16. package/dts/chart/area/GradientArea.d.ts +19 -13
  17. package/dts/chart/area/GradientArea.d.ts.map +1 -1
  18. package/dts/chart/area/SolidArea.d.ts +17 -2
  19. package/dts/chart/area/SolidArea.d.ts.map +1 -1
  20. package/dts/chart/axis/Axis.d.ts +68 -78
  21. package/dts/chart/axis/Axis.d.ts.map +1 -1
  22. package/dts/chart/axis/DefaultAxisTickLabel.d.ts +8 -0
  23. package/dts/chart/axis/DefaultAxisTickLabel.d.ts.map +1 -0
  24. package/dts/chart/axis/XAxis.d.ts +1 -1
  25. package/dts/chart/axis/XAxis.d.ts.map +1 -1
  26. package/dts/chart/axis/YAxis.d.ts +2 -2
  27. package/dts/chart/axis/YAxis.d.ts.map +1 -1
  28. package/dts/chart/axis/index.d.ts +1 -0
  29. package/dts/chart/axis/index.d.ts.map +1 -1
  30. package/dts/chart/bar/Bar.d.ts +16 -13
  31. package/dts/chart/bar/Bar.d.ts.map +1 -1
  32. package/dts/chart/bar/BarChart.d.ts +36 -20
  33. package/dts/chart/bar/BarChart.d.ts.map +1 -1
  34. package/dts/chart/bar/BarPlot.d.ts +2 -1
  35. package/dts/chart/bar/BarPlot.d.ts.map +1 -1
  36. package/dts/chart/bar/BarStack.d.ts +39 -48
  37. package/dts/chart/bar/BarStack.d.ts.map +1 -1
  38. package/dts/chart/bar/BarStackGroup.d.ts +1 -0
  39. package/dts/chart/bar/BarStackGroup.d.ts.map +1 -1
  40. package/dts/chart/bar/DefaultBar.d.ts +1 -1
  41. package/dts/chart/bar/DefaultBar.d.ts.map +1 -1
  42. package/dts/chart/bar/DefaultBarStack.d.ts.map +1 -1
  43. package/dts/chart/gradient/Gradient.d.ts +25 -0
  44. package/dts/chart/gradient/Gradient.d.ts.map +1 -0
  45. package/dts/chart/gradient/index.d.ts +2 -0
  46. package/dts/chart/gradient/index.d.ts.map +1 -0
  47. package/dts/chart/index.d.ts +3 -1
  48. package/dts/chart/index.d.ts.map +1 -1
  49. package/dts/chart/line/DefaultReferenceLineLabel.d.ts +9 -0
  50. package/dts/chart/line/DefaultReferenceLineLabel.d.ts.map +1 -0
  51. package/dts/chart/line/DottedLine.d.ts +13 -5
  52. package/dts/chart/line/DottedLine.d.ts.map +1 -1
  53. package/dts/chart/line/Line.d.ts +62 -25
  54. package/dts/chart/line/Line.d.ts.map +1 -1
  55. package/dts/chart/line/LineChart.d.ts +43 -9
  56. package/dts/chart/line/LineChart.d.ts.map +1 -1
  57. package/dts/chart/line/ReferenceLine.d.ts +68 -20
  58. package/dts/chart/line/ReferenceLine.d.ts.map +1 -1
  59. package/dts/chart/line/SolidLine.d.ts +8 -5
  60. package/dts/chart/line/SolidLine.d.ts.map +1 -1
  61. package/dts/chart/line/index.d.ts +1 -1
  62. package/dts/chart/line/index.d.ts.map +1 -1
  63. package/dts/chart/point/DefaultPointLabel.d.ts +10 -0
  64. package/dts/chart/point/DefaultPointLabel.d.ts.map +1 -0
  65. package/dts/chart/point/Point.d.ts +120 -0
  66. package/dts/chart/point/Point.d.ts.map +1 -0
  67. package/dts/chart/point/index.d.ts +3 -0
  68. package/dts/chart/point/index.d.ts.map +1 -0
  69. package/dts/chart/scrubber/DefaultScrubberBeacon.d.ts +8 -0
  70. package/dts/chart/scrubber/DefaultScrubberBeacon.d.ts.map +1 -0
  71. package/dts/chart/scrubber/DefaultScrubberBeaconLabel.d.ts +12 -0
  72. package/dts/chart/scrubber/DefaultScrubberBeaconLabel.d.ts.map +1 -0
  73. package/dts/chart/scrubber/DefaultScrubberLabel.d.ts +11 -0
  74. package/dts/chart/scrubber/DefaultScrubberLabel.d.ts.map +1 -0
  75. package/dts/chart/scrubber/Scrubber.d.ts +172 -43
  76. package/dts/chart/scrubber/Scrubber.d.ts.map +1 -1
  77. package/dts/chart/scrubber/ScrubberBeaconGroup.d.ts +44 -0
  78. package/dts/chart/scrubber/ScrubberBeaconGroup.d.ts.map +1 -0
  79. package/dts/chart/scrubber/ScrubberBeaconLabelGroup.d.ts +31 -0
  80. package/dts/chart/scrubber/ScrubberBeaconLabelGroup.d.ts.map +1 -0
  81. package/dts/chart/scrubber/ScrubberProvider.d.ts +6 -3
  82. package/dts/chart/scrubber/ScrubberProvider.d.ts.map +1 -1
  83. package/dts/chart/scrubber/index.d.ts +3 -0
  84. package/dts/chart/scrubber/index.d.ts.map +1 -1
  85. package/dts/chart/text/ChartText.d.ts +151 -77
  86. package/dts/chart/text/ChartText.d.ts.map +1 -1
  87. package/dts/chart/text/{SmartChartTextGroup.d.ts → ChartTextGroup.d.ts} +9 -3
  88. package/dts/chart/text/ChartTextGroup.d.ts.map +1 -0
  89. package/dts/chart/text/index.d.ts +1 -1
  90. package/dts/chart/text/index.d.ts.map +1 -1
  91. package/dts/chart/utils/chart.d.ts +34 -7
  92. package/dts/chart/utils/chart.d.ts.map +1 -1
  93. package/dts/chart/utils/context.d.ts +28 -7
  94. package/dts/chart/utils/context.d.ts.map +1 -1
  95. package/dts/chart/utils/gradient.d.ts +117 -0
  96. package/dts/chart/utils/gradient.d.ts.map +1 -0
  97. package/dts/chart/utils/index.d.ts +3 -0
  98. package/dts/chart/utils/index.d.ts.map +1 -1
  99. package/dts/chart/utils/path.d.ts +53 -0
  100. package/dts/chart/utils/path.d.ts.map +1 -1
  101. package/dts/chart/utils/point.d.ts +60 -1
  102. package/dts/chart/utils/point.d.ts.map +1 -1
  103. package/dts/chart/utils/scale.d.ts +91 -0
  104. package/dts/chart/utils/scale.d.ts.map +1 -1
  105. package/dts/chart/utils/scrubber.d.ts +39 -0
  106. package/dts/chart/utils/scrubber.d.ts.map +1 -0
  107. package/dts/chart/utils/transition.d.ts +140 -0
  108. package/dts/chart/utils/transition.d.ts.map +1 -0
  109. package/esm/chart/CartesianChart.js +164 -70
  110. package/esm/chart/ChartContextBridge.js +148 -0
  111. package/esm/chart/Path.js +196 -113
  112. package/esm/chart/PeriodSelector.js +1 -1
  113. package/esm/chart/__stories__/CartesianChart.stories.js +371 -129
  114. package/esm/chart/__stories__/Chart.stories.js +2 -4
  115. package/esm/chart/area/Area.js +25 -35
  116. package/esm/chart/area/AreaChart.js +17 -12
  117. package/esm/chart/area/DottedArea.js +61 -109
  118. package/esm/chart/area/GradientArea.js +35 -91
  119. package/esm/chart/area/SolidArea.js +22 -8
  120. package/esm/chart/area/__stories__/AreaChart.stories.js +1 -1
  121. package/esm/chart/axis/Axis.js +2 -0
  122. package/esm/chart/axis/DefaultAxisTickLabel.js +11 -0
  123. package/esm/chart/axis/XAxis.js +62 -56
  124. package/esm/chart/axis/YAxis.js +58 -52
  125. package/esm/chart/axis/__stories__/Axis.stories.js +0 -1
  126. package/esm/chart/axis/index.js +1 -0
  127. package/esm/chart/bar/Bar.js +3 -1
  128. package/esm/chart/bar/BarChart.js +15 -37
  129. package/esm/chart/bar/BarPlot.js +41 -35
  130. package/esm/chart/bar/BarStack.js +75 -38
  131. package/esm/chart/bar/BarStackGroup.js +6 -16
  132. package/esm/chart/bar/DefaultBar.js +26 -48
  133. package/esm/chart/bar/DefaultBarStack.js +23 -58
  134. package/esm/chart/bar/__stories__/BarChart.stories.js +463 -77
  135. package/esm/chart/gradient/Gradient.js +53 -0
  136. package/esm/chart/gradient/index.js +1 -0
  137. package/esm/chart/index.js +3 -1
  138. package/esm/chart/line/DefaultReferenceLineLabel.js +66 -0
  139. package/esm/chart/line/DottedLine.js +29 -14
  140. package/esm/chart/line/Line.js +106 -67
  141. package/esm/chart/line/LineChart.js +20 -14
  142. package/esm/chart/line/ReferenceLine.js +80 -63
  143. package/esm/chart/line/SolidLine.js +25 -10
  144. package/esm/chart/line/__stories__/LineChart.stories.js +2098 -1975
  145. package/esm/chart/line/__stories__/ReferenceLine.stories.js +83 -28
  146. package/esm/chart/line/index.js +1 -1
  147. package/esm/chart/point/DefaultPointLabel.js +39 -0
  148. package/esm/chart/point/Point.js +188 -0
  149. package/esm/chart/point/index.js +2 -0
  150. package/esm/chart/scrubber/DefaultScrubberBeacon.js +179 -0
  151. package/esm/chart/scrubber/DefaultScrubberBeaconLabel.js +43 -0
  152. package/esm/chart/scrubber/DefaultScrubberLabel.js +28 -0
  153. package/esm/chart/scrubber/Scrubber.js +126 -146
  154. package/esm/chart/scrubber/ScrubberBeaconGroup.js +161 -0
  155. package/esm/chart/scrubber/ScrubberBeaconLabelGroup.js +185 -0
  156. package/esm/chart/scrubber/ScrubberProvider.js +46 -54
  157. package/esm/chart/scrubber/index.js +3 -1
  158. package/esm/chart/text/ChartText.js +242 -174
  159. package/esm/chart/text/{SmartChartTextGroup.js → ChartTextGroup.js} +6 -5
  160. package/esm/chart/text/index.js +1 -1
  161. package/esm/chart/utils/chart.js +44 -3
  162. package/esm/chart/utils/gradient.js +305 -0
  163. package/esm/chart/utils/index.js +3 -0
  164. package/esm/chart/utils/path.js +76 -8
  165. package/esm/chart/utils/point.js +116 -5
  166. package/esm/chart/utils/scale.js +230 -1
  167. package/esm/chart/utils/scrubber.js +139 -0
  168. package/esm/chart/utils/transition.js +214 -0
  169. package/package.json +7 -5
  170. package/dts/chart/Point.d.ts +0 -103
  171. package/dts/chart/Point.d.ts.map +0 -1
  172. package/dts/chart/line/GradientLine.d.ts +0 -45
  173. package/dts/chart/line/GradientLine.d.ts.map +0 -1
  174. package/dts/chart/scrubber/ScrubberBeacon.d.ts +0 -75
  175. package/dts/chart/scrubber/ScrubberBeacon.d.ts.map +0 -1
  176. package/dts/chart/text/SmartChartTextGroup.d.ts.map +0 -1
  177. package/esm/chart/Point.js +0 -111
  178. package/esm/chart/line/GradientLine.js +0 -62
  179. package/esm/chart/scrubber/ScrubberBeacon.js +0 -199
@@ -1,17 +1,19 @@
1
- const _excluded = ["position", "showGrid", "requestedTickCount", "ticks", "tickLabelFormatter", "style", "className", "styles", "classNames", "GridLineComponent", "tickMarkLabelGap", "height", "minTickLabelGap", "showTickMarks", "showLine", "tickMarkSize", "tickInterval", "tickMinStep", "tickMaxStep"];
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); }
1
+ const _excluded = ["position", "showGrid", "requestedTickCount", "ticks", "tickLabelFormatter", "TickLabelComponent", "GridLineComponent", "LineComponent", "TickMarkLineComponent", "tickMarkLabelGap", "minTickLabelGap", "showTickMarks", "showLine", "tickMarkSize", "tickInterval", "tickMinStep", "tickMaxStep", "label", "labelGap", "height"];
3
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; }
4
3
  import { memo, useCallback, useEffect, useId, useMemo } from 'react';
5
- import Animated, { useAnimatedStyle, useSharedValue } from 'react-native-reanimated';
6
- import { G, Line } from 'react-native-svg';
7
4
  import { useTheme } from '@coinbase/cds-mobile/hooks/useTheme';
5
+ import { Group } from '@shopify/react-native-skia';
8
6
  import { useCartesianChartContext } from '../ChartProvider';
9
7
  import { DottedLine } from '../line/DottedLine';
10
8
  import { ReferenceLine } from '../line/ReferenceLine';
11
- import { SmartChartTextGroup } from '../text/SmartChartTextGroup';
12
- import { getAxisTicksData, isCategoricalScale } from '../utils';
9
+ import { SolidLine } from '../line/SolidLine';
10
+ import { ChartText } from '../text/ChartText';
11
+ import { ChartTextGroup } from '../text/ChartTextGroup';
12
+ import { getAxisTicksData, isCategoricalScale, lineToPath } from '../utils';
13
+ import { DefaultAxisTickLabel } from './DefaultAxisTickLabel';
13
14
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
14
- const AnimatedG = Animated.createAnimatedComponent(G);
15
+ const AXIS_HEIGHT = 32;
16
+ const LABEL_SIZE = 20;
15
17
  export const XAxis = /*#__PURE__*/memo(_ref => {
16
18
  let {
17
19
  position = 'bottom',
@@ -19,18 +21,21 @@ export const XAxis = /*#__PURE__*/memo(_ref => {
19
21
  requestedTickCount,
20
22
  ticks,
21
23
  tickLabelFormatter,
22
- styles,
23
- classNames,
24
+ TickLabelComponent = DefaultAxisTickLabel,
24
25
  GridLineComponent = DottedLine,
26
+ LineComponent = SolidLine,
27
+ TickMarkLineComponent = SolidLine,
25
28
  tickMarkLabelGap = 2,
26
- height = 32,
27
29
  minTickLabelGap = 4,
28
30
  showTickMarks,
29
31
  showLine,
30
32
  tickMarkSize = 4,
31
33
  tickInterval = 32,
32
34
  tickMinStep = 1,
33
- tickMaxStep
35
+ tickMaxStep,
36
+ label,
37
+ labelGap = 4,
38
+ height = label ? AXIS_HEIGHT + LABEL_SIZE : AXIS_HEIGHT
34
39
  } = _ref,
35
40
  props = _objectWithoutPropertiesLoose(_ref, _excluded);
36
41
  const theme = useTheme();
@@ -46,17 +51,10 @@ export const XAxis = /*#__PURE__*/memo(_ref => {
46
51
  const xScale = getXScale();
47
52
  const xAxis = getXAxis();
48
53
  const axisBounds = getAxisBounds(registrationId);
49
- const gridOpacity = useSharedValue(1);
50
- const axisLineProps = useMemo(() => ({
51
- stroke: theme.color.fg,
52
- strokeLinecap: 'square',
53
- strokeWidth: 1
54
- }), [theme.color.fg]);
55
- const axisTickMarkProps = useMemo(() => ({
56
- stroke: theme.color.fg,
57
- strokeLinecap: 'square',
58
- strokeWidth: 1
59
- }), [theme.color.fg]);
54
+
55
+ // Note: gridOpacity not currently used in Skia version
56
+ // const gridOpacity = useSharedValue(1);
57
+
60
58
  useEffect(() => {
61
59
  registerAxis(registrationId, position, height);
62
60
  return () => unregisterAxis(registrationId);
@@ -118,64 +116,72 @@ export const XAxis = /*#__PURE__*/memo(_ref => {
118
116
  if (!axisBounds) return null;
119
117
  return ticksData.map(tick => {
120
118
  const tickOffset = tickMarkLabelGap + (showTickMarks ? tickMarkSize : 0);
121
- const availableSpace = axisBounds.height - tickOffset;
119
+
120
+ // Use AXIS_HEIGHT for centering, not full axisBounds.height
121
+ // This ensures tick labels are centered in the axis area, not including label space
122
+ const availableSpace = AXIS_HEIGHT - tickOffset;
122
123
  const labelOffset = availableSpace / 2;
123
- const labelY = position === 'top' ? axisBounds.y + labelOffset - tickOffset : axisBounds.y + labelOffset + tickOffset;
124
+
125
+ // For bottom position: start at axisBounds.y
126
+ // For top position with label: start at axisBounds.y + LABEL_SIZE
127
+ const baseY = position === 'top' && label ? axisBounds.y + LABEL_SIZE : axisBounds.y;
128
+ const labelY = position === 'top' ? baseY + labelOffset - tickOffset : baseY + labelOffset + tickOffset;
124
129
  return {
125
130
  x: tick.position,
126
131
  y: labelY,
127
132
  label: String(formatTick(tick.tick)),
128
133
  chartTextProps: {
129
- className: classNames == null ? void 0 : classNames.tickLabel,
130
134
  color: theme.color.fgMuted,
131
135
  verticalAlignment: 'middle',
132
- style: styles == null ? void 0 : styles.tickLabel,
133
136
  horizontalAlignment: 'center'
134
137
  }
135
138
  };
136
139
  });
137
- }, [axisBounds, ticksData, theme.color.fgMuted, tickMarkLabelGap, showTickMarks, tickMarkSize, position, formatTick, classNames == null ? void 0 : classNames.tickLabel, styles == null ? void 0 : styles.tickLabel]);
138
- const gridAnimatedStyle = useAnimatedStyle(() => ({
139
- opacity: gridOpacity.value
140
- }));
141
- if (!xScale) return;
142
- return /*#__PURE__*/_jsxs(G, _extends({
143
- "data-axis": "x",
144
- "data-position": position
145
- }, props, {
146
- children: [showGrid && /*#__PURE__*/_jsx(AnimatedG, {
147
- animatedProps: gridAnimatedStyle,
140
+ }, [axisBounds, ticksData, theme.color.fgMuted, tickMarkLabelGap, showTickMarks, tickMarkSize, position, formatTick, label]);
141
+ if (!xScale || !axisBounds) return;
142
+ const labelX = axisBounds.x + axisBounds.width / 2;
143
+ const labelY = position === 'bottom' ? axisBounds.y + axisBounds.height - LABEL_SIZE / 2 : axisBounds.y + LABEL_SIZE / 2;
144
+ return /*#__PURE__*/_jsxs(Group, {
145
+ children: [showGrid && /*#__PURE__*/_jsx(Group, {
148
146
  children: ticksData.map((tick, index) => {
149
147
  const verticalLine = /*#__PURE__*/_jsx(ReferenceLine, {
150
148
  LineComponent: GridLineComponent,
151
149
  dataX: tick.tick
152
150
  });
153
- return /*#__PURE__*/_jsx(G, {
151
+ return /*#__PURE__*/_jsx(Group, {
154
152
  children: verticalLine
155
153
  }, "grid-" + tick.tick + "-" + index);
156
154
  })
157
- }), chartTextData && /*#__PURE__*/_jsx(SmartChartTextGroup, {
155
+ }), chartTextData && /*#__PURE__*/_jsx(ChartTextGroup, {
158
156
  prioritizeEndLabels: true,
157
+ LabelComponent: TickLabelComponent,
159
158
  labels: chartTextData,
160
159
  minGap: minTickLabelGap
161
- }), axisBounds && showTickMarks && /*#__PURE__*/_jsx(G, {
162
- "data-testid": "tick-marks",
160
+ }), axisBounds && showTickMarks && /*#__PURE__*/_jsx(Group, {
163
161
  children: ticksData.map((tick, index) => {
164
162
  const tickY = position === 'bottom' ? axisBounds.y : axisBounds.y + axisBounds.height;
165
- const tickMarkSizePixels = tickMarkSize;
166
- const tickY2 = position === 'bottom' ? axisBounds.y + tickMarkSizePixels : axisBounds.y + axisBounds.height - tickMarkSizePixels;
167
- return /*#__PURE__*/_jsx(Line, _extends({}, axisTickMarkProps, {
168
- x1: tick.position,
169
- x2: tick.position,
170
- y1: tickY,
171
- y2: tickY2
172
- }), "tick-mark-" + tick.tick + "-" + index);
163
+ const tickY2 = position === 'bottom' ? axisBounds.y + tickMarkSize : axisBounds.y + axisBounds.height - tickMarkSize;
164
+ return /*#__PURE__*/_jsx(TickMarkLineComponent, {
165
+ animate: false,
166
+ clipPath: null,
167
+ d: lineToPath(tick.position, tickY, tick.position, tickY2),
168
+ stroke: theme.color.fg,
169
+ strokeCap: "square",
170
+ strokeWidth: 1
171
+ }, "tick-mark-" + tick.tick + "-" + index);
173
172
  })
174
- }), axisBounds && showLine && /*#__PURE__*/_jsx(Line, _extends({}, axisLineProps, {
175
- x1: axisBounds.x,
176
- x2: axisBounds.x + axisBounds.width,
177
- y1: position === 'bottom' ? axisBounds.y : axisBounds.y + axisBounds.height,
178
- y2: position === 'bottom' ? axisBounds.y : axisBounds.y + axisBounds.height
179
- }))]
180
- }));
173
+ }), showLine && /*#__PURE__*/_jsx(LineComponent, {
174
+ animate: false,
175
+ d: lineToPath(axisBounds.x, position === 'bottom' ? axisBounds.y : axisBounds.y + axisBounds.height, axisBounds.x + axisBounds.width, position === 'bottom' ? axisBounds.y : axisBounds.y + axisBounds.height),
176
+ stroke: theme.color.fg,
177
+ strokeCap: "square",
178
+ strokeWidth: 1
179
+ }), label && /*#__PURE__*/_jsx(ChartText, {
180
+ horizontalAlignment: "center",
181
+ verticalAlignment: "middle",
182
+ x: labelX,
183
+ y: labelY,
184
+ children: label
185
+ })]
186
+ });
181
187
  });
@@ -1,17 +1,19 @@
1
- const _excluded = ["axisId", "position", "showGrid", "requestedTickCount", "ticks", "tickLabelFormatter", "style", "className", "styles", "classNames", "GridLineComponent", "tickMarkLabelGap", "width", "minTickLabelGap", "showTickMarks", "showLine", "tickMarkSize", "tickInterval"];
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); }
1
+ const _excluded = ["axisId", "position", "showGrid", "requestedTickCount", "ticks", "tickLabelFormatter", "TickLabelComponent", "GridLineComponent", "LineComponent", "TickMarkLineComponent", "tickMarkLabelGap", "minTickLabelGap", "showTickMarks", "showLine", "tickMarkSize", "tickInterval", "label", "labelGap", "width"];
3
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; }
4
3
  import { memo, useCallback, useEffect, useId, useMemo } from 'react';
5
- import Animated, { useAnimatedStyle, useSharedValue } from 'react-native-reanimated';
6
- import { G, Line } from 'react-native-svg';
7
4
  import { useTheme } from '@coinbase/cds-mobile/hooks/useTheme';
5
+ import { Group, vec } from '@shopify/react-native-skia';
8
6
  import { useCartesianChartContext } from '../ChartProvider';
9
7
  import { DottedLine } from '../line/DottedLine';
10
8
  import { ReferenceLine } from '../line/ReferenceLine';
11
- import { SmartChartTextGroup } from '../text/SmartChartTextGroup';
12
- import { getAxisTicksData, isCategoricalScale } from '../utils';
9
+ import { SolidLine } from '../line/SolidLine';
10
+ import { ChartText } from '../text/ChartText';
11
+ import { ChartTextGroup } from '../text/ChartTextGroup';
12
+ import { getAxisTicksData, isCategoricalScale, lineToPath } from '../utils';
13
+ import { DefaultAxisTickLabel } from './DefaultAxisTickLabel';
13
14
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
14
- const AnimatedG = Animated.createAnimatedComponent(G);
15
+ const AXIS_WIDTH = 44;
16
+ const LABEL_SIZE = 20;
15
17
  export const YAxis = /*#__PURE__*/memo(_ref => {
16
18
  let {
17
19
  axisId,
@@ -20,16 +22,19 @@ export const YAxis = /*#__PURE__*/memo(_ref => {
20
22
  requestedTickCount = 5,
21
23
  ticks,
22
24
  tickLabelFormatter,
23
- styles,
24
- classNames,
25
+ TickLabelComponent = DefaultAxisTickLabel,
25
26
  GridLineComponent = DottedLine,
27
+ LineComponent = SolidLine,
28
+ TickMarkLineComponent = SolidLine,
26
29
  tickMarkLabelGap = 8,
27
- width = 44,
28
30
  minTickLabelGap = 0,
29
31
  showTickMarks,
30
32
  showLine,
31
33
  tickMarkSize = 4,
32
- tickInterval
34
+ tickInterval,
35
+ label,
36
+ labelGap = 4,
37
+ width = label ? AXIS_WIDTH + LABEL_SIZE : AXIS_WIDTH
33
38
  } = _ref,
34
39
  props = _objectWithoutPropertiesLoose(_ref, _excluded);
35
40
  const theme = useTheme();
@@ -45,17 +50,10 @@ export const YAxis = /*#__PURE__*/memo(_ref => {
45
50
  const yScale = getYScale(axisId);
46
51
  const yAxis = getYAxis(axisId);
47
52
  const axisBounds = getAxisBounds(registrationId);
48
- const gridOpacity = useSharedValue(1);
49
- const axisLineProps = useMemo(() => ({
50
- stroke: theme.color.fg,
51
- strokeLinecap: 'square',
52
- strokeWidth: 1
53
- }), [theme.color.fg]);
54
- const axisTickMarkProps = useMemo(() => ({
55
- stroke: theme.color.fg,
56
- strokeLinecap: 'square',
57
- strokeWidth: 1
58
- }), [theme.color.fg]);
53
+
54
+ // Note: gridOpacity not currently used in Skia version
55
+ // const gridOpacity = useSharedValue(1);
56
+
59
57
  useEffect(() => {
60
58
  registerAxis(registrationId, position, width);
61
59
  return () => unregisterAxis(registrationId);
@@ -114,57 +112,65 @@ export const YAxis = /*#__PURE__*/memo(_ref => {
114
112
  y: tick.position,
115
113
  label: String(formatTick(tick.tick)),
116
114
  chartTextProps: {
117
- className: classNames == null ? void 0 : classNames.tickLabel,
118
115
  color: theme.color.fgMuted,
119
116
  verticalAlignment: 'middle',
120
- style: styles == null ? void 0 : styles.tickLabel,
121
117
  horizontalAlignment: position === 'left' ? 'right' : 'left'
122
118
  }
123
119
  };
124
120
  });
125
- }, [axisBounds, ticksData, theme.color.fgMuted, tickMarkLabelGap, showTickMarks, tickMarkSize, position, formatTick, classNames == null ? void 0 : classNames.tickLabel, styles == null ? void 0 : styles.tickLabel]);
126
- const gridAnimatedStyle = useAnimatedStyle(() => ({
127
- opacity: gridOpacity.value
128
- }));
129
- if (!yScale) return;
130
- return /*#__PURE__*/_jsxs(G, _extends({
131
- "data-axis": "y",
132
- "data-position": position
133
- }, props, {
134
- children: [showGrid && /*#__PURE__*/_jsx(AnimatedG, {
135
- animatedProps: gridAnimatedStyle,
121
+ }, [axisBounds, ticksData, tickMarkLabelGap, showTickMarks, tickMarkSize, position, formatTick, theme.color.fgMuted]);
122
+ if (!yScale || !axisBounds) return;
123
+ const labelX = position === 'left' ? axisBounds.x + LABEL_SIZE / 2 : axisBounds.x + axisBounds.width - LABEL_SIZE / 2;
124
+ const labelY = axisBounds.y + axisBounds.height / 2;
125
+ return /*#__PURE__*/_jsxs(Group, {
126
+ children: [showGrid && /*#__PURE__*/_jsx(Group, {
136
127
  children: ticksData.map((tick, index) => {
137
128
  const horizontalLine = /*#__PURE__*/_jsx(ReferenceLine, {
138
129
  LineComponent: GridLineComponent,
139
130
  dataY: tick.tick,
140
131
  yAxisId: axisId
141
132
  });
142
- return /*#__PURE__*/_jsx(G, {
133
+ return /*#__PURE__*/_jsx(Group, {
143
134
  children: horizontalLine
144
135
  }, "grid-" + tick.tick + "-" + index);
145
136
  })
146
- }), chartTextData && /*#__PURE__*/_jsx(SmartChartTextGroup, {
137
+ }), chartTextData && /*#__PURE__*/_jsx(ChartTextGroup, {
147
138
  prioritizeEndLabels: true,
139
+ LabelComponent: TickLabelComponent,
148
140
  labels: chartTextData,
149
141
  minGap: minTickLabelGap
150
- }), axisBounds && showTickMarks && /*#__PURE__*/_jsx(G, {
151
- "data-testid": "tick-marks",
142
+ }), axisBounds && showTickMarks && /*#__PURE__*/_jsx(Group, {
152
143
  children: ticksData.map((tick, index) => {
153
144
  const tickX = position === 'left' ? axisBounds.x + axisBounds.width : axisBounds.x;
154
145
  const tickMarkSizePixels = tickMarkSize;
155
146
  const tickX2 = position === 'left' ? axisBounds.x + axisBounds.width - tickMarkSizePixels : axisBounds.x + tickMarkSizePixels;
156
- return /*#__PURE__*/_jsx(Line, _extends({}, axisTickMarkProps, {
157
- x1: tickX,
158
- x2: tickX2,
159
- y1: tick.position,
160
- y2: tick.position
161
- }), "tick-mark-" + tick.tick + "-" + index);
147
+ return /*#__PURE__*/_jsx(TickMarkLineComponent, {
148
+ animate: false,
149
+ clipPath: null,
150
+ d: lineToPath(tickX, tick.position, tickX2, tick.position),
151
+ stroke: theme.color.fg,
152
+ strokeCap: "square",
153
+ strokeWidth: 1
154
+ }, "tick-mark-" + tick.tick + "-" + index);
155
+ })
156
+ }), showLine && /*#__PURE__*/_jsx(LineComponent, {
157
+ animate: false,
158
+ d: lineToPath(position === 'left' ? axisBounds.x + axisBounds.width : axisBounds.x, axisBounds.y, position === 'left' ? axisBounds.x + axisBounds.width : axisBounds.x, axisBounds.y + axisBounds.height),
159
+ stroke: theme.color.fg,
160
+ strokeCap: "square",
161
+ strokeWidth: 1
162
+ }), label && /*#__PURE__*/_jsx(Group, {
163
+ origin: vec(labelX, labelY),
164
+ transform: [{
165
+ rotate: position === 'left' ? -Math.PI / 2 : Math.PI / 2
166
+ }],
167
+ children: /*#__PURE__*/_jsx(ChartText, {
168
+ horizontalAlignment: "center",
169
+ verticalAlignment: "middle",
170
+ x: labelX,
171
+ y: labelY,
172
+ children: label
162
173
  })
163
- }), axisBounds && showLine && /*#__PURE__*/_jsx(Line, _extends({}, axisLineProps, {
164
- x1: position === 'left' ? axisBounds.x + axisBounds.width : axisBounds.x,
165
- x2: position === 'left' ? axisBounds.x + axisBounds.width : axisBounds.x,
166
- y1: axisBounds.y,
167
- y2: axisBounds.y + axisBounds.height
168
- }))]
169
- }));
174
+ })]
175
+ });
170
176
  });
@@ -118,7 +118,6 @@ const TimeOfDayAxesExample = () => {
118
118
  }, [timeData]);
119
119
  return /*#__PURE__*/_jsxs(LineChart, {
120
120
  enableScrubbing: true,
121
- curve: "monotone",
122
121
  height: defaultChartHeight,
123
122
  series: [{
124
123
  id: 'lineA',
@@ -1,5 +1,6 @@
1
1
  // codegen:start {preset: barrel, include: ./*.tsx, exclude: ./__stories__/*.tsx}
2
2
  export * from './Axis';
3
+ export * from './DefaultAxisTickLabel';
3
4
  export * from './XAxis';
4
5
  export * from './YAxis';
5
6
  // codegen:end
@@ -31,7 +31,8 @@ export const Bar = /*#__PURE__*/memo(_ref => {
31
31
  strokeWidth,
32
32
  borderRadius = 4,
33
33
  roundTop = true,
34
- roundBottom = true
34
+ roundBottom = true,
35
+ transition
35
36
  } = _ref;
36
37
  const theme = useTheme();
37
38
 
@@ -60,6 +61,7 @@ export const Bar = /*#__PURE__*/memo(_ref => {
60
61
  roundTop: roundTop,
61
62
  stroke: stroke,
62
63
  strokeWidth: strokeWidth,
64
+ transition: transition,
63
65
  width: width,
64
66
  x: x,
65
67
  y: y
@@ -1,4 +1,4 @@
1
- const _excluded = ["series", "stacked", "showXAxis", "showYAxis", "xAxis", "yAxis", "inset", "children", "barPadding", "BarComponent", "fillOpacity", "stroke", "strokeWidth", "borderRadius", "roundBaseline", "BarStackComponent", "stackGap", "barMinSize", "stackMinSize"],
1
+ const _excluded = ["series", "stacked", "showXAxis", "showYAxis", "xAxis", "yAxis", "inset", "children", "barPadding", "BarComponent", "fillOpacity", "stroke", "strokeWidth", "borderRadius", "roundBaseline", "BarStackComponent", "stackGap", "barMinSize", "stackMinSize", "transition"],
2
2
  _excluded2 = ["scaleType", "data", "categoryPadding", "domain", "domainLimit", "range"],
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); }
@@ -8,11 +8,6 @@ import { XAxis, YAxis } from '../axis';
8
8
  import { CartesianChart } from '../CartesianChart';
9
9
  import { defaultChartInset, defaultStackId, getChartInset } from '../utils';
10
10
  import { BarPlot } from './BarPlot';
11
-
12
- /**
13
- * Series type specifically for bar charts - supports both single numbers and tuples,
14
- * and allows individual customization of Bar props per series.
15
- */
16
11
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
17
12
  export const BarChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) => {
18
13
  let {
@@ -22,7 +17,7 @@ export const BarChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) =>
22
17
  showYAxis,
23
18
  xAxis,
24
19
  yAxis,
25
- inset: userInset,
20
+ inset,
26
21
  children,
27
22
  barPadding,
28
23
  BarComponent,
@@ -34,44 +29,26 @@ export const BarChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) =>
34
29
  BarStackComponent,
35
30
  stackGap,
36
31
  barMinSize,
37
- stackMinSize
32
+ stackMinSize,
33
+ transition
38
34
  } = _ref,
39
35
  chartProps = _objectWithoutPropertiesLoose(_ref, _excluded);
40
- const calculatedInset = useMemo(() => getChartInset(userInset, defaultChartInset), [userInset]);
41
-
42
- // Convert BarSeries to Series for Chart context
43
- const chartSeries = useMemo(() => {
44
- return series == null ? void 0 : series.map(s => ({
45
- id: s.id,
46
- data: s.data,
47
- label: s.label,
48
- color: s.color,
49
- yAxisId: s.yAxisId,
50
- stackId: s.stackId
51
- }));
52
- }, [series]);
36
+ const calculatedInset = useMemo(() => getChartInset(inset, defaultChartInset), [inset]);
53
37
  const transformedSeries = useMemo(() => {
54
- if (!stacked || !chartSeries) return chartSeries;
55
- return chartSeries.map(s => {
56
- var _s$stackId;
57
- return _extends({}, s, {
58
- stackId: (_s$stackId = s.stackId) != null ? _s$stackId : defaultStackId
59
- });
60
- });
61
- }, [chartSeries, stacked]);
62
- const seriesToRender = transformedSeries != null ? transformedSeries : chartSeries;
63
-
64
- // Keep the original series with bar-specific props for BarPlot
65
- const barSeriesToRender = useMemo(() => {
66
38
  if (!stacked || !series) return series;
67
39
  return series.map(s => {
68
- var _s$stackId2;
40
+ var _s$stackId;
69
41
  return _extends({}, s, {
70
- stackId: (_s$stackId2 = s.stackId) != null ? _s$stackId2 : defaultStackId
42
+ stackId: (_s$stackId = s.stackId) != null ? _s$stackId : defaultStackId
71
43
  });
72
44
  });
73
45
  }, [series, stacked]);
74
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);
51
+
75
52
  // Split axis props into config props for Chart and visual props for axis components
76
53
  const _ref2 = xAxis || {},
77
54
  {
@@ -137,11 +114,12 @@ export const BarChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) =>
137
114
  borderRadius: borderRadius,
138
115
  fillOpacity: fillOpacity,
139
116
  roundBaseline: roundBaseline,
140
- seriesIds: barSeriesToRender == null ? void 0 : barSeriesToRender.map(s => s.id),
117
+ seriesIds: seriesIds,
141
118
  stackGap: stackGap,
142
119
  stackMinSize: stackMinSize,
143
120
  stroke: stroke,
144
- strokeWidth: strokeWidth
121
+ strokeWidth: strokeWidth,
122
+ transition: transition
145
123
  }), children]
146
124
  }));
147
125
  }));
@@ -1,9 +1,9 @@
1
1
  import { memo, useId, useMemo } from 'react';
2
- import { ClipPath, Defs, G, Rect } from 'react-native-svg';
2
+ import { Group, Skia } from '@shopify/react-native-skia';
3
3
  import { useCartesianChartContext } from '../ChartProvider';
4
4
  import { defaultAxisId } from '../utils';
5
5
  import { BarStackGroup } from './BarStackGroup';
6
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
6
+ import { jsx as _jsx } from "react/jsx-runtime";
7
7
  /**
8
8
  * BarPlot component that handles multiple series with proper stacking coordination.
9
9
  * Groups series by stack ID + y-axis ID combination and renders BarStackGroup for each group.
@@ -23,7 +23,8 @@ export const BarPlot = /*#__PURE__*/memo(_ref => {
23
23
  BarStackComponent,
24
24
  stackGap,
25
25
  barMinSize,
26
- stackMinSize
26
+ stackMinSize,
27
+ transition
27
28
  } = _ref;
28
29
  const {
29
30
  series: allSeries,
@@ -58,39 +59,44 @@ export const BarPlot = /*#__PURE__*/memo(_ref => {
58
59
  });
59
60
  return Array.from(groups.values());
60
61
  }, [targetSeries]);
61
- if (!drawingArea) {
62
+
63
+ // Create clip path for the entire chart area (shared by all bars)
64
+ const clipPath = useMemo(() => {
65
+ if (!drawingArea) return null;
66
+ const clip = Skia.Path.Make();
67
+ clip.addRect({
68
+ x: drawingArea.x,
69
+ y: drawingArea.y,
70
+ width: drawingArea.width,
71
+ height: drawingArea.height
72
+ });
73
+ return clip;
74
+ }, [drawingArea]);
75
+ if (!clipPath) {
62
76
  return null;
63
77
  }
64
- return /*#__PURE__*/_jsxs(_Fragment, {
65
- children: [/*#__PURE__*/_jsx(Defs, {
66
- children: /*#__PURE__*/_jsx(ClipPath, {
67
- id: clipPathId,
68
- children: /*#__PURE__*/_jsx(Rect, {
69
- height: drawingArea.height,
70
- width: drawingArea.width,
71
- x: drawingArea.x,
72
- y: drawingArea.y
73
- })
74
- })
75
- }), /*#__PURE__*/_jsx(G, {
76
- clipPath: "url(#" + clipPathId + ")",
77
- children: stackGroups.map((group, stackIndex) => /*#__PURE__*/_jsx(BarStackGroup, {
78
- BarComponent: defaultBarComponent,
79
- BarStackComponent: BarStackComponent,
80
- barMinSize: barMinSize,
81
- barPadding: barPadding,
82
- borderRadius: defaultBorderRadius,
83
- fillOpacity: defaultFillOpacity,
84
- roundBaseline: roundBaseline,
85
- series: group.series,
86
- stackGap: stackGap,
87
- stackIndex: stackIndex,
88
- stackMinSize: stackMinSize,
89
- stroke: defaultStroke,
90
- strokeWidth: defaultStrokeWidth,
91
- totalStacks: stackGroups.length,
92
- yAxisId: group.yAxisId
93
- }, group.stackId))
94
- })]
78
+
79
+ // Note: Clipping is now handled here at the BarPlot level (one clip path for all bars!)
80
+ // This is much more efficient than creating a clip path for each individual bar
81
+ return /*#__PURE__*/_jsx(Group, {
82
+ clip: clipPath,
83
+ children: stackGroups.map((group, stackIndex) => /*#__PURE__*/_jsx(BarStackGroup, {
84
+ BarComponent: defaultBarComponent,
85
+ BarStackComponent: BarStackComponent,
86
+ barMinSize: barMinSize,
87
+ barPadding: barPadding,
88
+ borderRadius: defaultBorderRadius,
89
+ fillOpacity: defaultFillOpacity,
90
+ roundBaseline: roundBaseline,
91
+ series: group.series,
92
+ stackGap: stackGap,
93
+ stackIndex: stackIndex,
94
+ stackMinSize: stackMinSize,
95
+ stroke: defaultStroke,
96
+ strokeWidth: defaultStrokeWidth,
97
+ totalStacks: stackGroups.length,
98
+ transition: transition,
99
+ yAxisId: group.yAxisId
100
+ }, group.stackId))
95
101
  });
96
102
  });