@coinbase/cds-mobile-visualization 3.4.0-beta.2 → 3.4.0-beta.21
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 +128 -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 +215 -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
|
@@ -1,11 +1,28 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
1
|
+
import { memo, useMemo } from 'react';
|
|
2
|
+
import { runOnJS, useAnimatedReaction, useDerivedValue } from 'react-native-reanimated';
|
|
3
3
|
import { useTheme } from '@coinbase/cds-mobile/hooks/useTheme';
|
|
4
|
+
import { FontSlant, FontWeight, Group, Paint, Paragraph, RoundedRect, Shadow, Skia, TextAlign } from '@shopify/react-native-skia';
|
|
4
5
|
import { useCartesianChartContext } from '../ChartProvider';
|
|
5
|
-
import { getChartInset } from '../utils';
|
|
6
|
+
import { getChartInset, getColorWithOpacity, unwrapAnimatedValue } from '../utils';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Converts a fontWeight from Theme to a Skia FontWeight
|
|
10
|
+
* @note this only works when the fontWeight is a valid number (ie not 'bold')
|
|
11
|
+
* @param theme - The theme to use
|
|
12
|
+
* @param font - The font to use
|
|
13
|
+
* @returns The FontWeight or undefined if the fontWeight is not a valid number
|
|
14
|
+
*/
|
|
15
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
16
|
+
const getFontWeight = (theme, font) => {
|
|
17
|
+
const themeFontWeight = theme.fontWeight[font];
|
|
18
|
+
const numericWeight = typeof themeFontWeight === 'string' ? Number(themeFontWeight) : themeFontWeight;
|
|
19
|
+
const validFontWeights = Object.values(FontWeight).filter(value => typeof value === 'number');
|
|
20
|
+
return numericWeight !== undefined && validFontWeights.includes(numericWeight) ? numericWeight : undefined;
|
|
21
|
+
};
|
|
6
22
|
|
|
7
23
|
/**
|
|
8
24
|
* The supported content types for ChartText.
|
|
25
|
+
* Pass a string for simple text, or a SkParagraph for advanced rich text formatting.
|
|
9
26
|
*/
|
|
10
27
|
|
|
11
28
|
/**
|
|
@@ -15,137 +32,156 @@ import { getChartInset } from '../utils';
|
|
|
15
32
|
/**
|
|
16
33
|
* Vertical alignment options for chart text.
|
|
17
34
|
*/
|
|
18
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
19
|
-
/**
|
|
20
|
-
* Maps horizontal alignment to SVG textAnchor.
|
|
21
|
-
* This abstraction allows us to provide a consistent alignment API across web and mobile platforms,
|
|
22
|
-
* hiding the platform-specific SVG property differences.
|
|
23
|
-
*/
|
|
24
|
-
const getTextAnchor = alignment => {
|
|
25
|
-
switch (alignment) {
|
|
26
|
-
case 'left':
|
|
27
|
-
return 'start';
|
|
28
|
-
case 'center':
|
|
29
|
-
return 'middle';
|
|
30
|
-
case 'right':
|
|
31
|
-
return 'end';
|
|
32
|
-
}
|
|
33
|
-
};
|
|
34
35
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
* This abstraction allows us to provide a consistent alignment API across web and mobile platforms,
|
|
38
|
-
* hiding the platform-specific SVG property differences.
|
|
39
|
-
*/
|
|
40
|
-
const getAlignmentBaseline = alignment => {
|
|
41
|
-
switch (alignment) {
|
|
42
|
-
case 'top':
|
|
43
|
-
return 'hanging';
|
|
44
|
-
case 'middle':
|
|
45
|
-
return 'central';
|
|
46
|
-
case 'bottom':
|
|
47
|
-
return 'ideographic';
|
|
48
|
-
}
|
|
49
|
-
};
|
|
50
|
-
const ChartTextVisible = /*#__PURE__*/memo(_ref => {
|
|
51
|
-
let {
|
|
52
|
-
children,
|
|
53
|
-
background,
|
|
54
|
-
textAnchor,
|
|
55
|
-
alignmentBaseline,
|
|
56
|
-
fontSize,
|
|
57
|
-
fontWeight,
|
|
58
|
-
fill,
|
|
59
|
-
borderRadius,
|
|
60
|
-
inset: insetInput,
|
|
61
|
-
textDimensions,
|
|
62
|
-
dx,
|
|
63
|
-
dy
|
|
64
|
-
} = _ref;
|
|
65
|
-
const theme = useTheme();
|
|
66
|
-
const inset = useMemo(() => getChartInset(insetInput), [insetInput]);
|
|
67
|
-
const rectHeight = useMemo(() => textDimensions.height + inset.top + inset.bottom, [textDimensions, inset]);
|
|
68
|
-
const rectWidth = useMemo(() => textDimensions.width + inset.left + inset.right, [textDimensions, inset]);
|
|
69
|
-
return /*#__PURE__*/_jsxs(G, {
|
|
70
|
-
children: [background !== 'transparent' && /*#__PURE__*/_jsx(SvgRect, {
|
|
71
|
-
fill: background,
|
|
72
|
-
height: rectHeight,
|
|
73
|
-
rx: borderRadius,
|
|
74
|
-
ry: borderRadius,
|
|
75
|
-
width: rectWidth,
|
|
76
|
-
x: textDimensions.x - inset.left,
|
|
77
|
-
y: textDimensions.y - inset.top
|
|
78
|
-
}), /*#__PURE__*/_jsx(Text, {
|
|
79
|
-
alignmentBaseline: alignmentBaseline,
|
|
80
|
-
dx: dx,
|
|
81
|
-
dy: dy,
|
|
82
|
-
fill: fill != null ? fill : theme.color.fgMuted,
|
|
83
|
-
fontSize: fontSize,
|
|
84
|
-
fontWeight: fontWeight,
|
|
85
|
-
textAnchor: textAnchor,
|
|
86
|
-
children: children
|
|
87
|
-
})]
|
|
88
|
-
});
|
|
89
|
-
});
|
|
90
|
-
export const ChartText = /*#__PURE__*/memo(_ref2 => {
|
|
36
|
+
export const ChartText = /*#__PURE__*/memo(_ref => {
|
|
37
|
+
var _elevationShadow$shad, _elevationShadow$shad2, _elevationShadow$shad3, _elevationShadow$shad4, _elevationShadow$shad5, _elevationShadow$shad6, _elevationShadow$shad7;
|
|
91
38
|
let {
|
|
92
39
|
children,
|
|
93
40
|
x,
|
|
94
41
|
y,
|
|
42
|
+
dx = 0,
|
|
43
|
+
dy = 0,
|
|
95
44
|
horizontalAlignment = 'center',
|
|
96
45
|
verticalAlignment = 'middle',
|
|
97
|
-
|
|
98
|
-
dy,
|
|
46
|
+
paragraphAlignment = TextAlign.Left,
|
|
99
47
|
disableRepositioning = false,
|
|
100
48
|
bounds,
|
|
101
|
-
testID,
|
|
102
|
-
fontSize = 12,
|
|
103
|
-
fontWeight,
|
|
104
49
|
color,
|
|
105
|
-
background
|
|
106
|
-
borderRadius,
|
|
50
|
+
background: backgroundProp,
|
|
51
|
+
borderRadius = 4,
|
|
107
52
|
inset: insetInput,
|
|
108
53
|
onDimensionsChange,
|
|
109
|
-
opacity = 1
|
|
110
|
-
|
|
54
|
+
opacity = 1,
|
|
55
|
+
fontFamilies,
|
|
56
|
+
font = 'label2',
|
|
57
|
+
fontSize,
|
|
58
|
+
fontWeight,
|
|
59
|
+
fontStyle: fontStyleProp = FontSlant.Upright,
|
|
60
|
+
elevated
|
|
61
|
+
} = _ref;
|
|
62
|
+
const theme = useTheme();
|
|
111
63
|
const {
|
|
112
64
|
width: chartWidth,
|
|
113
|
-
height: chartHeight
|
|
65
|
+
height: chartHeight,
|
|
66
|
+
fontFamilies: contextFontFamilies,
|
|
67
|
+
fontProvider
|
|
114
68
|
} = useCartesianChartContext();
|
|
115
|
-
const
|
|
116
|
-
const
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
69
|
+
const inset = useMemo(() => getChartInset(insetInput), [insetInput]);
|
|
70
|
+
const background = backgroundProp != null ? backgroundProp : elevated ? theme.color.bgElevation1 : 'transparent';
|
|
71
|
+
const defaultParagraphStyle = useMemo(() => {
|
|
72
|
+
var _ref2;
|
|
73
|
+
return {
|
|
74
|
+
fontFamilies: (_ref2 = fontFamilies != null ? fontFamilies : contextFontFamilies) != null ? _ref2 : [],
|
|
75
|
+
fontSize: fontSize != null ? fontSize : theme.fontSize[font],
|
|
76
|
+
fontStyle: {
|
|
77
|
+
weight: fontWeight != null ? fontWeight : getFontWeight(theme, font),
|
|
78
|
+
slant: fontStyleProp
|
|
79
|
+
},
|
|
80
|
+
color: Skia.Color(color != null ? color : theme.color.fgMuted)
|
|
81
|
+
};
|
|
82
|
+
}, [fontFamilies, contextFontFamilies, fontSize, theme, font, fontWeight, fontStyleProp, color]);
|
|
83
|
+
const paragraph = useDerivedValue(() => {
|
|
84
|
+
const childrenValue = unwrapAnimatedValue(children);
|
|
85
|
+
if (typeof childrenValue !== 'string') {
|
|
86
|
+
return childrenValue;
|
|
127
87
|
}
|
|
88
|
+
const builder = Skia.ParagraphBuilder.Make({
|
|
89
|
+
textAlign: TextAlign.Left
|
|
90
|
+
}, fontProvider);
|
|
91
|
+
builder.pushStyle(defaultParagraphStyle);
|
|
92
|
+
builder.addText(childrenValue);
|
|
93
|
+
builder.pop();
|
|
94
|
+
const para = builder.build();
|
|
95
|
+
para.layout(chartWidth);
|
|
96
|
+
return para;
|
|
97
|
+
}, [children, fontProvider, defaultParagraphStyle, chartWidth]);
|
|
98
|
+
const textDimensions = useDerivedValue(() => {
|
|
99
|
+
const unwrappedParagraph = paragraph.value;
|
|
100
|
+
if (!unwrappedParagraph) return {
|
|
101
|
+
width: 0,
|
|
102
|
+
height: 0
|
|
103
|
+
};
|
|
128
104
|
return {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
width: textSize.width,
|
|
132
|
-
height: textSize.height
|
|
105
|
+
width: unwrappedParagraph.getLongestLine(),
|
|
106
|
+
height: unwrappedParagraph.getHeight()
|
|
133
107
|
};
|
|
134
|
-
}, [
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
108
|
+
}, [paragraph]);
|
|
109
|
+
const backgroundRectSize = useDerivedValue(() => ({
|
|
110
|
+
width: textDimensions.value.width + inset.left + inset.right,
|
|
111
|
+
height: textDimensions.value.height + inset.top + inset.bottom
|
|
112
|
+
}), [textDimensions, inset]);
|
|
113
|
+
|
|
114
|
+
// Calculate background rect position based on alignment
|
|
115
|
+
const backgroundRect = useDerivedValue(() => {
|
|
116
|
+
const horAlignment = unwrapAnimatedValue(horizontalAlignment);
|
|
117
|
+
const verAlignment = unwrapAnimatedValue(verticalAlignment);
|
|
118
|
+
// By default the value is top left
|
|
119
|
+
let rectX = unwrapAnimatedValue(x);
|
|
120
|
+
let rectY = unwrapAnimatedValue(y);
|
|
121
|
+
const rectSize = backgroundRectSize.value;
|
|
122
|
+
|
|
123
|
+
// Adjust for horizontal alignment
|
|
124
|
+
switch (horAlignment) {
|
|
125
|
+
case 'center':
|
|
126
|
+
rectX = rectX - rectSize.width / 2;
|
|
127
|
+
break;
|
|
128
|
+
case 'right':
|
|
129
|
+
rectX = rectX - rectSize.width;
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Adjust for vertical alignment
|
|
134
|
+
switch (verAlignment) {
|
|
135
|
+
case 'middle':
|
|
136
|
+
rectY = rectY - rectSize.height / 2;
|
|
137
|
+
break;
|
|
138
|
+
case 'bottom':
|
|
139
|
+
rectY = rectY - rectSize.height;
|
|
140
|
+
break;
|
|
139
141
|
}
|
|
140
|
-
const inset = getChartInset(insetInput);
|
|
141
142
|
return {
|
|
142
|
-
x:
|
|
143
|
-
y:
|
|
144
|
-
width:
|
|
145
|
-
height:
|
|
143
|
+
x: rectX,
|
|
144
|
+
y: rectY,
|
|
145
|
+
width: rectSize.width,
|
|
146
|
+
height: rectSize.height
|
|
146
147
|
};
|
|
147
|
-
}, [
|
|
148
|
-
|
|
148
|
+
}, [x, y, backgroundRectSize, horizontalAlignment, verticalAlignment]);
|
|
149
|
+
|
|
150
|
+
// Paragraph uses top-left positioning
|
|
151
|
+
const textPosition = useDerivedValue(() => {
|
|
152
|
+
const textDims = textDimensions.value;
|
|
153
|
+
|
|
154
|
+
// Calculate horizontal offset based on paragraph alignment
|
|
155
|
+
let horizontalOffset = 0;
|
|
156
|
+
switch (paragraphAlignment) {
|
|
157
|
+
case TextAlign.Center:
|
|
158
|
+
horizontalOffset = -textDims.width / 2;
|
|
159
|
+
break;
|
|
160
|
+
case TextAlign.Right:
|
|
161
|
+
case TextAlign.End:
|
|
162
|
+
horizontalOffset = -textDims.width;
|
|
163
|
+
break;
|
|
164
|
+
default:
|
|
165
|
+
// Left-aligned text needs no offset
|
|
166
|
+
horizontalOffset = 0;
|
|
167
|
+
break;
|
|
168
|
+
}
|
|
169
|
+
return {
|
|
170
|
+
x: backgroundRect.value.x + inset.left + horizontalOffset,
|
|
171
|
+
y: backgroundRect.value.y + inset.top,
|
|
172
|
+
width: textDims.width,
|
|
173
|
+
height: textDims.height
|
|
174
|
+
};
|
|
175
|
+
}, [backgroundRect, textDimensions, inset, paragraphAlignment]);
|
|
176
|
+
|
|
177
|
+
// Calculate overflow and repositioning
|
|
178
|
+
const fullChartBounds = useMemo(() => ({
|
|
179
|
+
x: 0,
|
|
180
|
+
y: 0,
|
|
181
|
+
width: chartWidth,
|
|
182
|
+
height: chartHeight
|
|
183
|
+
}), [chartWidth, chartHeight]);
|
|
184
|
+
const overflowAmount = useDerivedValue(() => {
|
|
149
185
|
if (disableRepositioning) {
|
|
150
186
|
return {
|
|
151
187
|
x: 0,
|
|
@@ -153,85 +189,117 @@ export const ChartText = /*#__PURE__*/memo(_ref2 => {
|
|
|
153
189
|
};
|
|
154
190
|
}
|
|
155
191
|
const parentBounds = bounds != null ? bounds : fullChartBounds;
|
|
156
|
-
if (!
|
|
192
|
+
if (!parentBounds || parentBounds.width <= 0 || parentBounds.height <= 0) {
|
|
157
193
|
return {
|
|
158
194
|
x: 0,
|
|
159
195
|
y: 0
|
|
160
196
|
};
|
|
161
197
|
}
|
|
162
|
-
let
|
|
163
|
-
let
|
|
198
|
+
let offsetX = 0;
|
|
199
|
+
let offsetY = 0;
|
|
164
200
|
|
|
165
201
|
// X-axis overflow
|
|
166
|
-
if (
|
|
167
|
-
|
|
168
|
-
} else if (
|
|
169
|
-
|
|
202
|
+
if (backgroundRect.value.x < parentBounds.x) {
|
|
203
|
+
offsetX = parentBounds.x - backgroundRect.value.x;
|
|
204
|
+
} else if (backgroundRect.value.x + backgroundRect.value.width > parentBounds.x + parentBounds.width) {
|
|
205
|
+
offsetX = parentBounds.x + parentBounds.width - (backgroundRect.value.x + backgroundRect.value.width);
|
|
170
206
|
}
|
|
171
207
|
|
|
172
208
|
// Y-axis overflow
|
|
173
|
-
if (
|
|
174
|
-
|
|
175
|
-
} else if (
|
|
176
|
-
|
|
209
|
+
if (backgroundRect.value.y < parentBounds.y) {
|
|
210
|
+
offsetY = parentBounds.y - backgroundRect.value.y;
|
|
211
|
+
} else if (backgroundRect.value.y + backgroundRect.value.height > parentBounds.y + parentBounds.height) {
|
|
212
|
+
offsetY = parentBounds.y + parentBounds.height - (backgroundRect.value.y + backgroundRect.value.height);
|
|
177
213
|
}
|
|
178
214
|
return {
|
|
179
|
-
x,
|
|
180
|
-
y
|
|
215
|
+
x: offsetX,
|
|
216
|
+
y: offsetY
|
|
181
217
|
};
|
|
182
|
-
}, [
|
|
183
|
-
|
|
184
|
-
|
|
218
|
+
}, [backgroundRect, fullChartBounds, bounds, disableRepositioning]);
|
|
219
|
+
|
|
220
|
+
// Final adjusted positions
|
|
221
|
+
const backgroundRectWithOffset = useDerivedValue(() => {
|
|
222
|
+
const offsetX = unwrapAnimatedValue(dx);
|
|
223
|
+
const offsetY = unwrapAnimatedValue(dy);
|
|
185
224
|
return {
|
|
186
|
-
x:
|
|
187
|
-
y:
|
|
188
|
-
width:
|
|
189
|
-
height:
|
|
225
|
+
x: backgroundRect.value.x + overflowAmount.value.x + offsetX,
|
|
226
|
+
y: backgroundRect.value.y + overflowAmount.value.y + offsetY,
|
|
227
|
+
width: backgroundRect.value.width,
|
|
228
|
+
height: backgroundRect.value.height
|
|
190
229
|
};
|
|
191
|
-
}, [
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
230
|
+
}, [backgroundRect, overflowAmount, dx, dy]);
|
|
231
|
+
const textWithOffsetX = useDerivedValue(() => textPosition.value.x + overflowAmount.value.x + unwrapAnimatedValue(dx), [textPosition, overflowAmount, dx]);
|
|
232
|
+
const textWithOffsetY = useDerivedValue(() => textPosition.value.y + overflowAmount.value.y + unwrapAnimatedValue(dy), [textPosition, overflowAmount, dy]);
|
|
233
|
+
useAnimatedReaction(() => backgroundRectWithOffset.value, (rect, previous) => {
|
|
234
|
+
if (onDimensionsChange && rect !== previous) {
|
|
235
|
+
runOnJS(onDimensionsChange)(rect);
|
|
195
236
|
}
|
|
196
|
-
}, [
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
237
|
+
}, [onDimensionsChange]);
|
|
238
|
+
|
|
239
|
+
// Show group if we are ready
|
|
240
|
+
const groupOpacity = useDerivedValue(() => {
|
|
241
|
+
const textSize = textDimensions.value;
|
|
242
|
+
const hasValidContent = paragraph.value && textSize.width > 0 && textSize.height > 0;
|
|
243
|
+
return hasValidContent ? unwrapAnimatedValue(opacity) : 0;
|
|
244
|
+
}, [paragraph, textDimensions, opacity]);
|
|
245
|
+
const backgroundRectHeight = useDerivedValue(() => backgroundRectWithOffset.value.height, [backgroundRectWithOffset]);
|
|
246
|
+
const backgroundRectWidth = useDerivedValue(() => backgroundRectWithOffset.value.width, [backgroundRectWithOffset]);
|
|
247
|
+
const backgroundRectX = useDerivedValue(() => backgroundRectWithOffset.value.x, [backgroundRectWithOffset]);
|
|
248
|
+
const backgroundRectY = useDerivedValue(() => backgroundRectWithOffset.value.y, [backgroundRectWithOffset]);
|
|
249
|
+
const elevationShadow = elevated ? theme.shadow.elevation1 : undefined;
|
|
250
|
+
|
|
251
|
+
// Calculate the paragraph's internal x offset from line metrics based on text alignment
|
|
252
|
+
const paragraphTransform = useDerivedValue(() => {
|
|
253
|
+
if (!paragraph.value || !paragraphAlignment) return [];
|
|
254
|
+
const rects = paragraph.value.getLineMetrics();
|
|
255
|
+
if (rects.length === 0) return [];
|
|
256
|
+
let minOffset;
|
|
257
|
+
switch (paragraphAlignment) {
|
|
258
|
+
case TextAlign.Center:
|
|
259
|
+
// For center-aligned text, account for half the width
|
|
260
|
+
minOffset = Math.min(...rects.map(rect => rect.x - rect.width / 2));
|
|
261
|
+
break;
|
|
262
|
+
case TextAlign.Right:
|
|
263
|
+
case TextAlign.End:
|
|
264
|
+
// For right-aligned text, account for the full width
|
|
265
|
+
minOffset = Math.min(...rects.map(rect => rect.x - rect.width));
|
|
266
|
+
break;
|
|
267
|
+
default:
|
|
268
|
+
// For left-aligned text, use the x position directly
|
|
269
|
+
minOffset = Math.min(...rects.map(rect => rect.x));
|
|
270
|
+
break;
|
|
200
271
|
}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
272
|
+
return [{
|
|
273
|
+
translateX: -minOffset
|
|
274
|
+
}];
|
|
275
|
+
}, [paragraph, paragraphAlignment]);
|
|
276
|
+
|
|
277
|
+
// Opacity on a group doesn't impact the paragraph so we need to apply it to Group
|
|
278
|
+
return /*#__PURE__*/_jsxs(Group, {
|
|
279
|
+
layer: /*#__PURE__*/_jsx(Paint, {
|
|
280
|
+
opacity: groupOpacity
|
|
281
|
+
}),
|
|
282
|
+
children: [background !== 'transparent' && /*#__PURE__*/_jsx(RoundedRect, {
|
|
283
|
+
color: background,
|
|
284
|
+
height: backgroundRectHeight,
|
|
285
|
+
r: borderRadius,
|
|
286
|
+
width: backgroundRectWidth,
|
|
287
|
+
x: backgroundRectX,
|
|
288
|
+
y: backgroundRectY,
|
|
289
|
+
children: elevationShadow && /*#__PURE__*/_jsx(Shadow, {
|
|
290
|
+
blur: Number((_elevationShadow$shad = elevationShadow.shadowRadius) != null ? _elevationShadow$shad : 0),
|
|
291
|
+
color: getColorWithOpacity(String((_elevationShadow$shad2 = elevationShadow.shadowColor) != null ? _elevationShadow$shad2 : '#000000'), Number((_elevationShadow$shad3 = elevationShadow.shadowOpacity) != null ? _elevationShadow$shad3 : 1)),
|
|
292
|
+
dx: Number((_elevationShadow$shad4 = (_elevationShadow$shad5 = elevationShadow.shadowOffset) == null ? void 0 : _elevationShadow$shad5.width) != null ? _elevationShadow$shad4 : 0),
|
|
293
|
+
dy: Number((_elevationShadow$shad6 = (_elevationShadow$shad7 = elevationShadow.shadowOffset) == null ? void 0 : _elevationShadow$shad7.height) != null ? _elevationShadow$shad6 : 0)
|
|
294
|
+
})
|
|
295
|
+
}), /*#__PURE__*/_jsx(Group, {
|
|
296
|
+
transform: paragraphTransform,
|
|
297
|
+
children: /*#__PURE__*/_jsx(Paragraph, {
|
|
298
|
+
paragraph: paragraph,
|
|
299
|
+
width: chartWidth,
|
|
300
|
+
x: textWithOffsetX,
|
|
301
|
+
y: textWithOffsetY
|
|
223
302
|
})
|
|
224
|
-
}), /*#__PURE__*/_jsx(Text, {
|
|
225
|
-
alignmentBaseline: alignmentBaseline,
|
|
226
|
-
dx: dx,
|
|
227
|
-
dy: dy,
|
|
228
|
-
fill: "transparent",
|
|
229
|
-
fontSize: fontSize,
|
|
230
|
-
fontWeight: fontWeight,
|
|
231
|
-
onLayout: onLayout,
|
|
232
|
-
opacity: 0,
|
|
233
|
-
textAnchor: textAnchor,
|
|
234
|
-
children: children
|
|
235
303
|
})]
|
|
236
304
|
});
|
|
237
305
|
});
|
|
@@ -2,7 +2,7 @@ const _excluded = ["onDimensionsChange"];
|
|
|
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, useEffect, useMemo, useState } from 'react';
|
|
5
|
-
import {
|
|
5
|
+
import { Group } from '@shopify/react-native-skia';
|
|
6
6
|
import { ChartText } from './ChartText';
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -32,12 +32,13 @@ const EPSILON_PX = 0.5;
|
|
|
32
32
|
*
|
|
33
33
|
* The component focuses solely on overlap prevention logic for better separation of concerns.
|
|
34
34
|
*/
|
|
35
|
-
export const
|
|
35
|
+
export const ChartTextGroup = /*#__PURE__*/memo(_ref => {
|
|
36
36
|
let {
|
|
37
37
|
labels,
|
|
38
38
|
minGap = 8,
|
|
39
39
|
prioritizeEndLabels = true,
|
|
40
|
-
chartTextProps
|
|
40
|
+
chartTextProps,
|
|
41
|
+
LabelComponent = ChartText
|
|
41
42
|
} = _ref;
|
|
42
43
|
const [boundingBoxes, setBoundingBoxes] = useState(new Map());
|
|
43
44
|
const _ref2 = chartTextProps != null ? chartTextProps : {},
|
|
@@ -193,11 +194,11 @@ export const SmartChartTextGroup = /*#__PURE__*/memo(_ref => {
|
|
|
193
194
|
}
|
|
194
195
|
return new Set(greedy);
|
|
195
196
|
}, [isReady, boundingBoxes, minGap, prioritizeEndLabels, labelsWithKeys]);
|
|
196
|
-
return /*#__PURE__*/_jsx(
|
|
197
|
+
return /*#__PURE__*/_jsx(Group, {
|
|
197
198
|
children: labelsWithKeys.map(labelData => {
|
|
198
199
|
const hasMeasurement = boundingBoxes.has(labelData.key);
|
|
199
200
|
const isVisible = hasMeasurement && isReady && (visibleKeySet == null ? void 0 : visibleKeySet.has(labelData.key));
|
|
200
|
-
return /*#__PURE__*/_jsx(
|
|
201
|
+
return /*#__PURE__*/_jsx(LabelComponent, _extends({
|
|
201
202
|
opacity: isVisible ? 1 : 0,
|
|
202
203
|
x: labelData.x,
|
|
203
204
|
y: labelData.y
|
package/esm/chart/text/index.js
CHANGED
package/esm/chart/utils/axis.js
CHANGED
|
@@ -3,10 +3,41 @@ function _extends() { return _extends = Object.assign ? Object.assign.bind() : f
|
|
|
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 { useCallback, useMemo, useState } from 'react';
|
|
5
5
|
import { getChartDomain, getChartRange, isValidBounds } from './chart';
|
|
6
|
+
import { getPointOnScale } from './point';
|
|
6
7
|
import { getCategoricalScale, getNumericScale, isCategoricalScale, isNumericScale } from './scale';
|
|
7
8
|
export const defaultAxisId = 'DEFAULT_AXIS_ID';
|
|
8
9
|
export const defaultAxisScaleType = 'linear';
|
|
9
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Position options for band scale axis elements (grid lines, tick marks, labels).
|
|
13
|
+
*
|
|
14
|
+
* - `'start'` - At the start of each step (before bar padding)
|
|
15
|
+
* - `'middle'` - At the center of each band
|
|
16
|
+
* - `'end'` - At the end of each step (after bar padding)
|
|
17
|
+
* - `'edges'` - At start of each tick, plus end for the last tick (encloses the chart)
|
|
18
|
+
*
|
|
19
|
+
* @note These properties only apply when using a band scale (`scaleType: 'band'`).
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Converts an AxisBandPlacement to the corresponding PointAnchor for use with getPointOnScale.
|
|
24
|
+
*
|
|
25
|
+
* @param placement - The axis placement value
|
|
26
|
+
* @returns The corresponding PointAnchor for scale calculations
|
|
27
|
+
*/
|
|
28
|
+
export const toPointAnchor = placement => {
|
|
29
|
+
switch (placement) {
|
|
30
|
+
case 'edges': // edges uses stepStart for each tick, stepEnd handled separately
|
|
31
|
+
case 'start':
|
|
32
|
+
return 'stepStart';
|
|
33
|
+
case 'end':
|
|
34
|
+
return 'stepEnd';
|
|
35
|
+
case 'middle':
|
|
36
|
+
default:
|
|
37
|
+
return 'middle';
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
|
|
10
41
|
/**
|
|
11
42
|
* Axis configuration with computed bounds
|
|
12
43
|
*/
|
|
@@ -52,7 +83,7 @@ export const getAxisScale = _ref => {
|
|
|
52
83
|
max: (_config$domain$max = config.domain.max) != null ? _config$domain$max : dataDomain.max
|
|
53
84
|
};
|
|
54
85
|
}
|
|
55
|
-
if (!isValidBounds(adjustedDomain)) throw new Error('Invalid domain bounds. See https://cds.coinbase.com/
|
|
86
|
+
if (!isValidBounds(adjustedDomain)) throw new Error('Invalid domain bounds. See https://cds.coinbase.com/components/charts/XAxis/#domain');
|
|
56
87
|
if (scaleType === 'band') {
|
|
57
88
|
var _config$categoryPaddi;
|
|
58
89
|
return getCategoricalScale({
|
|
@@ -106,7 +137,7 @@ export const getAxisConfig = function (type, axes, defaultId, defaultScaleType)
|
|
|
106
137
|
} = _ref2;
|
|
107
138
|
return id === undefined;
|
|
108
139
|
})) {
|
|
109
|
-
throw new Error('When defining multiple axes, each must have a unique id. See https://cds.coinbase.com/components/
|
|
140
|
+
throw new Error('When defining multiple axes, each must have a unique id. See https://cds.coinbase.com/components/charts/YAxis/#multiple-y-axes.');
|
|
110
141
|
}
|
|
111
142
|
return axes.map(_ref3 => {
|
|
112
143
|
let {
|
|
@@ -457,6 +488,7 @@ const generateEvenlyDistributedTicks = (scale, tickInterval, possibleTickValues,
|
|
|
457
488
|
* // Returns tick positions centered in each selected band
|
|
458
489
|
*/
|
|
459
490
|
export const getAxisTicksData = _ref4 => {
|
|
491
|
+
var _options$anchor;
|
|
460
492
|
let {
|
|
461
493
|
ticks,
|
|
462
494
|
scaleFunction,
|
|
@@ -466,53 +498,37 @@ export const getAxisTicksData = _ref4 => {
|
|
|
466
498
|
tickInterval,
|
|
467
499
|
options
|
|
468
500
|
} = _ref4;
|
|
501
|
+
const anchor = (_options$anchor = options == null ? void 0 : options.anchor) != null ? _options$anchor : 'middle';
|
|
502
|
+
|
|
469
503
|
// Handle band scales
|
|
470
504
|
if (isCategoricalScale(scaleFunction)) {
|
|
505
|
+
const bandScale = scaleFunction;
|
|
506
|
+
|
|
471
507
|
// If explicit ticks are provided as array, use them
|
|
472
508
|
if (Array.isArray(ticks)) {
|
|
473
|
-
return ticks.filter(index => index >= 0 && index < categories.length).map(index => {
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
if (position === undefined) return null;
|
|
478
|
-
return {
|
|
479
|
-
tick: index,
|
|
480
|
-
position: position + ((_bandwidth = scaleFunction.bandwidth == null ? void 0 : scaleFunction.bandwidth()) != null ? _bandwidth : 0) / 2
|
|
481
|
-
};
|
|
482
|
-
}).filter(Boolean);
|
|
509
|
+
return ticks.filter(index => index >= 0 && index < categories.length).map(index => ({
|
|
510
|
+
tick: index,
|
|
511
|
+
position: getPointOnScale(index, bandScale, anchor)
|
|
512
|
+
}));
|
|
483
513
|
}
|
|
484
514
|
|
|
485
515
|
// If a tick function is provided, use it to filter
|
|
486
516
|
if (typeof ticks === 'function') {
|
|
487
517
|
return categories.map((category, index) => {
|
|
488
|
-
var _bandwidth2;
|
|
489
518
|
if (!ticks(index)) return null;
|
|
490
|
-
|
|
491
|
-
// Band scales expect numeric indices, not category strings
|
|
492
|
-
const position = scaleFunction(index);
|
|
493
|
-
if (position === undefined) return null;
|
|
494
519
|
return {
|
|
495
520
|
tick: index,
|
|
496
|
-
position:
|
|
521
|
+
position: getPointOnScale(index, bandScale, anchor)
|
|
497
522
|
};
|
|
498
523
|
}).filter(Boolean);
|
|
499
524
|
}
|
|
500
|
-
if (typeof ticks === 'boolean' && !ticks) {
|
|
501
|
-
return [];
|
|
502
|
-
}
|
|
503
525
|
|
|
504
526
|
// For band scales without explicit ticks, show all categories
|
|
505
527
|
// requestedTickCount is ignored for categorical scales - use ticks parameter to control visibility
|
|
506
|
-
return categories.map((
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
if (position === undefined) return null;
|
|
511
|
-
return {
|
|
512
|
-
tick: index,
|
|
513
|
-
position: position + ((_bandwidth3 = scaleFunction.bandwidth == null ? void 0 : scaleFunction.bandwidth()) != null ? _bandwidth3 : 0) / 2
|
|
514
|
-
};
|
|
515
|
-
}).filter(Boolean);
|
|
528
|
+
return categories.map((_, index) => ({
|
|
529
|
+
tick: index,
|
|
530
|
+
position: getPointOnScale(index, bandScale, anchor)
|
|
531
|
+
}));
|
|
516
532
|
}
|
|
517
533
|
|
|
518
534
|
// Handle numeric scales
|