@coinbase/cds-mobile-visualization 3.4.0-beta.1 → 3.4.0-beta.10

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 (184) hide show
  1. package/CHANGELOG.md +54 -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 +2 -2
  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 +198 -113
  112. package/esm/chart/PeriodSelector.js +2 -2
  113. package/esm/chart/__stories__/CartesianChart.stories.js +378 -131
  114. package/esm/chart/__stories__/Chart.stories.js +2 -4
  115. package/esm/chart/__stories__/PeriodSelector.stories.js +103 -75
  116. package/esm/chart/area/Area.js +25 -35
  117. package/esm/chart/area/AreaChart.js +17 -12
  118. package/esm/chart/area/DottedArea.js +61 -109
  119. package/esm/chart/area/GradientArea.js +35 -91
  120. package/esm/chart/area/SolidArea.js +22 -8
  121. package/esm/chart/area/__stories__/AreaChart.stories.js +1 -1
  122. package/esm/chart/axis/Axis.js +2 -0
  123. package/esm/chart/axis/DefaultAxisTickLabel.js +11 -0
  124. package/esm/chart/axis/XAxis.js +63 -56
  125. package/esm/chart/axis/YAxis.js +59 -52
  126. package/esm/chart/axis/__stories__/Axis.stories.js +0 -1
  127. package/esm/chart/axis/index.js +1 -0
  128. package/esm/chart/bar/Bar.js +3 -1
  129. package/esm/chart/bar/BarChart.js +15 -37
  130. package/esm/chart/bar/BarPlot.js +41 -35
  131. package/esm/chart/bar/BarStack.js +75 -38
  132. package/esm/chart/bar/BarStackGroup.js +6 -16
  133. package/esm/chart/bar/DefaultBar.js +26 -48
  134. package/esm/chart/bar/DefaultBarStack.js +23 -58
  135. package/esm/chart/bar/__stories__/BarChart.stories.js +463 -77
  136. package/esm/chart/gradient/Gradient.js +53 -0
  137. package/esm/chart/gradient/index.js +1 -0
  138. package/esm/chart/index.js +3 -1
  139. package/esm/chart/line/DefaultReferenceLineLabel.js +66 -0
  140. package/esm/chart/line/DottedLine.js +29 -14
  141. package/esm/chart/line/Line.js +106 -67
  142. package/esm/chart/line/LineChart.js +20 -14
  143. package/esm/chart/line/ReferenceLine.js +80 -63
  144. package/esm/chart/line/SolidLine.js +25 -10
  145. package/esm/chart/line/__stories__/LineChart.stories.js +2101 -1977
  146. package/esm/chart/line/__stories__/ReferenceLine.stories.js +83 -28
  147. package/esm/chart/line/index.js +1 -1
  148. package/esm/chart/point/DefaultPointLabel.js +39 -0
  149. package/esm/chart/point/Point.js +188 -0
  150. package/esm/chart/point/index.js +2 -0
  151. package/esm/chart/scrubber/DefaultScrubberBeacon.js +179 -0
  152. package/esm/chart/scrubber/DefaultScrubberBeaconLabel.js +43 -0
  153. package/esm/chart/scrubber/DefaultScrubberLabel.js +28 -0
  154. package/esm/chart/scrubber/Scrubber.js +126 -146
  155. package/esm/chart/scrubber/ScrubberBeaconGroup.js +161 -0
  156. package/esm/chart/scrubber/ScrubberBeaconLabelGroup.js +185 -0
  157. package/esm/chart/scrubber/ScrubberProvider.js +46 -54
  158. package/esm/chart/scrubber/index.js +3 -1
  159. package/esm/chart/text/ChartText.js +242 -174
  160. package/esm/chart/text/{SmartChartTextGroup.js → ChartTextGroup.js} +6 -5
  161. package/esm/chart/text/index.js +1 -1
  162. package/esm/chart/utils/chart.js +44 -3
  163. package/esm/chart/utils/gradient.js +305 -0
  164. package/esm/chart/utils/index.js +3 -0
  165. package/esm/chart/utils/path.js +76 -8
  166. package/esm/chart/utils/point.js +116 -5
  167. package/esm/chart/utils/scale.js +230 -1
  168. package/esm/chart/utils/scrubber.js +139 -0
  169. package/esm/chart/utils/transition.js +185 -0
  170. package/esm/sparkline/__stories__/Sparkline.stories.js +11 -7
  171. package/esm/sparkline/__stories__/SparklineGradient.stories.js +7 -4
  172. package/esm/sparkline/sparkline-interactive/__stories__/SparklineInteractive.stories.js +51 -26
  173. package/esm/sparkline/sparkline-interactive-header/__stories__/SparklineInteractiveHeader.stories.js +17 -9
  174. package/package.json +15 -9
  175. package/dts/chart/Point.d.ts +0 -103
  176. package/dts/chart/Point.d.ts.map +0 -1
  177. package/dts/chart/line/GradientLine.d.ts +0 -45
  178. package/dts/chart/line/GradientLine.d.ts.map +0 -1
  179. package/dts/chart/scrubber/ScrubberBeacon.d.ts +0 -75
  180. package/dts/chart/scrubber/ScrubberBeacon.d.ts.map +0 -1
  181. package/dts/chart/text/SmartChartTextGroup.d.ts.map +0 -1
  182. package/esm/chart/Point.js +0 -111
  183. package/esm/chart/line/GradientLine.js +0 -62
  184. package/esm/chart/scrubber/ScrubberBeacon.js +0 -199
