@coinbase/cds-mobile-visualization 3.4.0-beta.2 → 3.4.0-beta.20
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 +122 -0
- package/dts/chart/CartesianChart.d.ts +92 -34
- package/dts/chart/CartesianChart.d.ts.map +1 -1
- package/dts/chart/ChartContextBridge.d.ts +28 -0
- package/dts/chart/ChartContextBridge.d.ts.map +1 -0
- package/dts/chart/ChartProvider.d.ts +3 -0
- package/dts/chart/ChartProvider.d.ts.map +1 -1
- package/dts/chart/Path.d.ts +97 -32
- package/dts/chart/Path.d.ts.map +1 -1
- package/dts/chart/PeriodSelector.d.ts +6 -13
- package/dts/chart/PeriodSelector.d.ts.map +1 -1
- package/dts/chart/area/Area.d.ts +39 -28
- package/dts/chart/area/Area.d.ts.map +1 -1
- package/dts/chart/area/AreaChart.d.ts +51 -10
- package/dts/chart/area/AreaChart.d.ts.map +1 -1
- package/dts/chart/area/DottedArea.d.ts +21 -2
- package/dts/chart/area/DottedArea.d.ts.map +1 -1
- package/dts/chart/area/GradientArea.d.ts +19 -13
- package/dts/chart/area/GradientArea.d.ts.map +1 -1
- package/dts/chart/area/SolidArea.d.ts +17 -2
- package/dts/chart/area/SolidArea.d.ts.map +1 -1
- package/dts/chart/axis/Axis.d.ts +86 -118
- package/dts/chart/axis/Axis.d.ts.map +1 -1
- package/dts/chart/axis/DefaultAxisTickLabel.d.ts +8 -0
- package/dts/chart/axis/DefaultAxisTickLabel.d.ts.map +1 -0
- package/dts/chart/axis/XAxis.d.ts +1 -1
- package/dts/chart/axis/XAxis.d.ts.map +1 -1
- package/dts/chart/axis/YAxis.d.ts +2 -2
- package/dts/chart/axis/YAxis.d.ts.map +1 -1
- package/dts/chart/axis/index.d.ts +1 -0
- package/dts/chart/axis/index.d.ts.map +1 -1
- package/dts/chart/bar/Bar.d.ts +49 -12
- package/dts/chart/bar/Bar.d.ts.map +1 -1
- package/dts/chart/bar/BarChart.d.ts +40 -19
- package/dts/chart/bar/BarChart.d.ts.map +1 -1
- package/dts/chart/bar/BarPlot.d.ts +3 -1
- package/dts/chart/bar/BarPlot.d.ts.map +1 -1
- package/dts/chart/bar/BarStack.d.ts +41 -46
- package/dts/chart/bar/BarStack.d.ts.map +1 -1
- package/dts/chart/bar/BarStackGroup.d.ts +2 -0
- package/dts/chart/bar/BarStackGroup.d.ts.map +1 -1
- package/dts/chart/bar/DefaultBar.d.ts +1 -1
- package/dts/chart/bar/DefaultBar.d.ts.map +1 -1
- package/dts/chart/bar/DefaultBarStack.d.ts.map +1 -1
- package/dts/chart/gradient/Gradient.d.ts +25 -0
- package/dts/chart/gradient/Gradient.d.ts.map +1 -0
- package/dts/chart/gradient/index.d.ts +2 -0
- package/dts/chart/gradient/index.d.ts.map +1 -0
- package/dts/chart/index.d.ts +4 -1
- package/dts/chart/index.d.ts.map +1 -1
- package/dts/chart/legend/DefaultLegendEntry.d.ts +5 -0
- package/dts/chart/legend/DefaultLegendEntry.d.ts.map +1 -0
- package/dts/chart/legend/DefaultLegendShape.d.ts +5 -0
- package/dts/chart/legend/DefaultLegendShape.d.ts.map +1 -0
- package/dts/chart/legend/Legend.d.ts +168 -0
- package/dts/chart/legend/Legend.d.ts.map +1 -0
- package/dts/chart/legend/index.d.ts +4 -0
- package/dts/chart/legend/index.d.ts.map +1 -0
- package/dts/chart/line/DefaultReferenceLineLabel.d.ts +9 -0
- package/dts/chart/line/DefaultReferenceLineLabel.d.ts.map +1 -0
- package/dts/chart/line/DottedLine.d.ts +13 -5
- package/dts/chart/line/DottedLine.d.ts.map +1 -1
- package/dts/chart/line/Line.d.ts +61 -27
- package/dts/chart/line/Line.d.ts.map +1 -1
- package/dts/chart/line/LineChart.d.ts +43 -9
- package/dts/chart/line/LineChart.d.ts.map +1 -1
- package/dts/chart/line/ReferenceLine.d.ts +68 -20
- package/dts/chart/line/ReferenceLine.d.ts.map +1 -1
- package/dts/chart/line/SolidLine.d.ts +8 -5
- package/dts/chart/line/SolidLine.d.ts.map +1 -1
- package/dts/chart/line/index.d.ts +1 -1
- package/dts/chart/line/index.d.ts.map +1 -1
- package/dts/chart/point/DefaultPointLabel.d.ts +10 -0
- package/dts/chart/point/DefaultPointLabel.d.ts.map +1 -0
- package/dts/chart/point/Point.d.ts +136 -0
- package/dts/chart/point/Point.d.ts.map +1 -0
- package/dts/chart/point/index.d.ts +3 -0
- package/dts/chart/point/index.d.ts.map +1 -0
- package/dts/chart/scrubber/DefaultScrubberBeacon.d.ts +38 -0
- package/dts/chart/scrubber/DefaultScrubberBeacon.d.ts.map +1 -0
- package/dts/chart/scrubber/DefaultScrubberBeaconLabel.d.ts +12 -0
- package/dts/chart/scrubber/DefaultScrubberBeaconLabel.d.ts.map +1 -0
- package/dts/chart/scrubber/DefaultScrubberLabel.d.ts +11 -0
- package/dts/chart/scrubber/DefaultScrubberLabel.d.ts.map +1 -0
- package/dts/chart/scrubber/Scrubber.d.ts +230 -42
- package/dts/chart/scrubber/Scrubber.d.ts.map +1 -1
- package/dts/chart/scrubber/ScrubberBeaconGroup.d.ts +54 -0
- package/dts/chart/scrubber/ScrubberBeaconGroup.d.ts.map +1 -0
- package/dts/chart/scrubber/ScrubberBeaconLabelGroup.d.ts +46 -0
- package/dts/chart/scrubber/ScrubberBeaconLabelGroup.d.ts.map +1 -0
- package/dts/chart/scrubber/ScrubberProvider.d.ts +6 -3
- package/dts/chart/scrubber/ScrubberProvider.d.ts.map +1 -1
- package/dts/chart/scrubber/index.d.ts +3 -0
- package/dts/chart/scrubber/index.d.ts.map +1 -1
- package/dts/chart/text/ChartText.d.ts +151 -77
- package/dts/chart/text/ChartText.d.ts.map +1 -1
- package/dts/chart/text/{SmartChartTextGroup.d.ts → ChartTextGroup.d.ts} +9 -3
- package/dts/chart/text/ChartTextGroup.d.ts.map +1 -0
- package/dts/chart/text/index.d.ts +1 -1
- package/dts/chart/text/index.d.ts.map +1 -1
- package/dts/chart/utils/axis.d.ts +25 -1
- package/dts/chart/utils/axis.d.ts.map +1 -1
- package/dts/chart/utils/bar.d.ts +34 -0
- package/dts/chart/utils/bar.d.ts.map +1 -1
- package/dts/chart/utils/chart.d.ts +52 -7
- package/dts/chart/utils/chart.d.ts.map +1 -1
- package/dts/chart/utils/context.d.ts +28 -7
- package/dts/chart/utils/context.d.ts.map +1 -1
- package/dts/chart/utils/gradient.d.ts +117 -0
- package/dts/chart/utils/gradient.d.ts.map +1 -0
- package/dts/chart/utils/index.d.ts +3 -0
- package/dts/chart/utils/index.d.ts.map +1 -1
- package/dts/chart/utils/path.d.ts +59 -0
- package/dts/chart/utils/path.d.ts.map +1 -1
- package/dts/chart/utils/point.d.ts +71 -7
- package/dts/chart/utils/point.d.ts.map +1 -1
- package/dts/chart/utils/scale.d.ts +102 -0
- package/dts/chart/utils/scale.d.ts.map +1 -1
- package/dts/chart/utils/scrubber.d.ts +40 -0
- package/dts/chart/utils/scrubber.d.ts.map +1 -0
- package/dts/chart/utils/transition.d.ts +178 -0
- package/dts/chart/utils/transition.d.ts.map +1 -0
- package/esm/chart/CartesianChart.js +199 -75
- package/esm/chart/ChartContextBridge.js +159 -0
- package/esm/chart/ChartProvider.js +2 -2
- package/esm/chart/Path.js +200 -114
- package/esm/chart/PeriodSelector.js +7 -3
- package/esm/chart/__stories__/CartesianChart.stories.js +307 -134
- package/esm/chart/__stories__/ChartTransitions.stories.js +629 -0
- package/esm/chart/__stories__/PeriodSelector.stories.js +201 -75
- package/esm/chart/area/Area.js +27 -35
- package/esm/chart/area/AreaChart.js +17 -12
- package/esm/chart/area/DottedArea.js +64 -108
- package/esm/chart/area/GradientArea.js +37 -91
- package/esm/chart/area/SolidArea.js +24 -8
- package/esm/chart/area/__stories__/AreaChart.stories.js +1 -1
- package/esm/chart/axis/Axis.js +5 -39
- package/esm/chart/axis/DefaultAxisTickLabel.js +11 -0
- package/esm/chart/axis/XAxis.js +148 -66
- package/esm/chart/axis/YAxis.js +149 -65
- package/esm/chart/axis/__stories__/Axis.stories.js +259 -1
- package/esm/chart/axis/index.js +1 -0
- package/esm/chart/bar/Bar.js +7 -1
- package/esm/chart/bar/BarChart.js +17 -37
- package/esm/chart/bar/BarPlot.js +43 -35
- package/esm/chart/bar/BarStack.js +84 -37
- package/esm/chart/bar/BarStackGroup.js +7 -17
- package/esm/chart/bar/DefaultBar.js +29 -51
- package/esm/chart/bar/DefaultBarStack.js +34 -58
- package/esm/chart/bar/__stories__/BarChart.stories.js +948 -88
- package/esm/chart/gradient/Gradient.js +53 -0
- package/esm/chart/gradient/index.js +1 -0
- package/esm/chart/index.js +4 -1
- package/esm/chart/legend/DefaultLegendEntry.js +42 -0
- package/esm/chart/legend/DefaultLegendShape.js +64 -0
- package/esm/chart/legend/Legend.js +59 -0
- package/esm/chart/legend/__stories__/Legend.stories.js +574 -0
- package/esm/chart/legend/index.js +3 -0
- package/esm/chart/line/DefaultReferenceLineLabel.js +66 -0
- package/esm/chart/line/DottedLine.js +31 -14
- package/esm/chart/line/Line.js +96 -68
- package/esm/chart/line/LineChart.js +21 -14
- package/esm/chart/line/ReferenceLine.js +80 -63
- package/esm/chart/line/SolidLine.js +27 -10
- package/esm/chart/line/__stories__/LineChart.stories.js +1748 -2048
- package/esm/chart/line/__stories__/ReferenceLine.stories.js +177 -28
- package/esm/chart/line/index.js +1 -1
- package/esm/chart/point/DefaultPointLabel.js +39 -0
- package/esm/chart/point/Point.js +186 -0
- package/esm/chart/point/index.js +2 -0
- package/esm/chart/scrubber/DefaultScrubberBeacon.js +180 -0
- package/esm/chart/scrubber/DefaultScrubberBeaconLabel.js +43 -0
- package/esm/chart/scrubber/DefaultScrubberLabel.js +28 -0
- package/esm/chart/scrubber/Scrubber.js +130 -144
- package/esm/chart/scrubber/ScrubberBeaconGroup.js +165 -0
- package/esm/chart/scrubber/ScrubberBeaconLabelGroup.js +208 -0
- package/esm/chart/scrubber/ScrubberProvider.js +46 -54
- package/esm/chart/scrubber/__stories__/Scrubber.stories.js +760 -0
- package/esm/chart/scrubber/index.js +3 -1
- package/esm/chart/text/ChartText.js +242 -174
- package/esm/chart/text/{SmartChartTextGroup.js → ChartTextGroup.js} +6 -5
- package/esm/chart/text/index.js +1 -1
- package/esm/chart/utils/axis.js +47 -31
- package/esm/chart/utils/bar.js +43 -0
- package/esm/chart/utils/chart.js +57 -3
- package/esm/chart/utils/gradient.js +305 -0
- package/esm/chart/utils/index.js +3 -0
- package/esm/chart/utils/path.js +84 -8
- package/esm/chart/utils/point.js +171 -17
- package/esm/chart/utils/scale.js +242 -2
- package/esm/chart/utils/scrubber.js +146 -0
- package/esm/chart/utils/transition.js +220 -0
- package/esm/sparkline/__figma__/Sparkline.figma.js +1 -1
- package/esm/sparkline/__stories__/Sparkline.stories.js +11 -7
- package/esm/sparkline/__stories__/SparklineGradient.stories.js +7 -4
- package/esm/sparkline/sparkline-interactive/__figma__/SparklineInteractive.figma.js +1 -1
- package/esm/sparkline/sparkline-interactive/__stories__/SparklineInteractive.stories.js +51 -26
- package/esm/sparkline/sparkline-interactive-header/__figma__/SparklineInteractiveHeader.figma.js +1 -1
- package/esm/sparkline/sparkline-interactive-header/__stories__/SparklineInteractiveHeader.stories.js +17 -9
- package/package.json +15 -10
- package/dts/chart/Point.d.ts +0 -103
- package/dts/chart/Point.d.ts.map +0 -1
- package/dts/chart/line/GradientLine.d.ts +0 -45
- package/dts/chart/line/GradientLine.d.ts.map +0 -1
- package/dts/chart/scrubber/ScrubberBeacon.d.ts +0 -75
- package/dts/chart/scrubber/ScrubberBeacon.d.ts.map +0 -1
- package/dts/chart/text/SmartChartTextGroup.d.ts.map +0 -1
- package/esm/chart/Point.js +0 -111
- package/esm/chart/__stories__/Chart.stories.js +0 -79
- package/esm/chart/line/GradientLine.js +0 -62
- package/esm/chart/scrubber/ScrubberBeacon.js +0 -199
package/esm/chart/axis/XAxis.js
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
const _excluded = ["position", "showGrid", "requestedTickCount", "ticks", "tickLabelFormatter", "
|
|
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", "bandGridLinePlacement", "bandTickMarkPlacement"];
|
|
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
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
8
|
+
import { SolidLine } from '../line/SolidLine';
|
|
9
|
+
import { ChartText } from '../text/ChartText';
|
|
10
|
+
import { ChartTextGroup } from '../text/ChartTextGroup';
|
|
11
|
+
import { getAxisTicksData, getPointOnScale, isCategoricalScale, lineToPath, toPointAnchor } from '../utils';
|
|
12
|
+
import { DefaultAxisTickLabel } from './DefaultAxisTickLabel';
|
|
13
13
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
14
|
-
const
|
|
14
|
+
const AXIS_HEIGHT = 32;
|
|
15
|
+
const LABEL_SIZE = 20;
|
|
15
16
|
export const XAxis = /*#__PURE__*/memo(_ref => {
|
|
16
17
|
let {
|
|
17
18
|
position = 'bottom',
|
|
@@ -19,24 +20,30 @@ export const XAxis = /*#__PURE__*/memo(_ref => {
|
|
|
19
20
|
requestedTickCount,
|
|
20
21
|
ticks,
|
|
21
22
|
tickLabelFormatter,
|
|
22
|
-
|
|
23
|
-
classNames,
|
|
23
|
+
TickLabelComponent = DefaultAxisTickLabel,
|
|
24
24
|
GridLineComponent = DottedLine,
|
|
25
|
+
LineComponent = SolidLine,
|
|
26
|
+
TickMarkLineComponent = SolidLine,
|
|
25
27
|
tickMarkLabelGap = 2,
|
|
26
|
-
height = 32,
|
|
27
28
|
minTickLabelGap = 4,
|
|
28
29
|
showTickMarks,
|
|
29
30
|
showLine,
|
|
30
31
|
tickMarkSize = 4,
|
|
31
32
|
tickInterval = 32,
|
|
32
33
|
tickMinStep = 1,
|
|
33
|
-
tickMaxStep
|
|
34
|
+
tickMaxStep,
|
|
35
|
+
label,
|
|
36
|
+
labelGap = 4,
|
|
37
|
+
height = label ? AXIS_HEIGHT + LABEL_SIZE : AXIS_HEIGHT,
|
|
38
|
+
bandGridLinePlacement = 'edges',
|
|
39
|
+
bandTickMarkPlacement = 'middle'
|
|
34
40
|
} = _ref,
|
|
35
41
|
props = _objectWithoutPropertiesLoose(_ref, _excluded);
|
|
36
42
|
const theme = useTheme();
|
|
37
43
|
const registrationId = useId();
|
|
38
44
|
const {
|
|
39
45
|
animate,
|
|
46
|
+
drawingArea,
|
|
40
47
|
getXScale,
|
|
41
48
|
getXAxis,
|
|
42
49
|
registerAxis,
|
|
@@ -46,17 +53,6 @@ export const XAxis = /*#__PURE__*/memo(_ref => {
|
|
|
46
53
|
const xScale = getXScale();
|
|
47
54
|
const xAxis = getXAxis();
|
|
48
55
|
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
56
|
useEffect(() => {
|
|
61
57
|
registerAxis(registrationId, position, height);
|
|
62
58
|
return () => unregisterAxis(registrationId);
|
|
@@ -114,68 +110,154 @@ export const XAxis = /*#__PURE__*/memo(_ref => {
|
|
|
114
110
|
}
|
|
115
111
|
});
|
|
116
112
|
}, [ticks, xScale, requestedTickCount, tickInterval, tickMinStep, tickMaxStep, xAxis == null ? void 0 : xAxis.data]);
|
|
113
|
+
const isBandScale = useMemo(() => {
|
|
114
|
+
if (!xScale) return false;
|
|
115
|
+
return isCategoricalScale(xScale);
|
|
116
|
+
}, [xScale]);
|
|
117
|
+
|
|
118
|
+
// Compute grid line positions (including bounds closing line for band scales)
|
|
119
|
+
const gridLinePositions = useMemo(() => {
|
|
120
|
+
if (!xScale) return [];
|
|
121
|
+
return ticksData.flatMap((tick, index) => {
|
|
122
|
+
if (!isBandScale) {
|
|
123
|
+
return [{
|
|
124
|
+
x: tick.position,
|
|
125
|
+
key: "grid-" + tick.tick + "-" + index
|
|
126
|
+
}];
|
|
127
|
+
}
|
|
128
|
+
const bandScale = xScale;
|
|
129
|
+
const isLastTick = index === ticksData.length - 1;
|
|
130
|
+
const isEdges = bandGridLinePlacement === 'edges';
|
|
131
|
+
const startX = getPointOnScale(tick.tick, bandScale, toPointAnchor(bandGridLinePlacement));
|
|
132
|
+
const positions = [{
|
|
133
|
+
x: startX,
|
|
134
|
+
key: "grid-" + tick.tick + "-" + index
|
|
135
|
+
}];
|
|
136
|
+
|
|
137
|
+
// For edges on last tick, add the closing line at stepEnd
|
|
138
|
+
if (isLastTick && isEdges) {
|
|
139
|
+
const endX = getPointOnScale(tick.tick, bandScale, 'stepEnd');
|
|
140
|
+
positions.push({
|
|
141
|
+
x: endX,
|
|
142
|
+
key: "grid-" + tick.tick + "-" + index + "-end"
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
return positions;
|
|
146
|
+
});
|
|
147
|
+
}, [ticksData, xScale, isBandScale, bandGridLinePlacement]);
|
|
148
|
+
|
|
149
|
+
// Compute tick mark positions (including bounds closing tick for band scales)
|
|
150
|
+
const tickMarkPositions = useMemo(() => {
|
|
151
|
+
if (!xScale) return [];
|
|
152
|
+
return ticksData.flatMap((tick, index) => {
|
|
153
|
+
if (!isBandScale) {
|
|
154
|
+
return [{
|
|
155
|
+
x: tick.position,
|
|
156
|
+
key: "tick-mark-" + tick.tick + "-" + index
|
|
157
|
+
}];
|
|
158
|
+
}
|
|
159
|
+
const bandScale = xScale;
|
|
160
|
+
const isLastTick = index === ticksData.length - 1;
|
|
161
|
+
const isEdges = bandTickMarkPlacement === 'edges';
|
|
162
|
+
const startX = getPointOnScale(tick.tick, bandScale, toPointAnchor(bandTickMarkPlacement));
|
|
163
|
+
const positions = [{
|
|
164
|
+
x: startX,
|
|
165
|
+
key: "tick-mark-" + tick.tick + "-" + index
|
|
166
|
+
}];
|
|
167
|
+
|
|
168
|
+
// For edges on last tick, add the closing tick mark at stepEnd
|
|
169
|
+
if (isLastTick && isEdges) {
|
|
170
|
+
const endX = getPointOnScale(tick.tick, bandScale, 'stepEnd');
|
|
171
|
+
positions.push({
|
|
172
|
+
x: endX,
|
|
173
|
+
key: "tick-mark-" + tick.tick + "-" + index + "-end"
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
return positions;
|
|
177
|
+
});
|
|
178
|
+
}, [ticksData, xScale, isBandScale, bandTickMarkPlacement]);
|
|
117
179
|
const chartTextData = useMemo(() => {
|
|
118
180
|
if (!axisBounds) return null;
|
|
119
181
|
return ticksData.map(tick => {
|
|
120
182
|
const tickOffset = tickMarkLabelGap + (showTickMarks ? tickMarkSize : 0);
|
|
121
|
-
|
|
183
|
+
|
|
184
|
+
// Use AXIS_HEIGHT for centering, not full axisBounds.height
|
|
185
|
+
// This ensures tick labels are centered in the axis area, not including label space
|
|
186
|
+
const availableSpace = AXIS_HEIGHT - tickOffset;
|
|
122
187
|
const labelOffset = availableSpace / 2;
|
|
123
|
-
const labelY = position === 'top' ? axisBounds.y +
|
|
188
|
+
const labelY = position === 'top' ? axisBounds.y + axisBounds.height - tickOffset - labelOffset : axisBounds.y + labelOffset + tickOffset;
|
|
124
189
|
return {
|
|
125
190
|
x: tick.position,
|
|
126
191
|
y: labelY,
|
|
127
192
|
label: String(formatTick(tick.tick)),
|
|
128
193
|
chartTextProps: {
|
|
129
|
-
className: classNames == null ? void 0 : classNames.tickLabel,
|
|
130
194
|
color: theme.color.fgMuted,
|
|
131
195
|
verticalAlignment: 'middle',
|
|
132
|
-
style: styles == null ? void 0 : styles.tickLabel,
|
|
133
196
|
horizontalAlignment: 'center'
|
|
134
197
|
}
|
|
135
198
|
};
|
|
136
199
|
});
|
|
137
|
-
}, [axisBounds, ticksData, theme.color.fgMuted, tickMarkLabelGap, showTickMarks, tickMarkSize, position, formatTick
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
200
|
+
}, [axisBounds, ticksData, theme.color.fgMuted, tickMarkLabelGap, showTickMarks, tickMarkSize, position, formatTick]);
|
|
201
|
+
if (!xScale || !axisBounds) return;
|
|
202
|
+
const labelX = axisBounds.x + axisBounds.width / 2;
|
|
203
|
+
const labelY = position === 'bottom' ? axisBounds.y + axisBounds.height - LABEL_SIZE / 2 : axisBounds.y + LABEL_SIZE / 2;
|
|
204
|
+
|
|
205
|
+
// Pre-compute tick mark Y coordinates
|
|
206
|
+
const tickYTop = axisBounds.y;
|
|
207
|
+
const tickYBottom = axisBounds.y + axisBounds.height;
|
|
208
|
+
const tickYStart = position === 'bottom' ? tickYTop : tickYBottom;
|
|
209
|
+
const tickYEnd = position === 'bottom' ? tickYTop + tickMarkSize : tickYBottom - tickMarkSize;
|
|
210
|
+
|
|
211
|
+
// Note: Unlike web, mobile renders grid lines and tick marks immediately without fade animation.
|
|
212
|
+
// This is because Skia can measure text dimensions synchronously, so there's no need to hide
|
|
213
|
+
// elements while waiting for measurements (web uses async ResizeObserver).
|
|
214
|
+
return /*#__PURE__*/_jsxs(Group, {
|
|
215
|
+
children: [showGrid && /*#__PURE__*/_jsx(Group, {
|
|
216
|
+
children: gridLinePositions.map(_ref2 => {
|
|
217
|
+
let {
|
|
218
|
+
x,
|
|
219
|
+
key
|
|
220
|
+
} = _ref2;
|
|
221
|
+
return /*#__PURE__*/_jsx(GridLineComponent, {
|
|
222
|
+
animate: false,
|
|
223
|
+
clipPath: null,
|
|
224
|
+
d: lineToPath(x, drawingArea.y, x, drawingArea.y + drawingArea.height),
|
|
225
|
+
stroke: theme.color.bgLine
|
|
226
|
+
}, key);
|
|
156
227
|
})
|
|
157
|
-
}), chartTextData && /*#__PURE__*/_jsx(
|
|
228
|
+
}), chartTextData && /*#__PURE__*/_jsx(ChartTextGroup, {
|
|
158
229
|
prioritizeEndLabels: true,
|
|
230
|
+
LabelComponent: TickLabelComponent,
|
|
159
231
|
labels: chartTextData,
|
|
160
232
|
minGap: minTickLabelGap
|
|
161
|
-
}), axisBounds && showTickMarks && /*#__PURE__*/_jsx(
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
return /*#__PURE__*/_jsx(
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
233
|
+
}), axisBounds && showTickMarks && /*#__PURE__*/_jsx(Group, {
|
|
234
|
+
children: tickMarkPositions.map(_ref3 => {
|
|
235
|
+
let {
|
|
236
|
+
x,
|
|
237
|
+
key
|
|
238
|
+
} = _ref3;
|
|
239
|
+
return /*#__PURE__*/_jsx(TickMarkLineComponent, {
|
|
240
|
+
animate: false,
|
|
241
|
+
clipPath: null,
|
|
242
|
+
d: lineToPath(x, tickYStart, x, tickYEnd),
|
|
243
|
+
stroke: theme.color.fg,
|
|
244
|
+
strokeCap: "square",
|
|
245
|
+
strokeWidth: 1
|
|
246
|
+
}, key);
|
|
173
247
|
})
|
|
174
|
-
}),
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
248
|
+
}), showLine && /*#__PURE__*/_jsx(LineComponent, {
|
|
249
|
+
animate: false,
|
|
250
|
+
clipPath: null,
|
|
251
|
+
d: lineToPath(axisBounds.x, position === 'bottom' ? axisBounds.y : axisBounds.y + axisBounds.height, axisBounds.x + axisBounds.width, position === 'bottom' ? axisBounds.y : axisBounds.y + axisBounds.height),
|
|
252
|
+
stroke: theme.color.fg,
|
|
253
|
+
strokeCap: "square",
|
|
254
|
+
strokeWidth: 1
|
|
255
|
+
}), label && /*#__PURE__*/_jsx(ChartText, {
|
|
256
|
+
horizontalAlignment: "center",
|
|
257
|
+
verticalAlignment: "middle",
|
|
258
|
+
x: labelX,
|
|
259
|
+
y: labelY,
|
|
260
|
+
children: label
|
|
261
|
+
})]
|
|
262
|
+
});
|
|
181
263
|
});
|
package/esm/chart/axis/YAxis.js
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
const _excluded = ["axisId", "position", "showGrid", "requestedTickCount", "ticks", "tickLabelFormatter", "
|
|
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", "bandGridLinePlacement", "bandTickMarkPlacement"];
|
|
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
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
8
|
+
import { SolidLine } from '../line/SolidLine';
|
|
9
|
+
import { ChartText } from '../text/ChartText';
|
|
10
|
+
import { ChartTextGroup } from '../text/ChartTextGroup';
|
|
11
|
+
import { getAxisTicksData, getPointOnScale, isCategoricalScale, lineToPath, toPointAnchor } from '../utils';
|
|
12
|
+
import { DefaultAxisTickLabel } from './DefaultAxisTickLabel';
|
|
13
13
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
14
|
-
const
|
|
14
|
+
const AXIS_WIDTH = 44;
|
|
15
|
+
const LABEL_SIZE = 20;
|
|
15
16
|
export const YAxis = /*#__PURE__*/memo(_ref => {
|
|
16
17
|
let {
|
|
17
18
|
axisId,
|
|
@@ -20,22 +21,28 @@ export const YAxis = /*#__PURE__*/memo(_ref => {
|
|
|
20
21
|
requestedTickCount = 5,
|
|
21
22
|
ticks,
|
|
22
23
|
tickLabelFormatter,
|
|
23
|
-
|
|
24
|
-
classNames,
|
|
24
|
+
TickLabelComponent = DefaultAxisTickLabel,
|
|
25
25
|
GridLineComponent = DottedLine,
|
|
26
|
+
LineComponent = SolidLine,
|
|
27
|
+
TickMarkLineComponent = SolidLine,
|
|
26
28
|
tickMarkLabelGap = 8,
|
|
27
|
-
width = 44,
|
|
28
29
|
minTickLabelGap = 0,
|
|
29
30
|
showTickMarks,
|
|
30
31
|
showLine,
|
|
31
32
|
tickMarkSize = 4,
|
|
32
|
-
tickInterval
|
|
33
|
+
tickInterval,
|
|
34
|
+
label,
|
|
35
|
+
labelGap = 4,
|
|
36
|
+
width = label ? AXIS_WIDTH + LABEL_SIZE : AXIS_WIDTH,
|
|
37
|
+
bandGridLinePlacement = 'edges',
|
|
38
|
+
bandTickMarkPlacement = 'middle'
|
|
33
39
|
} = _ref,
|
|
34
40
|
props = _objectWithoutPropertiesLoose(_ref, _excluded);
|
|
35
41
|
const theme = useTheme();
|
|
36
42
|
const registrationId = useId();
|
|
37
43
|
const {
|
|
38
44
|
animate,
|
|
45
|
+
drawingArea,
|
|
39
46
|
getYScale,
|
|
40
47
|
getYAxis,
|
|
41
48
|
registerAxis,
|
|
@@ -45,17 +52,6 @@ export const YAxis = /*#__PURE__*/memo(_ref => {
|
|
|
45
52
|
const yScale = getYScale(axisId);
|
|
46
53
|
const yAxis = getYAxis(axisId);
|
|
47
54
|
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
55
|
useEffect(() => {
|
|
60
56
|
registerAxis(registrationId, position, width);
|
|
61
57
|
return () => unregisterAxis(registrationId);
|
|
@@ -104,6 +100,72 @@ export const YAxis = /*#__PURE__*/memo(_ref => {
|
|
|
104
100
|
tickInterval: tickInterval
|
|
105
101
|
});
|
|
106
102
|
}, [ticks, yScale, requestedTickCount, tickInterval, yAxis == null ? void 0 : yAxis.data]);
|
|
103
|
+
const isBandScale = useMemo(() => {
|
|
104
|
+
if (!yScale) return false;
|
|
105
|
+
return isCategoricalScale(yScale);
|
|
106
|
+
}, [yScale]);
|
|
107
|
+
|
|
108
|
+
// Compute grid line positions (including bounds closing line for band scales)
|
|
109
|
+
const gridLinePositions = useMemo(() => {
|
|
110
|
+
if (!yScale) return [];
|
|
111
|
+
return ticksData.flatMap((tick, index) => {
|
|
112
|
+
if (!isBandScale) {
|
|
113
|
+
return [{
|
|
114
|
+
y: tick.position,
|
|
115
|
+
key: "grid-" + tick.tick + "-" + index
|
|
116
|
+
}];
|
|
117
|
+
}
|
|
118
|
+
const bandScale = yScale;
|
|
119
|
+
const isLastTick = index === ticksData.length - 1;
|
|
120
|
+
const isEdges = bandGridLinePlacement === 'edges';
|
|
121
|
+
const startY = getPointOnScale(tick.tick, bandScale, toPointAnchor(bandGridLinePlacement));
|
|
122
|
+
const positions = [{
|
|
123
|
+
y: startY,
|
|
124
|
+
key: "grid-" + tick.tick + "-" + index
|
|
125
|
+
}];
|
|
126
|
+
|
|
127
|
+
// For edges on last tick, add the closing line at stepEnd
|
|
128
|
+
if (isLastTick && isEdges) {
|
|
129
|
+
const endY = getPointOnScale(tick.tick, bandScale, 'stepEnd');
|
|
130
|
+
positions.push({
|
|
131
|
+
y: endY,
|
|
132
|
+
key: "grid-" + tick.tick + "-" + index + "-end"
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
return positions;
|
|
136
|
+
});
|
|
137
|
+
}, [ticksData, yScale, isBandScale, bandGridLinePlacement]);
|
|
138
|
+
|
|
139
|
+
// Compute tick mark positions (including bounds closing tick for band scales)
|
|
140
|
+
const tickMarkPositions = useMemo(() => {
|
|
141
|
+
if (!yScale) return [];
|
|
142
|
+
return ticksData.flatMap((tick, index) => {
|
|
143
|
+
if (!isBandScale) {
|
|
144
|
+
return [{
|
|
145
|
+
y: tick.position,
|
|
146
|
+
key: "tick-mark-" + tick.tick + "-" + index
|
|
147
|
+
}];
|
|
148
|
+
}
|
|
149
|
+
const bandScale = yScale;
|
|
150
|
+
const isLastTick = index === ticksData.length - 1;
|
|
151
|
+
const isEdges = bandTickMarkPlacement === 'edges';
|
|
152
|
+
const startY = getPointOnScale(tick.tick, bandScale, toPointAnchor(bandTickMarkPlacement));
|
|
153
|
+
const positions = [{
|
|
154
|
+
y: startY,
|
|
155
|
+
key: "tick-mark-" + tick.tick + "-" + index
|
|
156
|
+
}];
|
|
157
|
+
|
|
158
|
+
// For edges on last tick, add the closing tick mark at stepEnd
|
|
159
|
+
if (isLastTick && isEdges) {
|
|
160
|
+
const endY = getPointOnScale(tick.tick, bandScale, 'stepEnd');
|
|
161
|
+
positions.push({
|
|
162
|
+
y: endY,
|
|
163
|
+
key: "tick-mark-" + tick.tick + "-" + index + "-end"
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
return positions;
|
|
167
|
+
});
|
|
168
|
+
}, [ticksData, yScale, isBandScale, bandTickMarkPlacement]);
|
|
107
169
|
const chartTextData = useMemo(() => {
|
|
108
170
|
if (!axisBounds) return null;
|
|
109
171
|
return ticksData.map(tick => {
|
|
@@ -114,57 +176,79 @@ export const YAxis = /*#__PURE__*/memo(_ref => {
|
|
|
114
176
|
y: tick.position,
|
|
115
177
|
label: String(formatTick(tick.tick)),
|
|
116
178
|
chartTextProps: {
|
|
117
|
-
className: classNames == null ? void 0 : classNames.tickLabel,
|
|
118
179
|
color: theme.color.fgMuted,
|
|
119
180
|
verticalAlignment: 'middle',
|
|
120
|
-
style: styles == null ? void 0 : styles.tickLabel,
|
|
121
181
|
horizontalAlignment: position === 'left' ? 'right' : 'left'
|
|
122
182
|
}
|
|
123
183
|
};
|
|
124
184
|
});
|
|
125
|
-
}, [axisBounds, ticksData,
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
185
|
+
}, [axisBounds, ticksData, tickMarkLabelGap, showTickMarks, tickMarkSize, position, formatTick, theme.color.fgMuted]);
|
|
186
|
+
if (!yScale || !axisBounds) return;
|
|
187
|
+
const labelX = position === 'left' ? axisBounds.x + LABEL_SIZE / 2 : axisBounds.x + axisBounds.width - LABEL_SIZE / 2;
|
|
188
|
+
const labelY = axisBounds.y + axisBounds.height / 2;
|
|
189
|
+
|
|
190
|
+
// Pre-compute tick mark X coordinates
|
|
191
|
+
const tickXLeft = axisBounds.x;
|
|
192
|
+
const tickXRight = axisBounds.x + axisBounds.width;
|
|
193
|
+
const tickXStart = position === 'left' ? tickXRight : tickXLeft;
|
|
194
|
+
const tickXEnd = position === 'left' ? tickXRight - tickMarkSize : tickXLeft + tickMarkSize;
|
|
195
|
+
|
|
196
|
+
// Note: Unlike web, mobile renders grid lines and tick marks immediately without fade animation.
|
|
197
|
+
// This is because Skia can measure text dimensions synchronously, so there's no need to hide
|
|
198
|
+
// elements while waiting for measurements (web uses async ResizeObserver).
|
|
199
|
+
return /*#__PURE__*/_jsxs(Group, {
|
|
200
|
+
children: [showGrid && /*#__PURE__*/_jsx(Group, {
|
|
201
|
+
children: gridLinePositions.map(_ref2 => {
|
|
202
|
+
let {
|
|
203
|
+
y,
|
|
204
|
+
key
|
|
205
|
+
} = _ref2;
|
|
206
|
+
return /*#__PURE__*/_jsx(GridLineComponent, {
|
|
207
|
+
animate: false,
|
|
208
|
+
clipPath: null,
|
|
209
|
+
d: lineToPath(drawingArea.x, y, drawingArea.x + drawingArea.width, y),
|
|
210
|
+
stroke: theme.color.bgLine
|
|
211
|
+
}, key);
|
|
145
212
|
})
|
|
146
|
-
}), chartTextData && /*#__PURE__*/_jsx(
|
|
213
|
+
}), chartTextData && /*#__PURE__*/_jsx(ChartTextGroup, {
|
|
147
214
|
prioritizeEndLabels: true,
|
|
215
|
+
LabelComponent: TickLabelComponent,
|
|
148
216
|
labels: chartTextData,
|
|
149
217
|
minGap: minTickLabelGap
|
|
150
|
-
}), axisBounds && showTickMarks && /*#__PURE__*/_jsx(
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
return /*#__PURE__*/_jsx(
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
218
|
+
}), axisBounds && showTickMarks && /*#__PURE__*/_jsx(Group, {
|
|
219
|
+
children: tickMarkPositions.map(_ref3 => {
|
|
220
|
+
let {
|
|
221
|
+
y,
|
|
222
|
+
key
|
|
223
|
+
} = _ref3;
|
|
224
|
+
return /*#__PURE__*/_jsx(TickMarkLineComponent, {
|
|
225
|
+
animate: false,
|
|
226
|
+
clipPath: null,
|
|
227
|
+
d: lineToPath(tickXStart, y, tickXEnd, y),
|
|
228
|
+
stroke: theme.color.fg,
|
|
229
|
+
strokeCap: "square",
|
|
230
|
+
strokeWidth: 1
|
|
231
|
+
}, key);
|
|
232
|
+
})
|
|
233
|
+
}), showLine && /*#__PURE__*/_jsx(LineComponent, {
|
|
234
|
+
animate: false,
|
|
235
|
+
clipPath: null,
|
|
236
|
+
d: lineToPath(position === 'left' ? axisBounds.x + axisBounds.width : axisBounds.x, axisBounds.y, position === 'left' ? axisBounds.x + axisBounds.width : axisBounds.x, axisBounds.y + axisBounds.height),
|
|
237
|
+
stroke: theme.color.fg,
|
|
238
|
+
strokeCap: "square",
|
|
239
|
+
strokeWidth: 1
|
|
240
|
+
}), label && /*#__PURE__*/_jsx(Group, {
|
|
241
|
+
origin: vec(labelX, labelY),
|
|
242
|
+
transform: [{
|
|
243
|
+
rotate: position === 'left' ? -Math.PI / 2 : Math.PI / 2
|
|
244
|
+
}],
|
|
245
|
+
children: /*#__PURE__*/_jsx(ChartText, {
|
|
246
|
+
horizontalAlignment: "center",
|
|
247
|
+
verticalAlignment: "middle",
|
|
248
|
+
x: labelX,
|
|
249
|
+
y: labelY,
|
|
250
|
+
children: label
|
|
162
251
|
})
|
|
163
|
-
})
|
|
164
|
-
|
|
165
|
-
x2: position === 'left' ? axisBounds.x + axisBounds.width : axisBounds.x,
|
|
166
|
-
y1: axisBounds.y,
|
|
167
|
-
y2: axisBounds.y + axisBounds.height
|
|
168
|
-
}))]
|
|
169
|
-
}));
|
|
252
|
+
})]
|
|
253
|
+
});
|
|
170
254
|
});
|