@coinbase/cds-mobile-visualization 3.3.0 → 3.4.0-beta.1
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.
- package/CHANGELOG.md +26 -0
- package/dts/chart/CartesianChart.d.ts +101 -0
- package/dts/chart/CartesianChart.d.ts.map +1 -0
- package/dts/chart/ChartProvider.d.ts +6 -0
- package/dts/chart/ChartProvider.d.ts.map +1 -0
- package/dts/chart/Path.d.ts +48 -0
- package/dts/chart/Path.d.ts.map +1 -0
- package/dts/chart/PeriodSelector.d.ts +85 -0
- package/dts/chart/PeriodSelector.d.ts.map +1 -0
- package/dts/chart/Point.d.ts +103 -0
- package/dts/chart/Point.d.ts.map +1 -0
- package/dts/chart/area/Area.d.ts +62 -0
- package/dts/chart/area/Area.d.ts.map +1 -0
- package/dts/chart/area/AreaChart.d.ts +90 -0
- package/dts/chart/area/AreaChart.d.ts.map +1 -0
- package/dts/chart/area/DottedArea.d.ts +27 -0
- package/dts/chart/area/DottedArea.d.ts.map +1 -0
- package/dts/chart/area/GradientArea.d.ts +30 -0
- package/dts/chart/area/GradientArea.d.ts.map +1 -0
- package/dts/chart/area/SolidArea.d.ts +8 -0
- package/dts/chart/area/SolidArea.d.ts.map +1 -0
- package/dts/chart/area/index.d.ts +6 -0
- package/dts/chart/area/index.d.ts.map +1 -0
- package/dts/chart/axis/Axis.d.ts +204 -0
- package/dts/chart/axis/Axis.d.ts.map +1 -0
- package/dts/chart/axis/XAxis.d.ts +16 -0
- package/dts/chart/axis/XAxis.d.ts.map +1 -0
- package/dts/chart/axis/YAxis.d.ts +21 -0
- package/dts/chart/axis/YAxis.d.ts.map +1 -0
- package/dts/chart/axis/index.d.ts +4 -0
- package/dts/chart/axis/index.d.ts.map +1 -0
- package/dts/chart/bar/Bar.d.ts +89 -0
- package/dts/chart/bar/Bar.d.ts.map +1 -0
- package/dts/chart/bar/BarChart.d.ts +97 -0
- package/dts/chart/bar/BarChart.d.ts.map +1 -0
- package/dts/chart/bar/BarPlot.d.ts +29 -0
- package/dts/chart/bar/BarPlot.d.ts.map +1 -0
- package/dts/chart/bar/BarStack.d.ts +111 -0
- package/dts/chart/bar/BarStack.d.ts.map +1 -0
- package/dts/chart/bar/BarStackGroup.d.ts +35 -0
- package/dts/chart/bar/BarStackGroup.d.ts.map +1 -0
- package/dts/chart/bar/DefaultBar.d.ts +7 -0
- package/dts/chart/bar/DefaultBar.d.ts.map +1 -0
- package/dts/chart/bar/DefaultBarStack.d.ts +7 -0
- package/dts/chart/bar/DefaultBarStack.d.ts.map +1 -0
- package/dts/chart/bar/index.d.ts +8 -0
- package/dts/chart/bar/index.d.ts.map +1 -0
- package/dts/chart/index.d.ts +13 -0
- package/dts/chart/index.d.ts.map +1 -0
- package/dts/chart/line/DottedLine.d.ts +12 -0
- package/dts/chart/line/DottedLine.d.ts.map +1 -0
- package/dts/chart/line/GradientLine.d.ts +45 -0
- package/dts/chart/line/GradientLine.d.ts.map +1 -0
- package/dts/chart/line/Line.d.ts +78 -0
- package/dts/chart/line/Line.d.ts.map +1 -0
- package/dts/chart/line/LineChart.d.ts +84 -0
- package/dts/chart/line/LineChart.d.ts.map +1 -0
- package/dts/chart/line/ReferenceLine.d.ts +91 -0
- package/dts/chart/line/ReferenceLine.d.ts.map +1 -0
- package/dts/chart/line/SolidLine.d.ts +12 -0
- package/dts/chart/line/SolidLine.d.ts.map +1 -0
- package/dts/chart/line/index.d.ts +7 -0
- package/dts/chart/line/index.d.ts.map +1 -0
- package/dts/chart/scrubber/Scrubber.d.ts +104 -0
- package/dts/chart/scrubber/Scrubber.d.ts.map +1 -0
- package/dts/chart/scrubber/ScrubberBeacon.d.ts +75 -0
- package/dts/chart/scrubber/ScrubberBeacon.d.ts.map +1 -0
- package/dts/chart/scrubber/ScrubberProvider.d.ts +17 -0
- package/dts/chart/scrubber/ScrubberProvider.d.ts.map +1 -0
- package/dts/chart/scrubber/index.d.ts +2 -0
- package/dts/chart/scrubber/index.d.ts.map +1 -0
- package/dts/chart/text/ChartText.d.ts +90 -0
- package/dts/chart/text/ChartText.d.ts.map +1 -0
- package/dts/chart/text/SmartChartTextGroup.d.ts +55 -0
- package/dts/chart/text/SmartChartTextGroup.d.ts.map +1 -0
- package/dts/chart/text/index.d.ts +3 -0
- package/dts/chart/text/index.d.ts.map +1 -0
- package/dts/chart/utils/axis.d.ts +342 -0
- package/dts/chart/utils/axis.d.ts.map +1 -0
- package/dts/chart/utils/bar.d.ts +20 -0
- package/dts/chart/utils/bar.d.ts.map +1 -0
- package/dts/chart/utils/chart.d.ts +97 -0
- package/dts/chart/utils/chart.d.ts.map +1 -0
- package/dts/chart/utils/context.d.ts +95 -0
- package/dts/chart/utils/context.d.ts.map +1 -0
- package/dts/chart/utils/index.d.ts +8 -0
- package/dts/chart/utils/index.d.ts.map +1 -0
- package/dts/chart/utils/path.d.ts +107 -0
- package/dts/chart/utils/path.d.ts.map +1 -0
- package/dts/chart/utils/point.d.ts +75 -0
- package/dts/chart/utils/point.d.ts.map +1 -0
- package/dts/chart/utils/scale.d.ts +43 -0
- package/dts/chart/utils/scale.d.ts.map +1 -0
- package/dts/index.d.ts +2 -1
- package/dts/index.d.ts.map +1 -1
- package/dts/sparkline/Counter.d.ts +7 -2
- package/dts/sparkline/Sparkline.d.ts +67 -16
- package/dts/sparkline/Sparkline.d.ts.map +1 -1
- package/dts/sparkline/SparklineArea.d.ts +10 -4
- package/dts/sparkline/SparklineArea.d.ts.map +1 -1
- package/dts/sparkline/SparklineAreaPattern.d.ts +12 -4
- package/dts/sparkline/SparklineAreaPattern.d.ts.map +1 -1
- package/dts/sparkline/SparklineGradient.d.ts +21 -10
- package/dts/sparkline/SparklineGradient.d.ts.map +1 -1
- package/dts/sparkline/__figma__/Sparkline.figma.d.ts +1 -1
- package/dts/sparkline/generateSparklineWithId.d.ts +8 -2
- package/dts/sparkline/generateSparklineWithId.d.ts.map +1 -1
- package/dts/sparkline/index.d.ts +1 -1
- package/dts/sparkline/sparkline-interactive/SparklineAccessibleView.d.ts +8 -3
- package/dts/sparkline/sparkline-interactive/SparklineInteractive.d.ts +132 -110
- package/dts/sparkline/sparkline-interactive/SparklineInteractive.d.ts.map +1 -1
- package/dts/sparkline/sparkline-interactive/SparklineInteractiveAnimatedPath.d.ts +22 -9
- package/dts/sparkline/sparkline-interactive/SparklineInteractiveAnimatedPath.d.ts.map +1 -1
- package/dts/sparkline/sparkline-interactive/SparklineInteractiveHoverDate.d.ts +18 -7
- package/dts/sparkline/sparkline-interactive/SparklineInteractiveLineVertical.d.ts +9 -4
- package/dts/sparkline/sparkline-interactive/SparklineInteractiveMarkerDates.d.ts +11 -6
- package/dts/sparkline/sparkline-interactive/SparklineInteractiveMinMax.d.ts +7 -5
- package/dts/sparkline/sparkline-interactive/SparklineInteractivePanGestureHandler.d.ts +22 -10
- package/dts/sparkline/sparkline-interactive/SparklineInteractivePaths.d.ts +21 -7
- package/dts/sparkline/sparkline-interactive/SparklineInteractivePaths.d.ts.map +1 -1
- package/dts/sparkline/sparkline-interactive/SparklineInteractivePeriodSelector.d.ts +21 -16
- package/dts/sparkline/sparkline-interactive/SparklineInteractiveProvider.d.ts +29 -23
- package/dts/sparkline/sparkline-interactive/SparklineInteractiveTimeseriesPaths.d.ts +22 -14
- package/dts/sparkline/sparkline-interactive/__figma__/SparklineInteractive.figma.d.ts +1 -1
- package/dts/sparkline/sparkline-interactive/useInterruptiblePathAnimation.d.ts +9 -5
- package/dts/sparkline/sparkline-interactive/useMinMaxTransform.d.ts +11 -6
- package/dts/sparkline/sparkline-interactive/useOpacityAnimation.d.ts +5 -2
- package/dts/sparkline/sparkline-interactive/useSparklineInteractiveConstants.d.ts +17 -17
- package/dts/sparkline/sparkline-interactive/useSparklineInteractiveLineStyles.d.ts +16 -13
- package/dts/sparkline/sparkline-interactive-header/SparklineInteractiveHeader.d.ts +106 -98
- package/dts/sparkline/sparkline-interactive-header/__figma__/SparklineInteractiveHeader.figma.d.ts +1 -1
- package/dts/sparkline/sparkline-interactive-header/useSparklineInteractiveHeaderStyles.d.ts +22 -19
- package/esm/chart/CartesianChart.js +241 -0
- package/esm/chart/ChartProvider.js +10 -0
- package/esm/chart/Path.js +133 -0
- package/esm/chart/PeriodSelector.js +136 -0
- package/esm/chart/Point.js +111 -0
- package/esm/chart/__stories__/CartesianChart.stories.js +476 -0
- package/esm/chart/__stories__/Chart.stories.js +79 -0
- package/esm/chart/__stories__/PeriodSelector.stories.js +294 -0
- package/esm/chart/area/Area.js +85 -0
- package/esm/chart/area/AreaChart.js +146 -0
- package/esm/chart/area/DottedArea.js +128 -0
- package/esm/chart/area/GradientArea.js +110 -0
- package/esm/chart/area/SolidArea.js +24 -0
- package/esm/chart/area/__stories__/AreaChart.stories.js +100 -0
- package/esm/chart/area/index.js +7 -0
- package/esm/chart/axis/Axis.js +43 -0
- package/esm/chart/axis/XAxis.js +181 -0
- package/esm/chart/axis/YAxis.js +170 -0
- package/esm/chart/axis/__stories__/Axis.stories.js +277 -0
- package/esm/chart/axis/index.js +5 -0
- package/esm/chart/bar/Bar.js +67 -0
- package/esm/chart/bar/BarChart.js +147 -0
- package/esm/chart/bar/BarPlot.js +96 -0
- package/esm/chart/bar/BarStack.js +514 -0
- package/esm/chart/bar/BarStackGroup.js +89 -0
- package/esm/chart/bar/DefaultBar.js +78 -0
- package/esm/chart/bar/DefaultBarStack.js +82 -0
- package/esm/chart/bar/__stories__/BarChart.stories.js +282 -0
- package/esm/chart/bar/index.js +9 -0
- package/esm/chart/index.js +14 -0
- package/esm/chart/line/DottedLine.js +35 -0
- package/esm/chart/line/GradientLine.js +62 -0
- package/esm/chart/line/Line.js +139 -0
- package/esm/chart/line/LineChart.js +115 -0
- package/esm/chart/line/ReferenceLine.js +115 -0
- package/esm/chart/line/SolidLine.js +31 -0
- package/esm/chart/line/__stories__/LineChart.stories.js +2248 -0
- package/esm/chart/line/__stories__/ReferenceLine.stories.js +77 -0
- package/esm/chart/line/index.js +8 -0
- package/esm/chart/scrubber/Scrubber.js +186 -0
- package/esm/chart/scrubber/ScrubberBeacon.js +199 -0
- package/esm/chart/scrubber/ScrubberProvider.js +143 -0
- package/esm/chart/scrubber/index.js +2 -0
- package/esm/chart/text/ChartText.js +237 -0
- package/esm/chart/text/SmartChartTextGroup.js +210 -0
- package/esm/chart/text/index.js +4 -0
- package/esm/chart/utils/axis.js +592 -0
- package/esm/chart/utils/bar.js +24 -0
- package/esm/chart/utils/chart.js +229 -0
- package/esm/chart/utils/context.js +15 -0
- package/esm/chart/utils/index.js +9 -0
- package/esm/chart/utils/path.js +206 -0
- package/esm/chart/utils/point.js +118 -0
- package/esm/chart/utils/scale.js +48 -0
- package/esm/index.js +4 -1
- package/esm/sparkline/Sparkline.js +129 -16
- package/esm/sparkline/SparklineArea.js +7 -2
- package/esm/sparkline/SparklineAreaPattern.js +4 -2
- package/esm/sparkline/SparklineGradient.js +4 -0
- package/esm/sparkline/generateSparklineWithId.js +3 -2
- package/esm/sparkline/sparkline-interactive/SparklineInteractive.js +5 -1
- package/esm/sparkline/sparkline-interactive/SparklineInteractiveAnimatedPath.js +5 -2
- package/esm/sparkline/sparkline-interactive/SparklineInteractivePaths.js +4 -0
- package/esm/sparkline/sparkline-interactive/__stories__/SparklineInteractive.stories.js +27 -0
- package/package.json +11 -11
- package/dts/sparkline/__stories__/Sparkline.stories.d.ts +0 -3
- package/dts/sparkline/__stories__/Sparkline.stories.d.ts.map +0 -1
- package/dts/sparkline/__stories__/SparklineGradient.stories.d.ts +0 -3
- package/dts/sparkline/__stories__/SparklineGradient.stories.d.ts.map +0 -1
- package/dts/sparkline/sparkline-interactive/__stories__/SparklineInteractive.stories.d.ts +0 -3
- package/dts/sparkline/sparkline-interactive/__stories__/SparklineInteractive.stories.d.ts.map +0 -1
- package/dts/sparkline/sparkline-interactive/__tests__/SparklineInteractive.test.d.ts +0 -2
- package/dts/sparkline/sparkline-interactive/__tests__/SparklineInteractive.test.d.ts.map +0 -1
- package/dts/sparkline/sparkline-interactive/__tests__/SparklineInteractiveHoverDate.test.d.ts +0 -2
- package/dts/sparkline/sparkline-interactive/__tests__/SparklineInteractiveHoverDate.test.d.ts.map +0 -1
- package/dts/sparkline/sparkline-interactive/__tests__/SparklineInteractivePanGestureHandler.test.d.ts +0 -2
- package/dts/sparkline/sparkline-interactive/__tests__/SparklineInteractivePanGestureHandler.test.d.ts.map +0 -1
- package/dts/sparkline/sparkline-interactive/__tests__/SparklineInteractivePeriodSelector.test.d.ts +0 -2
- package/dts/sparkline/sparkline-interactive/__tests__/SparklineInteractivePeriodSelector.test.d.ts.map +0 -1
- package/dts/sparkline/sparkline-interactive/__tests__/SparklineInteractiveTimeseriesPaths.test.d.ts +0 -2
- package/dts/sparkline/sparkline-interactive/__tests__/SparklineInteractiveTimeseriesPaths.test.d.ts.map +0 -1
- package/dts/sparkline/sparkline-interactive/__tests__/useMinMaxTransform.test.d.ts +0 -2
- package/dts/sparkline/sparkline-interactive/__tests__/useMinMaxTransform.test.d.ts.map +0 -1
- package/dts/sparkline/sparkline-interactive/useInterruptiblePathAnimation.test.disable.d.ts +0 -2
- package/dts/sparkline/sparkline-interactive/useInterruptiblePathAnimation.test.disable.d.ts.map +0 -1
- package/dts/sparkline/sparkline-interactive-header/__stories__/SparklineInteractiveHeader.stories.d.ts +0 -4
- package/dts/sparkline/sparkline-interactive-header/__stories__/SparklineInteractiveHeader.stories.d.ts.map +0 -1
- package/dts/sparkline/sparkline-interactive-header/__tests__/SparklineInteractiveHeader.test.d.ts +0 -2
- package/dts/sparkline/sparkline-interactive-header/__tests__/SparklineInteractiveHeader.test.d.ts.map +0 -1
- package/dts/sparkline/sparkline-interactive-header/__tests__/useSparklineInteractiveHeaderStyles.test.d.ts +0 -2
- package/dts/sparkline/sparkline-interactive-header/__tests__/useSparklineInteractiveHeaderStyles.test.d.ts.map +0 -1
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
const _excluded = ["d", "fill", "fillOpacity", "peakColor", "baselineColor", "peakOpacity", "baselineOpacity", "baseline", "yAxisId", "clipRect"];
|
|
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, useId } from 'react';
|
|
5
|
+
import { Defs, LinearGradient, Stop } from 'react-native-svg';
|
|
6
|
+
import { useTheme } from '@coinbase/cds-mobile/hooks/useTheme';
|
|
7
|
+
import { useCartesianChartContext } from '../ChartProvider';
|
|
8
|
+
import { Path } from '../Path';
|
|
9
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
10
|
+
/**
|
|
11
|
+
* A customizable gradient area component which uses Path.
|
|
12
|
+
*/
|
|
13
|
+
export const GradientArea = /*#__PURE__*/memo(_ref => {
|
|
14
|
+
let {
|
|
15
|
+
d,
|
|
16
|
+
fill,
|
|
17
|
+
fillOpacity = 1,
|
|
18
|
+
peakColor,
|
|
19
|
+
baselineColor,
|
|
20
|
+
peakOpacity = 0.3,
|
|
21
|
+
baselineOpacity = 0,
|
|
22
|
+
baseline,
|
|
23
|
+
yAxisId,
|
|
24
|
+
clipRect
|
|
25
|
+
} = _ref,
|
|
26
|
+
pathProps = _objectWithoutPropertiesLoose(_ref, _excluded);
|
|
27
|
+
const context = useCartesianChartContext();
|
|
28
|
+
const theme = useTheme();
|
|
29
|
+
const patternId = useId();
|
|
30
|
+
|
|
31
|
+
// Get the y-scale for the specified axis (or default)
|
|
32
|
+
const yScale = context.getYScale(yAxisId);
|
|
33
|
+
const yRange = yScale == null ? void 0 : yScale.range();
|
|
34
|
+
const yDomain = yScale == null ? void 0 : yScale.domain();
|
|
35
|
+
|
|
36
|
+
// Use chart range if available, otherwise fall back to percentage
|
|
37
|
+
const useUserSpaceUnits = yRange !== undefined;
|
|
38
|
+
const gradientY1 = useUserSpaceUnits && yRange ? String(yRange[1]) : '0%';
|
|
39
|
+
const gradientY2 = useUserSpaceUnits && yRange ? String(yRange[0]) : '100%';
|
|
40
|
+
|
|
41
|
+
// Auto-calculate baseline position based on domain
|
|
42
|
+
let baselinePosition;
|
|
43
|
+
let baselinePercentage;
|
|
44
|
+
if (yScale && yDomain) {
|
|
45
|
+
const [minValue, maxValue] = yDomain;
|
|
46
|
+
let dataBaseline;
|
|
47
|
+
if (minValue >= 0) {
|
|
48
|
+
// All positive: baseline at min
|
|
49
|
+
dataBaseline = minValue;
|
|
50
|
+
} else if (maxValue <= 0) {
|
|
51
|
+
// All negative: baseline at max
|
|
52
|
+
dataBaseline = maxValue;
|
|
53
|
+
} else {
|
|
54
|
+
// Crosses zero: baseline at 0
|
|
55
|
+
dataBaseline = 0;
|
|
56
|
+
}
|
|
57
|
+
if (useUserSpaceUnits && yRange) {
|
|
58
|
+
// Get the actual y coordinate for the baseline
|
|
59
|
+
const scaledValue = yScale(baseline != null ? baseline : dataBaseline);
|
|
60
|
+
if (typeof scaledValue === 'number') {
|
|
61
|
+
baselinePosition = scaledValue;
|
|
62
|
+
}
|
|
63
|
+
} else {
|
|
64
|
+
// Calculate percentage position
|
|
65
|
+
baselinePercentage = (maxValue - (baseline != null ? baseline : dataBaseline)) / (maxValue - minValue) * 100 + "%";
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
const effectiveFill = fill != null ? fill : theme.color.fgPrimary;
|
|
69
|
+
const effectivePeakColor = peakColor != null ? peakColor : effectiveFill;
|
|
70
|
+
const effectiveBaselineColor = baselineColor != null ? baselineColor : effectiveFill;
|
|
71
|
+
return /*#__PURE__*/_jsxs(_Fragment, {
|
|
72
|
+
children: [/*#__PURE__*/_jsx(Defs, {
|
|
73
|
+
children: /*#__PURE__*/_jsx(LinearGradient, {
|
|
74
|
+
gradientUnits: useUserSpaceUnits ? 'userSpaceOnUse' : 'objectBoundingBox',
|
|
75
|
+
id: patternId,
|
|
76
|
+
x1: useUserSpaceUnits ? '0' : '0%',
|
|
77
|
+
x2: useUserSpaceUnits ? '0' : '0%',
|
|
78
|
+
y1: gradientY1,
|
|
79
|
+
y2: gradientY2,
|
|
80
|
+
children: baselinePosition !== undefined || baselinePercentage !== undefined ? /* Diverging gradient: peak opacity at extremes, baseline opacity at baseline */
|
|
81
|
+
[/*#__PURE__*/_jsx(Stop, {
|
|
82
|
+
offset: "0%",
|
|
83
|
+
stopColor: effectivePeakColor,
|
|
84
|
+
stopOpacity: peakOpacity
|
|
85
|
+
}, "0"), /*#__PURE__*/_jsx(Stop, {
|
|
86
|
+
offset: baselinePercentage != null ? baselinePercentage : (baselinePosition - yRange[1]) / (yRange[0] - yRange[1]) * 100 + "%",
|
|
87
|
+
stopColor: effectiveBaselineColor,
|
|
88
|
+
stopOpacity: baselineOpacity
|
|
89
|
+
}, "1"), /*#__PURE__*/_jsx(Stop, {
|
|
90
|
+
offset: "100%",
|
|
91
|
+
stopColor: effectivePeakColor,
|
|
92
|
+
stopOpacity: peakOpacity
|
|
93
|
+
}, "2")] : /* Simple gradient from peak to baseline */
|
|
94
|
+
[/*#__PURE__*/_jsx(Stop, {
|
|
95
|
+
offset: "0%",
|
|
96
|
+
stopColor: effectivePeakColor,
|
|
97
|
+
stopOpacity: peakOpacity
|
|
98
|
+
}, "0"), /*#__PURE__*/_jsx(Stop, {
|
|
99
|
+
offset: "100%",
|
|
100
|
+
stopColor: effectiveBaselineColor,
|
|
101
|
+
stopOpacity: baselineOpacity
|
|
102
|
+
}, "1")]
|
|
103
|
+
})
|
|
104
|
+
}), /*#__PURE__*/_jsx(Path, _extends({
|
|
105
|
+
clipRect: clipRect,
|
|
106
|
+
d: d,
|
|
107
|
+
fill: "url(#" + patternId + ")"
|
|
108
|
+
}, pathProps))]
|
|
109
|
+
});
|
|
110
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const _excluded = ["d", "fill", "fillOpacity", "clipRect"];
|
|
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 } from 'react';
|
|
5
|
+
import { Path } from '../Path';
|
|
6
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
7
|
+
/**
|
|
8
|
+
* A customizable solid area component which uses Path.
|
|
9
|
+
*/
|
|
10
|
+
export const SolidArea = /*#__PURE__*/memo(_ref => {
|
|
11
|
+
let {
|
|
12
|
+
d,
|
|
13
|
+
fill,
|
|
14
|
+
fillOpacity = 1,
|
|
15
|
+
clipRect
|
|
16
|
+
} = _ref,
|
|
17
|
+
props = _objectWithoutPropertiesLoose(_ref, _excluded);
|
|
18
|
+
return /*#__PURE__*/_jsx(Path, _extends({
|
|
19
|
+
clipRect: clipRect,
|
|
20
|
+
d: d,
|
|
21
|
+
fill: fill,
|
|
22
|
+
fillOpacity: fillOpacity
|
|
23
|
+
}, props));
|
|
24
|
+
});
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { Example, ExampleScreen } from '@coinbase/cds-mobile/examples/ExampleScreen';
|
|
2
|
+
import { useTheme } from '@coinbase/cds-mobile/hooks/useTheme';
|
|
3
|
+
import { DottedLine } from '../../line';
|
|
4
|
+
import { Scrubber } from '../../scrubber/Scrubber';
|
|
5
|
+
import { AreaChart } from '..';
|
|
6
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
7
|
+
const BasicExample = () => {
|
|
8
|
+
return /*#__PURE__*/_jsx(AreaChart, {
|
|
9
|
+
enableScrubbing: true,
|
|
10
|
+
showYAxis: true,
|
|
11
|
+
height: 400,
|
|
12
|
+
series: [{
|
|
13
|
+
id: 'pageViews',
|
|
14
|
+
data: [24, 13, 98, 39, 48, 38, 43]
|
|
15
|
+
}],
|
|
16
|
+
yAxis: {
|
|
17
|
+
showGrid: true,
|
|
18
|
+
domain: {
|
|
19
|
+
min: 0
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
children: /*#__PURE__*/_jsx(Scrubber, {})
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
const StackedExample = () => {
|
|
26
|
+
const theme = useTheme();
|
|
27
|
+
return /*#__PURE__*/_jsx(AreaChart, {
|
|
28
|
+
enableScrubbing: true,
|
|
29
|
+
showLines: true,
|
|
30
|
+
stacked: true,
|
|
31
|
+
curve: "natural",
|
|
32
|
+
height: 256,
|
|
33
|
+
series: [{
|
|
34
|
+
id: 'currentRewards',
|
|
35
|
+
data: [100, 150, 200, 280, 380, 500, 650, 820, 1020, 1250, 1510, 1800, 2120, 2470, 2850, 3260, 3700, 4170],
|
|
36
|
+
color: theme.color.fg
|
|
37
|
+
}, {
|
|
38
|
+
id: 'potentialRewards',
|
|
39
|
+
data: [150, 220, 300, 400, 520, 660, 820, 1000, 1200, 1420, 1660, 1920, 2200, 2500, 2820, 3160, 3520, 3900],
|
|
40
|
+
color: theme.color.fgPositive,
|
|
41
|
+
type: 'dotted',
|
|
42
|
+
LineComponent: DottedLine
|
|
43
|
+
}],
|
|
44
|
+
type: "dotted",
|
|
45
|
+
children: /*#__PURE__*/_jsx(Scrubber, {})
|
|
46
|
+
});
|
|
47
|
+
};
|
|
48
|
+
const AreaChartStories = () => {
|
|
49
|
+
return /*#__PURE__*/_jsxs(ExampleScreen, {
|
|
50
|
+
children: [/*#__PURE__*/_jsx(Example, {
|
|
51
|
+
title: "Basic",
|
|
52
|
+
children: /*#__PURE__*/_jsx(BasicExample, {})
|
|
53
|
+
}), /*#__PURE__*/_jsx(Example, {
|
|
54
|
+
title: "Stacked",
|
|
55
|
+
children: /*#__PURE__*/_jsx(StackedExample, {})
|
|
56
|
+
}), /*#__PURE__*/_jsx(Example, {
|
|
57
|
+
title: "Negative Values",
|
|
58
|
+
children: /*#__PURE__*/_jsx(AreaChart, {
|
|
59
|
+
enableScrubbing: true,
|
|
60
|
+
showLines: true,
|
|
61
|
+
showYAxis: true,
|
|
62
|
+
height: 400,
|
|
63
|
+
series: [{
|
|
64
|
+
id: 'pageViews',
|
|
65
|
+
data: [24, 13, -98, 39, 48, 38, 43]
|
|
66
|
+
}],
|
|
67
|
+
type: "gradient",
|
|
68
|
+
yAxis: {
|
|
69
|
+
showGrid: true
|
|
70
|
+
},
|
|
71
|
+
children: /*#__PURE__*/_jsx(Scrubber, {})
|
|
72
|
+
})
|
|
73
|
+
}), /*#__PURE__*/_jsx(Example, {
|
|
74
|
+
title: "Styles",
|
|
75
|
+
children: /*#__PURE__*/_jsx(AreaChart, {
|
|
76
|
+
enableScrubbing: false,
|
|
77
|
+
height: 350,
|
|
78
|
+
series: [{
|
|
79
|
+
id: 'visitors',
|
|
80
|
+
data: [450, 520, 480, 600, 750, 680, 590],
|
|
81
|
+
label: 'Weekly Visitors',
|
|
82
|
+
color: '#fb4d3d',
|
|
83
|
+
type: 'dotted'
|
|
84
|
+
}, {
|
|
85
|
+
id: 'repeatVisitors',
|
|
86
|
+
data: [250, 200, 150, 140, 100, 80, 50],
|
|
87
|
+
label: 'Weekly Repeat Visitors',
|
|
88
|
+
color: '#16a34a'
|
|
89
|
+
}, {
|
|
90
|
+
id: 'signups',
|
|
91
|
+
data: [45, 62, 55, 250, 380, 400, 450],
|
|
92
|
+
label: 'Weekly Signups',
|
|
93
|
+
color: '#2563eb',
|
|
94
|
+
type: 'gradient'
|
|
95
|
+
}]
|
|
96
|
+
})
|
|
97
|
+
})]
|
|
98
|
+
});
|
|
99
|
+
};
|
|
100
|
+
export default AreaChartStories;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Animation variants for grouped axis tick labels - initial mount
|
|
3
|
+
*/
|
|
4
|
+
export const axisTickLabelsInitialAnimationVariants = {
|
|
5
|
+
initial: {
|
|
6
|
+
opacity: 0
|
|
7
|
+
},
|
|
8
|
+
animate: {
|
|
9
|
+
opacity: 1,
|
|
10
|
+
transition: {
|
|
11
|
+
duration: 0,
|
|
12
|
+
delay: 0
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
exit: {
|
|
16
|
+
opacity: 0,
|
|
17
|
+
transition: {
|
|
18
|
+
duration: 0.15
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Animation variants for axis elements - updates (used for both grid lines and tick labels)
|
|
25
|
+
*/
|
|
26
|
+
export const axisUpdateAnimationVariants = {
|
|
27
|
+
initial: {
|
|
28
|
+
opacity: 0
|
|
29
|
+
},
|
|
30
|
+
animate: {
|
|
31
|
+
opacity: 1,
|
|
32
|
+
transition: {
|
|
33
|
+
duration: 0.15,
|
|
34
|
+
delay: 0.15 // For updates: fade out 150ms, then fade in 150ms
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
exit: {
|
|
38
|
+
opacity: 0,
|
|
39
|
+
transition: {
|
|
40
|
+
duration: 0.15
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
};
|
|
@@ -0,0 +1,181 @@
|
|
|
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); }
|
|
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, useCallback, useEffect, useId, useMemo } from 'react';
|
|
5
|
+
import Animated, { useAnimatedStyle, useSharedValue } from 'react-native-reanimated';
|
|
6
|
+
import { G, Line } from 'react-native-svg';
|
|
7
|
+
import { useTheme } from '@coinbase/cds-mobile/hooks/useTheme';
|
|
8
|
+
import { useCartesianChartContext } from '../ChartProvider';
|
|
9
|
+
import { DottedLine } from '../line/DottedLine';
|
|
10
|
+
import { ReferenceLine } from '../line/ReferenceLine';
|
|
11
|
+
import { SmartChartTextGroup } from '../text/SmartChartTextGroup';
|
|
12
|
+
import { getAxisTicksData, isCategoricalScale } from '../utils';
|
|
13
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
14
|
+
const AnimatedG = Animated.createAnimatedComponent(G);
|
|
15
|
+
export const XAxis = /*#__PURE__*/memo(_ref => {
|
|
16
|
+
let {
|
|
17
|
+
position = 'bottom',
|
|
18
|
+
showGrid,
|
|
19
|
+
requestedTickCount,
|
|
20
|
+
ticks,
|
|
21
|
+
tickLabelFormatter,
|
|
22
|
+
styles,
|
|
23
|
+
classNames,
|
|
24
|
+
GridLineComponent = DottedLine,
|
|
25
|
+
tickMarkLabelGap = 2,
|
|
26
|
+
height = 32,
|
|
27
|
+
minTickLabelGap = 4,
|
|
28
|
+
showTickMarks,
|
|
29
|
+
showLine,
|
|
30
|
+
tickMarkSize = 4,
|
|
31
|
+
tickInterval = 32,
|
|
32
|
+
tickMinStep = 1,
|
|
33
|
+
tickMaxStep
|
|
34
|
+
} = _ref,
|
|
35
|
+
props = _objectWithoutPropertiesLoose(_ref, _excluded);
|
|
36
|
+
const theme = useTheme();
|
|
37
|
+
const registrationId = useId();
|
|
38
|
+
const {
|
|
39
|
+
animate,
|
|
40
|
+
getXScale,
|
|
41
|
+
getXAxis,
|
|
42
|
+
registerAxis,
|
|
43
|
+
unregisterAxis,
|
|
44
|
+
getAxisBounds
|
|
45
|
+
} = useCartesianChartContext();
|
|
46
|
+
const xScale = getXScale();
|
|
47
|
+
const xAxis = getXAxis();
|
|
48
|
+
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]);
|
|
60
|
+
useEffect(() => {
|
|
61
|
+
registerAxis(registrationId, position, height);
|
|
62
|
+
return () => unregisterAxis(registrationId);
|
|
63
|
+
}, [registrationId, registerAxis, unregisterAxis, position, height]);
|
|
64
|
+
const formatTick = useCallback(value => {
|
|
65
|
+
var _tickLabelFormatter;
|
|
66
|
+
// If we have string labels and no custom formatter, use the labels
|
|
67
|
+
const axisData = xAxis == null ? void 0 : xAxis.data;
|
|
68
|
+
const hasStringLabels = axisData && Array.isArray(axisData) && typeof axisData[0] === 'string';
|
|
69
|
+
let finalValue = value;
|
|
70
|
+
|
|
71
|
+
// For band scales with string data, value is an index
|
|
72
|
+
if (hasStringLabels && typeof value === 'number' && axisData[value] !== undefined) {
|
|
73
|
+
finalValue = axisData[value];
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Use the formatter (if provided) or the value itself
|
|
77
|
+
return (_tickLabelFormatter = tickLabelFormatter == null ? void 0 : tickLabelFormatter(finalValue)) != null ? _tickLabelFormatter : finalValue;
|
|
78
|
+
}, [xAxis == null ? void 0 : xAxis.data, tickLabelFormatter]);
|
|
79
|
+
const ticksData = useMemo(() => {
|
|
80
|
+
if (!xScale) return [];
|
|
81
|
+
|
|
82
|
+
// Check if we have string labels
|
|
83
|
+
const axisData = xAxis == null ? void 0 : xAxis.data;
|
|
84
|
+
const hasStringLabels = axisData && Array.isArray(axisData) && typeof axisData[0] === 'string';
|
|
85
|
+
|
|
86
|
+
// For band scales, we need categories
|
|
87
|
+
let categories;
|
|
88
|
+
if (hasStringLabels) {
|
|
89
|
+
categories = axisData;
|
|
90
|
+
} else if (isCategoricalScale(xScale)) {
|
|
91
|
+
// For band scales without explicit string data, generate numeric categories
|
|
92
|
+
// based on the domain of the scale
|
|
93
|
+
const domain = xScale.domain();
|
|
94
|
+
categories = domain.map(String);
|
|
95
|
+
}
|
|
96
|
+
let possibleTickValues;
|
|
97
|
+
|
|
98
|
+
// If we have discrete data, we can use the indices as possible tick values
|
|
99
|
+
if (axisData && Array.isArray(axisData) && (typeof axisData[0] === 'string' || typeof axisData[0] === 'number' && isCategoricalScale(xScale))) {
|
|
100
|
+
possibleTickValues = Array.from({
|
|
101
|
+
length: axisData.length
|
|
102
|
+
}, (_, i) => i);
|
|
103
|
+
}
|
|
104
|
+
return getAxisTicksData({
|
|
105
|
+
scaleFunction: xScale,
|
|
106
|
+
ticks,
|
|
107
|
+
requestedTickCount,
|
|
108
|
+
categories,
|
|
109
|
+
possibleTickValues,
|
|
110
|
+
tickInterval: tickInterval,
|
|
111
|
+
options: {
|
|
112
|
+
minStep: tickMinStep,
|
|
113
|
+
maxStep: tickMaxStep
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
}, [ticks, xScale, requestedTickCount, tickInterval, tickMinStep, tickMaxStep, xAxis == null ? void 0 : xAxis.data]);
|
|
117
|
+
const chartTextData = useMemo(() => {
|
|
118
|
+
if (!axisBounds) return null;
|
|
119
|
+
return ticksData.map(tick => {
|
|
120
|
+
const tickOffset = tickMarkLabelGap + (showTickMarks ? tickMarkSize : 0);
|
|
121
|
+
const availableSpace = axisBounds.height - tickOffset;
|
|
122
|
+
const labelOffset = availableSpace / 2;
|
|
123
|
+
const labelY = position === 'top' ? axisBounds.y + labelOffset - tickOffset : axisBounds.y + labelOffset + tickOffset;
|
|
124
|
+
return {
|
|
125
|
+
x: tick.position,
|
|
126
|
+
y: labelY,
|
|
127
|
+
label: String(formatTick(tick.tick)),
|
|
128
|
+
chartTextProps: {
|
|
129
|
+
className: classNames == null ? void 0 : classNames.tickLabel,
|
|
130
|
+
color: theme.color.fgMuted,
|
|
131
|
+
verticalAlignment: 'middle',
|
|
132
|
+
style: styles == null ? void 0 : styles.tickLabel,
|
|
133
|
+
horizontalAlignment: 'center'
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
});
|
|
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,
|
|
148
|
+
children: ticksData.map((tick, index) => {
|
|
149
|
+
const verticalLine = /*#__PURE__*/_jsx(ReferenceLine, {
|
|
150
|
+
LineComponent: GridLineComponent,
|
|
151
|
+
dataX: tick.tick
|
|
152
|
+
});
|
|
153
|
+
return /*#__PURE__*/_jsx(G, {
|
|
154
|
+
children: verticalLine
|
|
155
|
+
}, "grid-" + tick.tick + "-" + index);
|
|
156
|
+
})
|
|
157
|
+
}), chartTextData && /*#__PURE__*/_jsx(SmartChartTextGroup, {
|
|
158
|
+
prioritizeEndLabels: true,
|
|
159
|
+
labels: chartTextData,
|
|
160
|
+
minGap: minTickLabelGap
|
|
161
|
+
}), axisBounds && showTickMarks && /*#__PURE__*/_jsx(G, {
|
|
162
|
+
"data-testid": "tick-marks",
|
|
163
|
+
children: ticksData.map((tick, index) => {
|
|
164
|
+
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);
|
|
173
|
+
})
|
|
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
|
+
}));
|
|
181
|
+
});
|
|
@@ -0,0 +1,170 @@
|
|
|
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); }
|
|
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, useCallback, useEffect, useId, useMemo } from 'react';
|
|
5
|
+
import Animated, { useAnimatedStyle, useSharedValue } from 'react-native-reanimated';
|
|
6
|
+
import { G, Line } from 'react-native-svg';
|
|
7
|
+
import { useTheme } from '@coinbase/cds-mobile/hooks/useTheme';
|
|
8
|
+
import { useCartesianChartContext } from '../ChartProvider';
|
|
9
|
+
import { DottedLine } from '../line/DottedLine';
|
|
10
|
+
import { ReferenceLine } from '../line/ReferenceLine';
|
|
11
|
+
import { SmartChartTextGroup } from '../text/SmartChartTextGroup';
|
|
12
|
+
import { getAxisTicksData, isCategoricalScale } from '../utils';
|
|
13
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
14
|
+
const AnimatedG = Animated.createAnimatedComponent(G);
|
|
15
|
+
export const YAxis = /*#__PURE__*/memo(_ref => {
|
|
16
|
+
let {
|
|
17
|
+
axisId,
|
|
18
|
+
position = 'right',
|
|
19
|
+
showGrid,
|
|
20
|
+
requestedTickCount = 5,
|
|
21
|
+
ticks,
|
|
22
|
+
tickLabelFormatter,
|
|
23
|
+
styles,
|
|
24
|
+
classNames,
|
|
25
|
+
GridLineComponent = DottedLine,
|
|
26
|
+
tickMarkLabelGap = 8,
|
|
27
|
+
width = 44,
|
|
28
|
+
minTickLabelGap = 0,
|
|
29
|
+
showTickMarks,
|
|
30
|
+
showLine,
|
|
31
|
+
tickMarkSize = 4,
|
|
32
|
+
tickInterval
|
|
33
|
+
} = _ref,
|
|
34
|
+
props = _objectWithoutPropertiesLoose(_ref, _excluded);
|
|
35
|
+
const theme = useTheme();
|
|
36
|
+
const registrationId = useId();
|
|
37
|
+
const {
|
|
38
|
+
animate,
|
|
39
|
+
getYScale,
|
|
40
|
+
getYAxis,
|
|
41
|
+
registerAxis,
|
|
42
|
+
unregisterAxis,
|
|
43
|
+
getAxisBounds
|
|
44
|
+
} = useCartesianChartContext();
|
|
45
|
+
const yScale = getYScale(axisId);
|
|
46
|
+
const yAxis = getYAxis(axisId);
|
|
47
|
+
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]);
|
|
59
|
+
useEffect(() => {
|
|
60
|
+
registerAxis(registrationId, position, width);
|
|
61
|
+
return () => unregisterAxis(registrationId);
|
|
62
|
+
}, [registrationId, registerAxis, unregisterAxis, position, width]);
|
|
63
|
+
const formatTick = useCallback(value => {
|
|
64
|
+
var _tickLabelFormatter;
|
|
65
|
+
// If we have string labels and no custom formatter, use the labels
|
|
66
|
+
const axisData = yAxis == null ? void 0 : yAxis.data;
|
|
67
|
+
const hasStringLabels = axisData && Array.isArray(axisData) && typeof axisData[0] === 'string';
|
|
68
|
+
if (hasStringLabels && !tickLabelFormatter && axisData[value] !== undefined) {
|
|
69
|
+
// Use the string label from the data array
|
|
70
|
+
return axisData[value];
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Otherwise use the formatter (if provided) or the value itself
|
|
74
|
+
return (_tickLabelFormatter = tickLabelFormatter == null ? void 0 : tickLabelFormatter(value)) != null ? _tickLabelFormatter : value;
|
|
75
|
+
}, [yAxis == null ? void 0 : yAxis.data, tickLabelFormatter]);
|
|
76
|
+
|
|
77
|
+
// Use D3 to get the ticks data
|
|
78
|
+
// Result contains each tick value and its axis position
|
|
79
|
+
const ticksData = useMemo(() => {
|
|
80
|
+
if (!yScale) return [];
|
|
81
|
+
|
|
82
|
+
// Check if we have string labels
|
|
83
|
+
const axisData = yAxis == null ? void 0 : yAxis.data;
|
|
84
|
+
const hasStringLabels = axisData && Array.isArray(axisData) && typeof axisData[0] === 'string';
|
|
85
|
+
|
|
86
|
+
// For band scales, we need categories
|
|
87
|
+
let categories;
|
|
88
|
+
if (hasStringLabels) {
|
|
89
|
+
categories = axisData;
|
|
90
|
+
} else if (isCategoricalScale(yScale)) {
|
|
91
|
+
// For band scales without explicit string data, generate numeric categories
|
|
92
|
+
// based on the domain of the scale
|
|
93
|
+
const domain = yScale.domain();
|
|
94
|
+
categories = domain.map(String);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// For numeric data or no explicit data, use default tick generation
|
|
98
|
+
return getAxisTicksData({
|
|
99
|
+
scaleFunction: yScale,
|
|
100
|
+
ticks,
|
|
101
|
+
requestedTickCount: tickInterval !== undefined ? undefined : requestedTickCount != null ? requestedTickCount : 5,
|
|
102
|
+
categories,
|
|
103
|
+
possibleTickValues: axisData && Array.isArray(axisData) && typeof axisData[0] === 'number' ? axisData : undefined,
|
|
104
|
+
tickInterval: tickInterval
|
|
105
|
+
});
|
|
106
|
+
}, [ticks, yScale, requestedTickCount, tickInterval, yAxis == null ? void 0 : yAxis.data]);
|
|
107
|
+
const chartTextData = useMemo(() => {
|
|
108
|
+
if (!axisBounds) return null;
|
|
109
|
+
return ticksData.map(tick => {
|
|
110
|
+
const tickOffset = tickMarkLabelGap + (showTickMarks ? tickMarkSize : 0);
|
|
111
|
+
const labelX = position === 'left' ? axisBounds.x + axisBounds.width - tickOffset : axisBounds.x + tickOffset;
|
|
112
|
+
return {
|
|
113
|
+
x: labelX,
|
|
114
|
+
y: tick.position,
|
|
115
|
+
label: String(formatTick(tick.tick)),
|
|
116
|
+
chartTextProps: {
|
|
117
|
+
className: classNames == null ? void 0 : classNames.tickLabel,
|
|
118
|
+
color: theme.color.fgMuted,
|
|
119
|
+
verticalAlignment: 'middle',
|
|
120
|
+
style: styles == null ? void 0 : styles.tickLabel,
|
|
121
|
+
horizontalAlignment: position === 'left' ? 'right' : 'left'
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
});
|
|
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,
|
|
136
|
+
children: ticksData.map((tick, index) => {
|
|
137
|
+
const horizontalLine = /*#__PURE__*/_jsx(ReferenceLine, {
|
|
138
|
+
LineComponent: GridLineComponent,
|
|
139
|
+
dataY: tick.tick,
|
|
140
|
+
yAxisId: axisId
|
|
141
|
+
});
|
|
142
|
+
return /*#__PURE__*/_jsx(G, {
|
|
143
|
+
children: horizontalLine
|
|
144
|
+
}, "grid-" + tick.tick + "-" + index);
|
|
145
|
+
})
|
|
146
|
+
}), chartTextData && /*#__PURE__*/_jsx(SmartChartTextGroup, {
|
|
147
|
+
prioritizeEndLabels: true,
|
|
148
|
+
labels: chartTextData,
|
|
149
|
+
minGap: minTickLabelGap
|
|
150
|
+
}), axisBounds && showTickMarks && /*#__PURE__*/_jsx(G, {
|
|
151
|
+
"data-testid": "tick-marks",
|
|
152
|
+
children: ticksData.map((tick, index) => {
|
|
153
|
+
const tickX = position === 'left' ? axisBounds.x + axisBounds.width : axisBounds.x;
|
|
154
|
+
const tickMarkSizePixels = tickMarkSize;
|
|
155
|
+
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);
|
|
162
|
+
})
|
|
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
|
+
}));
|
|
170
|
+
});
|