@@ -0,0 +1,66 @@
1
+ const _excluded = ["color", "elevated", "borderRadius", "inset", "boundsInset"];
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
+ 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
+ import { memo, useMemo } from 'react';
5
+ import { useTheme } from '@coinbase/cds-mobile';
6
+ import { useCartesianChartContext } from '../ChartProvider';
7
+ import { ChartText } from '../text';
8
+ import { getChartInset } from '../utils';
9
+ import { jsx as _jsx } from "react/jsx-runtime";
10
+ const elevatedInset = {
11
+ top: 8,
12
+ bottom: 8,
13
+ left: 12,
14
+ right: 12
15
+ };
16
+ const elevatedBorderRadius = 4;
17
+ // Default bounds inset when elevated to prevent shadow clipping
18
+ const elevatedBoundsInset = {
19
+ top: 4,
20
+ bottom: 20,
21
+ left: 12,
22
+ right: 12
23
+ };
24
+ const nonElevatedBoundsInset = {
25
+ top: 0,
26
+ bottom: 0,
27
+ left: 0,
28
+ right: 0
29
+ };
30
+
31
+ /**
32
+ * DefaultReferenceLineLabel is the default label component for ReferenceLine.
33
+ * Provides standard styling with elevation, inset, and color defaults.
34
+ * When elevated, automatically adds bounds to prevent shadow cutoff at chart edges.
35
+ */
36
+ export const DefaultReferenceLineLabel = /*#__PURE__*/memo(_ref => {
37
+ let {
38
+ color,
39
+ elevated,
40
+ borderRadius = elevated ? elevatedBorderRadius : undefined,
41
+ inset = elevated ? elevatedInset : undefined,
42
+ boundsInset: boundsInsetProp
43
+ } = _ref,
44
+ props = _objectWithoutPropertiesLoose(_ref, _excluded);
45
+ const theme = useTheme();
46
+ const {
47
+ width: chartWidth,
48
+ height: chartHeight
49
+ } = useCartesianChartContext();
50
+ const bounds = useMemo(() => {
51
+ const boundsInset = getChartInset(boundsInsetProp, elevated ? elevatedBoundsInset : nonElevatedBoundsInset);
52
+ return {
53
+ x: boundsInset.left,
54
+ y: boundsInset.top,
55
+ width: chartWidth - boundsInset.left - boundsInset.right,
56
+ height: chartHeight - boundsInset.top - boundsInset.bottom
57
+ };
58
+ }, [elevated, boundsInsetProp, chartWidth, chartHeight]);
59
+ return /*#__PURE__*/_jsx(ChartText, _extends({
60
+ borderRadius: borderRadius,
61
+ bounds: bounds,
62
+ color: color != null ? color : theme.color.fgMuted,
63
+ elevated: elevated,
64
+ inset: inset
65
+ }, props));
66
+ });
@@ -1,35 +1,50 @@
1
- const _excluded = ["fill", "stroke", "strokeDasharray", "strokeLinecap", "strokeLinejoin", "strokeOpacity", "strokeWidth", "vectorEffect"];
1
+ const _excluded = ["fill", "stroke", "dashIntervals", "strokeCap", "strokeJoin", "strokeOpacity", "strokeWidth", "gradient", "yAxisId", "d", "animate", "transition"];
2
2
  function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
3
3
  function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
4
4
  import { memo } from 'react';
5
5
  import { useTheme } from '@coinbase/cds-mobile/hooks/useTheme';
6
+ import { DashPathEffect } from '@shopify/react-native-skia';
7
+ import { Gradient } from '../gradient';
6
8
  import { Path } from '../Path';
7
- import { jsx as _jsx } from "react/jsx-runtime";
9
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
8
10
  /**
9
- * A customizable dotted line component which uses path element.
11
+ * A customizable dotted line component.
12
+ * Supports gradient for gradient effects on the dots and smooth data transitions via AnimatedPath.
10
13
  */
11
14
  export const DottedLine = /*#__PURE__*/memo(_ref => {
12
15
  let {
13
16
  fill = 'none',
14
17
  stroke,
15
- strokeDasharray = '0 4',
16
- strokeLinecap = 'round',
17
- strokeLinejoin = 'round',
18
+ dashIntervals = [0, 4],
19
+ strokeCap = 'round',
20
+ strokeJoin = 'round',
18
21
  strokeOpacity = 1,
19
22
  strokeWidth = 2,
20
- vectorEffect = 'non-scaling-stroke'
23
+ gradient,
24
+ yAxisId,
25
+ d,
26
+ animate,
27
+ transition
21
28
  } = _ref,
22
29
  props = _objectWithoutPropertiesLoose(_ref, _excluded);
23
30
  const theme = useTheme();
24
- return /*#__PURE__*/_jsx(Path, _extends({
31
+ return /*#__PURE__*/_jsxs(Path, _extends({
32
+ animate: animate,
25
33
  clipOffset: strokeWidth,
34
+ d: d,
26
35
  fill: fill,
27
- stroke: stroke != null ? stroke : theme.color.bgLine,
28
- strokeDasharray: strokeDasharray,
29
- strokeLinecap: strokeLinecap,
30
- strokeLinejoin: strokeLinejoin,
36
+ stroke: stroke != null ? stroke : theme.color.fgPrimary,
37
+ strokeCap: strokeCap,
38
+ strokeJoin: strokeJoin,
31
39
  strokeOpacity: strokeOpacity,
32
40
  strokeWidth: strokeWidth,
33
- vectorEffect: vectorEffect
34
- }, props));
41
+ transition: transition
42
+ }, props, {
43
+ children: [/*#__PURE__*/_jsx(DashPathEffect, {
44
+ intervals: dashIntervals
45
+ }), gradient && /*#__PURE__*/_jsx(Gradient, {
46
+ gradient: gradient,
47
+ yAxisId: yAxisId
48
+ })]
49
+ }));
35
50
  });
@@ -1,70 +1,69 @@
1
- const _excluded = ["seriesId", "curve", "type", "areaType", "areaBaseline", "stroke", "showArea", "LineComponent", "AreaComponent", "opacity", "renderPoints"];
1
+ const _excluded = ["seriesId", "curve", "type", "areaType", "areaBaseline", "stroke", "strokeOpacity", "showArea", "LineComponent", "AreaComponent", "opacity", "points", "connectNulls", "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
- import React, { memo, useMemo } from 'react';
5
- import { useTheme } from '@coinbase/cds-mobile/hooks/useTheme';
4
+ import React, { memo, useEffect, useMemo } from 'react';
5
+ import { useSharedValue, withDelay, withTiming } from 'react-native-reanimated';
6
+ import { useTheme } from '@coinbase/cds-mobile';
7
+ import { Group } from '@shopify/react-native-skia';
6
8
  import { Area } from '../area/Area';
7
9
  import { useCartesianChartContext } from '../ChartProvider';
8
- import { Point } from '../Point';
9
- import { getLinePath } from '../utils';
10
+ import { Point } from '../point';
11
+ import { accessoryFadeTransitionDelay, accessoryFadeTransitionDuration, getLineData, getLinePath } from '../utils';
12
+ import { evaluateGradientAtValue, getGradientStops } from '../utils/gradient';
13
+ import { convertToSerializableScale } from '../utils/scale';
10
14
  import { DottedLine } from './DottedLine';
11
- import { GradientLine } from './GradientLine';
12
15
  import { SolidLine } from './SolidLine';
13
16
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
14
17
  export const Line = /*#__PURE__*/memo(_ref => {
15
18
  var _ref2;
16
19
  let {
17
20
  seriesId,
18
- curve = 'linear',
21
+ curve = 'bump',
19
22
  type = 'solid',
20
23
  areaType = 'gradient',
21
24
  areaBaseline,
22
- stroke: specifiedStroke,
23
- showArea = false,
25
+ stroke: strokeProp,
26
+ strokeOpacity,
27
+ showArea,
24
28
  LineComponent: SelectedLineComponent,
25
29
  AreaComponent,
26
30
  opacity = 1,
27
- renderPoints
31
+ points,
32
+ connectNulls,
33
+ transition,
34
+ gradient: gradientProp
28
35
  } = _ref,
29
36
  props = _objectWithoutPropertiesLoose(_ref, _excluded);
30
37
  const theme = useTheme();
31
38
  const {
39
+ animate,
32
40
  getSeries,
33
41
  getSeriesData,
34
42
  getXScale,
35
43
  getYScale,
36
44
  getXAxis
37
45
  } = useCartesianChartContext();
38
- const matchedSeries = getSeries(seriesId);
39
- const sourceData = useMemo(() => {
40
- return getSeriesData(seriesId) || null;
41
- }, [seriesId, getSeriesData]);
42
- const xAxis = getXAxis();
43
- const xScale = getXScale();
44
- const yScale = getYScale(matchedSeries == null ? void 0 : matchedSeries.yAxisId);
45
46
 
46
- // Convert sourceData to number array (line only supports numbers, not tuples)
47
- // If data is stacked (tuples), extract the actual values from [baseline, actualValue] format
48
- const chartData = useMemo(() => {
49
- if (!sourceData) return [];
47
+ // Animation state for delayed point rendering (matches web timing)
48
+ const pointsOpacity = useSharedValue(animate ? 0 : 1);
50
49
 
51
- // Check if this is stacked data (array of tuples)
52
- const firstNonNull = sourceData.find(d => d !== null);
53
- if (Array.isArray(firstNonNull)) {
54
- // Extract actual values from [baseline, value] tuples
55
- return sourceData.map(d => {
56
- if (d === null) return null;
57
- if (Array.isArray(d)) return d[1];
58
- return d;
59
- });
50
+ // Delay point appearance until after path enter animation completes
51
+ useEffect(() => {
52
+ if (animate) {
53
+ pointsOpacity.value = withDelay(accessoryFadeTransitionDelay, withTiming(1, {
54
+ duration: accessoryFadeTransitionDuration
55
+ }));
60
56
  }
57
+ }, [animate, pointsOpacity]);
58
+ const matchedSeries = useMemo(() => getSeries(seriesId), [getSeries, seriesId]);
59
+ const gradient = useMemo(() => gradientProp != null ? gradientProp : matchedSeries == null ? void 0 : matchedSeries.gradient, [gradientProp, matchedSeries == null ? void 0 : matchedSeries.gradient]);
60
+ const sourceData = useMemo(() => getSeriesData(seriesId), [getSeriesData, seriesId]);
61
+ const xAxis = useMemo(() => getXAxis(), [getXAxis]);
62
+ const xScale = useMemo(() => getXScale(), [getXScale]);
63
+ const yScale = useMemo(() => getYScale(matchedSeries == null ? void 0 : matchedSeries.yAxisId), [getYScale, matchedSeries == null ? void 0 : matchedSeries.yAxisId]);
61
64
 
62
- // Regular number array
63
- if (sourceData.every(d => typeof d === 'number' || d === null)) {
64
- return sourceData;
65
- }
66
- return [];
67
- }, [sourceData]);
65
+ // Convert sourceData to number array (line only supports numbers, not tuples)
66
+ const chartData = useMemo(() => getLineData(sourceData), [sourceData]);
68
67
  const path = useMemo(() => {
69
68
  if (!xScale || !yScale || chartData.length === 0) return '';
70
69
 
@@ -75,9 +74,10 @@ export const Line = /*#__PURE__*/memo(_ref => {
75
74
  xScale,
76
75
  yScale,
77
76
  curve,
78
- xData
77
+ xData,
78
+ connectNulls
79
79
  });
80
- }, [chartData, xScale, yScale, curve, xAxis == null ? void 0 : xAxis.data]);
80
+ }, [chartData, xScale, yScale, curve, xAxis == null ? void 0 : xAxis.data, connectNulls]);
81
81
  const LineComponent = useMemo(() => {
82
82
  if (SelectedLineComponent) {
83
83
  return SelectedLineComponent;
@@ -85,55 +85,94 @@ export const Line = /*#__PURE__*/memo(_ref => {
85
85
  switch (type) {
86
86
  case 'dotted':
87
87
  return DottedLine;
88
- case 'gradient':
89
- return GradientLine;
90
- case 'solid':
91
88
  default:
92
89
  return SolidLine;
93
90
  }
94
91
  }, [SelectedLineComponent, type]);
95
- const stroke = (_ref2 = specifiedStroke != null ? specifiedStroke : matchedSeries == null ? void 0 : matchedSeries.color) != null ? _ref2 : theme.color.fgPrimary;
92
+
93
+ // Get series color for stroke
94
+ const stroke = (_ref2 = strokeProp != null ? strokeProp : matchedSeries == null ? void 0 : matchedSeries.color) != null ? _ref2 : theme.color.fgPrimary;
96
95
  const xData = useMemo(() => {
97
96
  const data = xAxis == null ? void 0 : xAxis.data;
98
97
  return data && Array.isArray(data) && data.length > 0 && typeof data[0] === 'number' ? data : null;
99
98
  }, [xAxis == null ? void 0 : xAxis.data]);
100
- if (!xScale || !yScale) return;
99
+ const gradientConfig = useMemo(() => {
100
+ if (!gradient || !xScale || !yScale) return;
101
+ const gradientScale = gradient.axis === 'x' ? xScale : yScale;
102
+ const serializableScale = convertToSerializableScale(gradientScale);
103
+ if (!serializableScale) return;
104
+ const domain = {
105
+ min: serializableScale.domain[0],
106
+ max: serializableScale.domain[1]
107
+ };
108
+ const stops = getGradientStops(gradient.stops, domain);
109
+ return {
110
+ scale: serializableScale,
111
+ stops
112
+ };
113
+ }, [gradient, xScale, yScale]);
114
+ if (!xScale || !yScale || !path) return;
101
115
  return /*#__PURE__*/_jsxs(_Fragment, {
102
116
  children: [showArea && /*#__PURE__*/_jsx(Area, {
103
117
  AreaComponent: AreaComponent,
104
118
  baseline: areaBaseline,
119
+ connectNulls: connectNulls,
105
120
  curve: curve,
106
121
  fill: stroke,
107
122
  fillOpacity: opacity,
123
+ gradient: gradient,
108
124
  seriesId: seriesId,
125
+ transition: transition,
109
126
  type: areaType
110
127
  }), /*#__PURE__*/_jsx(LineComponent, _extends({
111
128
  d: path,
129
+ gradient: gradient,
112
130
  stroke: stroke,
113
- strokeOpacity: opacity
114
- }, props)), renderPoints && chartData.map((value, index) => {
115
- var _xScale, _yScale, _pointConfig$fill, _pointConfig$opacity;
116
- if (value === null) {
117
- return null;
118
- }
119
- const xValue = xData && xData[index] !== undefined ? xData[index] : index;
120
- const pointResult = renderPoints({
121
- dataY: value,
122
- dataX: xValue,
123
- x: (_xScale = xScale == null ? void 0 : xScale(xValue)) != null ? _xScale : 0,
124
- y: (_yScale = yScale == null ? void 0 : yScale(value)) != null ? _yScale : 0
125
- });
126
- if (pointResult === false || pointResult === null || pointResult === undefined) {
127
- return null;
128
- }
129
- const pointConfig = pointResult === true ? {} : pointResult;
130
- return /*#__PURE__*/_jsx(Point, _extends({
131
- dataX: xValue,
132
- dataY: value
133
- }, pointConfig, {
134
- fill: (_pointConfig$fill = pointConfig.fill) != null ? _pointConfig$fill : stroke,
135
- opacity: (_pointConfig$opacity = pointConfig.opacity) != null ? _pointConfig$opacity : opacity
136
- }), seriesId + "-renderpoint-" + index);
131
+ strokeOpacity: strokeOpacity != null ? strokeOpacity : opacity,
132
+ transition: transition,
133
+ yAxisId: matchedSeries == null ? void 0 : matchedSeries.yAxisId
134
+ }, props)), points && /*#__PURE__*/_jsx(Group, {
135
+ opacity: pointsOpacity,
136
+ children: chartData.map((value, index) => {
137
+ if (value === null) return;
138
+ const xValue = xData && xData[index] !== undefined ? xData[index] : index;
139
+ let pointFill = stroke;
140
+ if (gradientConfig && gradient) {
141
+ var _gradient$axis;
142
+ // Use the appropriate data value based on gradient axis
143
+ const axis = (_gradient$axis = gradient.axis) != null ? _gradient$axis : 'y';
144
+ const dataValue = axis === 'x' ? xValue : value;
145
+ const evaluatedColor = evaluateGradientAtValue(gradientConfig.stops, dataValue, gradientConfig.scale);
146
+ if (evaluatedColor) {
147
+ // Apply gradient color to fill if not explicitly set
148
+ pointFill = evaluatedColor;
149
+ }
150
+ }
151
+
152
+ // Build defaults that would be passed to Point
153
+ const defaults = {
154
+ dataX: xValue,
155
+ dataY: value,
156
+ fill: pointFill,
157
+ yAxisId: matchedSeries == null ? void 0 : matchedSeries.yAxisId,
158
+ opacity
159
+ };
160
+
161
+ // If points is true, render with defaults
162
+ if (points === true) {
163
+ return /*#__PURE__*/_jsx(Point, _extends({
164
+ transition: transition
165
+ }, defaults), seriesId + "-" + xValue);
166
+ }
167
+
168
+ // Call the function with defaults
169
+ const result = points(defaults);
170
+ if (!result) return;
171
+ const pointConfig = result === true ? {} : result;
172
+ return /*#__PURE__*/_jsx(Point, _extends({
173
+ transition: transition
174
+ }, defaults, pointConfig), seriesId + "-" + xValue);
175
+ })
137
176
  })]
138
177
  });
139
178
  });
@@ -1,4 +1,4 @@
1
- const _excluded = ["series", "showArea", "areaType", "type", "LineComponent", "AreaComponent", "curve", "renderPoints", "strokeWidth", "showXAxis", "showYAxis", "xAxis", "yAxis", "inset", "children"],
1
+ const _excluded = ["series", "showArea", "areaType", "type", "LineComponent", "AreaComponent", "curve", "points", "strokeWidth", "strokeOpacity", "connectNulls", "transition", "opacity", "showXAxis", "showYAxis", "xAxis", "yAxis", "inset", "children"],
2
2
  _excluded2 = ["scaleType", "data", "categoryPadding", "domain", "domainLimit", "range"],
3
3
  _excluded3 = ["scaleType", "data", "categoryPadding", "domain", "domainLimit", "range", "id"],
4
4
  _excluded4 = ["id", "data", "label", "color", "yAxisId"];
@@ -20,23 +20,21 @@ export const LineChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) =
20
20
  LineComponent,
21
21
  AreaComponent,
22
22
  curve,
23
- renderPoints,
23
+ points,
24
24
  strokeWidth,
25
+ strokeOpacity,
26
+ connectNulls,
27
+ transition,
28
+ opacity,
25
29
  showXAxis,
26
30
  showYAxis,
27
31
  xAxis,
28
32
  yAxis,
29
- inset: userInset,
33
+ inset,
30
34
  children
31
35
  } = _ref,
32
36
  chartProps = _objectWithoutPropertiesLoose(_ref, _excluded);
33
- const calculatedInset = useMemo(() => getChartInset(userInset, defaultChartInset), [userInset]);
34
-
35
- // Check if we have valid data across all series
36
- const hasData = useMemo(() => {
37
- if (!series || series.length === 0) return false;
38
- return series.some(s => s.data && s.data.length > 0);
39
- }, [series]);
37
+ const calculatedInset = useMemo(() => getChartInset(inset, defaultChartInset), [inset]);
40
38
 
41
39
  // Convert LineSeries to Series for Chart context
42
40
  const chartSeries = useMemo(() => {
@@ -44,7 +42,10 @@ export const LineChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) =
44
42
  id: s.id,
45
43
  data: s.data,
46
44
  label: s.label,
47
- color: s.color
45
+ color: s.color,
46
+ yAxisId: s.yAxisId,
47
+ stackId: s.stackId,
48
+ gradient: s.gradient
48
49
  }));
49
50
  }, [series]);
50
51
 
@@ -94,7 +95,8 @@ export const LineChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) =
94
95
  yAxis: yAxisConfig,
95
96
  children: [showXAxis && /*#__PURE__*/_jsx(XAxis, _extends({}, xAxisVisualProps)), showYAxis && /*#__PURE__*/_jsx(YAxis, _extends({
96
97
  axisId: yAxisId
97
- }, yAxisVisualProps)), hasData && (series == null ? void 0 : series.map(_ref4 => {
98
+ }, yAxisVisualProps)), series == null ? void 0 : series.map(_ref4 => {
99
+ var _linePropsFromSeries$;
98
100
  let {
99
101
  id
100
102
  } = _ref4,
@@ -103,13 +105,17 @@ export const LineChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) =
103
105
  AreaComponent: AreaComponent,
104
106
  LineComponent: LineComponent,
105
107
  areaType: areaType,
108
+ connectNulls: connectNulls,
106
109
  curve: curve,
107
- renderPoints: renderPoints,
110
+ opacity: opacity,
111
+ points: points,
108
112
  seriesId: id,
109
113
  showArea: showArea,
114
+ strokeOpacity: strokeOpacity,
110
115
  strokeWidth: strokeWidth,
116
+ transition: (_linePropsFromSeries$ = linePropsFromSeries.transition) != null ? _linePropsFromSeries$ : transition,
111
117
  type: type
112
118
  }, linePropsFromSeries), id);
113
- })), children]
119
+ }), children]
114
120
  }));
115
121
  }));
@@ -1,16 +1,12 @@
1
- function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
2
- import { memo, useMemo } from 'react';
3
- import { G } from 'react-native-svg';
1
+ import { memo } from 'react';
2
+ import { useDerivedValue } from 'react-native-reanimated';
4
3
  import { useTheme } from '@coinbase/cds-mobile/hooks/useTheme';
5
4
  import { useCartesianChartContext } from '../ChartProvider';
6
- import { ChartText } from '../text';
7
- import { getPointOnScale } from '../utils';
5
+ import { unwrapAnimatedValue } from '../utils';
6
+ import { getPointOnSerializableScale } from '../utils/point';
7
+ import { DefaultReferenceLineLabel } from './DefaultReferenceLineLabel';
8
8
  import { DottedLine } from './DottedLine';
9
-
10
- /**
11
- * Configuration for ReferenceLine label rendering using ChartText.
12
- */
13
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
9
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
14
10
  export const ReferenceLine = /*#__PURE__*/memo(_ref => {
15
11
  let {
16
12
  dataX,
@@ -18,44 +14,60 @@ export const ReferenceLine = /*#__PURE__*/memo(_ref => {
18
14
  yAxisId,
19
15
  label,
20
16
  labelPosition = dataY !== undefined ? 'right' : 'top',
21
- testID,
22
17
  LineComponent = DottedLine,
18
+ LabelComponent = DefaultReferenceLineLabel,
19
+ labelElevated,
20
+ labelFont,
21
+ labelDx,
22
+ labelDy,
23
+ labelHorizontalAlignment,
24
+ labelVerticalAlignment,
25
+ labelBoundsInset,
23
26
  stroke,
24
- labelProps
27
+ opacity = 1
25
28
  } = _ref;
26
29
  const theme = useTheme();
27
30
  const {
28
- getXScale,
29
- getYScale,
31
+ getXSerializableScale,
32
+ getYSerializableScale,
30
33
  drawingArea
31
34
  } = useCartesianChartContext();
35
+ const xScale = getXSerializableScale();
36
+ const yScale = getYSerializableScale(yAxisId);
32
37
  const effectiveLineStroke = stroke != null ? stroke : theme.color.bgLine;
33
38
 
34
- // Merge default props with user provided props
35
- const finalLabelProps = useMemo(() => _extends({
36
- borderRadius: 8,
37
- color: theme.color.fgMuted,
38
- inset: {
39
- top: 8,
40
- bottom: 8,
41
- left: 12,
42
- right: 12
43
- }
44
- }, dataY !== undefined ? {
45
- verticalAlignment: 'middle'
46
- } : {
47
- horizontalAlignment: 'center'
48
- }, labelProps), [dataY, labelProps, theme.color.fgMuted]);
49
- // Horizontal reference line logic
39
+ // For horizontal lines (dataY defined): default to verticalAlignment: 'middle'
40
+ // For vertical lines (dataX defined): default to horizontalAlignment: 'center'
41
+ const isHorizontal = dataY !== undefined;
42
+ const xPixel = useDerivedValue(() => {
43
+ const dataXValue = unwrapAnimatedValue(dataX);
44
+ return dataXValue !== undefined && xScale ? getPointOnSerializableScale(dataXValue, xScale) : undefined;
45
+ }, [dataX, xScale]);
46
+ const yPixel = useDerivedValue(() => {
47
+ const dataYValue = unwrapAnimatedValue(dataY);
48
+ return dataYValue !== undefined && yScale ? getPointOnSerializableScale(dataYValue, yScale) : undefined;
49
+ }, [dataY, yScale]);
50
+ const horizontalLine = useDerivedValue(() => {
51
+ if (yPixel.value === undefined) return;
52
+ return "M" + drawingArea.x + "," + yPixel.value + " L" + (drawingArea.x + drawingArea.width) + "," + yPixel.value;
53
+ }, [drawingArea, yPixel]);
54
+ const verticalLine = useDerivedValue(() => {
55
+ if (xPixel.value === undefined) return;
56
+ return "M" + xPixel.value + "," + drawingArea.y + " L" + xPixel.value + "," + (drawingArea.y + drawingArea.height);
57
+ }, [drawingArea, xPixel]);
58
+ const labelXPixel = useDerivedValue(() => {
59
+ var _xPixel$value;
60
+ return (_xPixel$value = xPixel.value) != null ? _xPixel$value : 0;
61
+ }, [xPixel]);
62
+ const labelYPixel = useDerivedValue(() => {
63
+ var _yPixel$value;
64
+ return (_yPixel$value = yPixel.value) != null ? _yPixel$value : 0;
65
+ }, [yPixel]);
66
+ const labelOpacity = useDerivedValue(() => {
67
+ const isVisible = dataY !== undefined && yPixel.value !== undefined || dataX !== undefined && xPixel.value !== undefined;
68
+ return isVisible ? unwrapAnimatedValue(opacity) : 0;
69
+ }, [yPixel, xPixel, opacity]);
50
70
  if (dataY !== undefined) {
51
- const yScale = getYScale(yAxisId);
52
-
53
- // Don't render if we don't have a scale
54
- if (!yScale) {
55
- return null;
56
- }
57
- const yPixel = yScale(dataY);
58
- if (yPixel === undefined) return null;
59
71
  let labelX;
60
72
  if (labelPosition === 'left') {
61
73
  labelX = drawingArea.x;
@@ -64,30 +76,30 @@ export const ReferenceLine = /*#__PURE__*/memo(_ref => {
64
76
  } else {
65
77
  labelX = drawingArea.x + drawingArea.width;
66
78
  }
67
- return /*#__PURE__*/_jsxs(G, {
68
- "data-testid": testID,
79
+ return /*#__PURE__*/_jsxs(_Fragment, {
69
80
  children: [/*#__PURE__*/_jsx(LineComponent, {
70
81
  animate: false,
71
- d: "M" + drawingArea.x + "," + yPixel + " L" + (drawingArea.x + drawingArea.width) + "," + yPixel,
72
- stroke: effectiveLineStroke
73
- }), label && /*#__PURE__*/_jsx(ChartText, _extends({}, finalLabelProps, {
82
+ d: horizontalLine,
83
+ stroke: effectiveLineStroke,
84
+ strokeOpacity: opacity
85
+ }), label && /*#__PURE__*/_jsx(LabelComponent, {
86
+ boundsInset: labelBoundsInset,
87
+ dx: labelDx,
88
+ dy: labelDy,
89
+ elevated: labelElevated,
90
+ font: labelFont,
91
+ horizontalAlignment: labelHorizontalAlignment,
92
+ opacity: labelOpacity,
93
+ verticalAlignment: labelVerticalAlignment != null ? labelVerticalAlignment : isHorizontal ? 'middle' : undefined,
74
94
  x: labelX,
75
- y: yPixel,
95
+ y: labelYPixel,
76
96
  children: label
77
- }))]
97
+ })]
78
98
  });
79
99
  }
80
100
 
81
101
  // Vertical reference line logic
82
102
  if (dataX !== undefined) {
83
- const xScale = getXScale();
84
-
85
- // Don't render if we don't have scales
86
- if (!xScale) {
87
- return null;
88
- }
89
- const xPixel = getPointOnScale(dataX, xScale);
90
- if (xPixel === undefined) return null;
91
103
  let labelY;
92
104
  if (labelPosition === 'top') {
93
105
  labelY = drawingArea.y;
@@ -96,20 +108,25 @@ export const ReferenceLine = /*#__PURE__*/memo(_ref => {
96
108
  } else {
97
109
  labelY = drawingArea.y + drawingArea.height;
98
110
  }
99
- return /*#__PURE__*/_jsxs(G, {
100
- "data-testid": testID,
111
+ return /*#__PURE__*/_jsxs(_Fragment, {
101
112
  children: [/*#__PURE__*/_jsx(LineComponent, {
102
113
  animate: false,
103
- d: "M" + xPixel + "," + drawingArea.y + " L" + xPixel + "," + (drawingArea.y + drawingArea.height),
104
- stroke: effectiveLineStroke
105
- }), label && /*#__PURE__*/_jsx(ChartText, _extends({}, finalLabelProps, {
106
- x: xPixel,
114
+ d: verticalLine,
115
+ stroke: effectiveLineStroke,
116
+ strokeOpacity: opacity
117
+ }), label && /*#__PURE__*/_jsx(LabelComponent, {
118
+ boundsInset: labelBoundsInset,
119
+ dx: labelDx,
120
+ dy: labelDy,
121
+ elevated: labelElevated,
122
+ font: labelFont,
123
+ horizontalAlignment: labelHorizontalAlignment != null ? labelHorizontalAlignment : !isHorizontal ? 'center' : undefined,
124
+ opacity: labelOpacity,
125
+ verticalAlignment: labelVerticalAlignment,
126
+ x: labelXPixel,
107
127
  y: labelY,
108
128
  children: label
109
- }))]
129
+ })]
110
130
  });
111
131
  }
112
-
113
- // Should not reach here if types are correct
114
- return null;
115
132
  });