react-native-livechart 3.11.0 → 4.0.0
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/dist/components/BadgeOverlay.d.ts +9 -1
- package/dist/components/BadgeOverlay.d.ts.map +1 -1
- package/dist/components/ChartOverlayLayer.d.ts +19 -0
- package/dist/components/ChartOverlayLayer.d.ts.map +1 -0
- package/dist/components/CustomMarkerOverlay.d.ts +18 -6
- package/dist/components/CustomMarkerOverlay.d.ts.map +1 -1
- package/dist/components/CustomReferenceLineOverlay.d.ts +36 -0
- package/dist/components/CustomReferenceLineOverlay.d.ts.map +1 -0
- package/dist/components/CustomTooltipOverlay.d.ts +5 -2
- package/dist/components/CustomTooltipOverlay.d.ts.map +1 -1
- package/dist/components/DotOverlay.d.ts +7 -1
- package/dist/components/DotOverlay.d.ts.map +1 -1
- package/dist/components/LiveChart.d.ts.map +1 -1
- package/dist/components/LiveChartSeries.d.ts.map +1 -1
- package/dist/components/MarkerOverlay.d.ts +8 -3
- package/dist/components/MarkerOverlay.d.ts.map +1 -1
- package/dist/components/MultiSeriesDots.d.ts +4 -1
- package/dist/components/MultiSeriesDots.d.ts.map +1 -1
- package/dist/components/ReferenceLineGroupOverlay.d.ts +27 -0
- package/dist/components/ReferenceLineGroupOverlay.d.ts.map +1 -0
- package/dist/components/ReferenceLineOverlay.d.ts +25 -2
- package/dist/components/ReferenceLineOverlay.d.ts.map +1 -1
- package/dist/components/XAxisOverlay.d.ts +7 -1
- package/dist/components/XAxisOverlay.d.ts.map +1 -1
- package/dist/components/YAxisOverlay.d.ts +12 -1
- package/dist/components/YAxisOverlay.d.ts.map +1 -1
- package/dist/constants.d.ts +7 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/core/liveChartEngineTick.d.ts +29 -0
- package/dist/core/liveChartEngineTick.d.ts.map +1 -1
- package/dist/core/liveChartSeriesEngineTick.d.ts +18 -0
- package/dist/core/liveChartSeriesEngineTick.d.ts.map +1 -1
- package/dist/core/resolveConfig.d.ts +56 -2
- package/dist/core/resolveConfig.d.ts.map +1 -1
- package/dist/core/useLiveChartEngine.d.ts +58 -7
- package/dist/core/useLiveChartEngine.d.ts.map +1 -1
- package/dist/core/useLiveChartSeriesEngine.d.ts +8 -2
- package/dist/core/useLiveChartSeriesEngine.d.ts.map +1 -1
- package/dist/draw/grid.d.ts.map +1 -1
- package/dist/draw/markerAtlas.d.ts +20 -2
- package/dist/draw/markerAtlas.d.ts.map +1 -1
- package/dist/draw/volume.d.ts +25 -0
- package/dist/draw/volume.d.ts.map +1 -0
- package/dist/hooks/crosshairShared.d.ts +12 -6
- package/dist/hooks/crosshairShared.d.ts.map +1 -1
- package/dist/hooks/overlayScale.d.ts +22 -0
- package/dist/hooks/overlayScale.d.ts.map +1 -0
- package/dist/hooks/resolveChartLayout.d.ts +9 -0
- package/dist/hooks/resolveChartLayout.d.ts.map +1 -1
- package/dist/hooks/useBadge.d.ts +22 -1
- package/dist/hooks/useBadge.d.ts.map +1 -1
- package/dist/hooks/useCandlePaths.d.ts +6 -0
- package/dist/hooks/useCandlePaths.d.ts.map +1 -1
- package/dist/hooks/useChartOverlayContext.d.ts +45 -0
- package/dist/hooks/useChartOverlayContext.d.ts.map +1 -0
- package/dist/hooks/useChartPaths.d.ts +8 -1
- package/dist/hooks/useChartPaths.d.ts.map +1 -1
- package/dist/hooks/useCrosshair.d.ts +9 -2
- package/dist/hooks/useCrosshair.d.ts.map +1 -1
- package/dist/hooks/useLiveDot.d.ts +6 -1
- package/dist/hooks/useLiveDot.d.ts.map +1 -1
- package/dist/hooks/useMarkers.d.ts +12 -4
- package/dist/hooks/useMarkers.d.ts.map +1 -1
- package/dist/hooks/useMultiSeriesLinePaths.d.ts.map +1 -1
- package/dist/hooks/usePanScroll.d.ts +82 -0
- package/dist/hooks/usePanScroll.d.ts.map +1 -0
- package/dist/hooks/usePinchZoom.d.ts +74 -0
- package/dist/hooks/usePinchZoom.d.ts.map +1 -0
- package/dist/hooks/useReferenceDrag.d.ts +24 -0
- package/dist/hooks/useReferenceDrag.d.ts.map +1 -0
- package/dist/hooks/useReferenceLine.d.ts +23 -4
- package/dist/hooks/useReferenceLine.d.ts.map +1 -1
- package/dist/hooks/useReferenceLinePress.d.ts +5 -1
- package/dist/hooks/useReferenceLinePress.d.ts.map +1 -1
- package/dist/hooks/useVisibleRange.d.ts +39 -0
- package/dist/hooks/useVisibleRange.d.ts.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/math/markerCluster.d.ts +47 -0
- package/dist/math/markerCluster.d.ts.map +1 -0
- package/dist/math/markers.d.ts +15 -0
- package/dist/math/markers.d.ts.map +1 -1
- package/dist/math/referenceDrag.d.ts +24 -0
- package/dist/math/referenceDrag.d.ts.map +1 -0
- package/dist/math/referenceGroup.d.ts +31 -0
- package/dist/math/referenceGroup.d.ts.map +1 -0
- package/dist/math/referenceLines.d.ts +33 -7
- package/dist/math/referenceLines.d.ts.map +1 -1
- package/dist/types.d.ts +512 -21
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/BadgeOverlay.tsx +26 -1
- package/src/components/ChartOverlayLayer.tsx +32 -0
- package/src/components/CustomMarkerOverlay.tsx +153 -53
- package/src/components/CustomReferenceLineOverlay.tsx +250 -0
- package/src/components/CustomTooltipOverlay.tsx +27 -7
- package/src/components/DotOverlay.tsx +9 -0
- package/src/components/LiveChart.tsx +561 -34
- package/src/components/LiveChartSeries.tsx +110 -5
- package/src/components/MarkerOverlay.tsx +100 -6
- package/src/components/MultiSeriesDots.tsx +12 -3
- package/src/components/ReferenceLineGroupOverlay.tsx +207 -0
- package/src/components/ReferenceLineOverlay.tsx +105 -32
- package/src/components/XAxisOverlay.tsx +9 -2
- package/src/components/YAxisOverlay.tsx +48 -26
- package/src/constants.ts +10 -0
- package/src/core/liveChartEngineTick.ts +81 -8
- package/src/core/liveChartSeriesEngineTick.ts +50 -9
- package/src/core/resolveConfig.ts +122 -1
- package/src/core/useLiveChartEngine.ts +103 -10
- package/src/core/useLiveChartSeriesEngine.ts +26 -3
- package/src/draw/grid.ts +13 -1
- package/src/draw/markerAtlas.ts +117 -3
- package/src/draw/volume.ts +190 -0
- package/src/hooks/crosshairShared.ts +37 -9
- package/src/hooks/overlayScale.ts +59 -0
- package/src/hooks/resolveChartLayout.ts +33 -0
- package/src/hooks/useBadge.ts +89 -21
- package/src/hooks/useCandlePaths.ts +104 -7
- package/src/hooks/useChartOverlayContext.ts +93 -0
- package/src/hooks/useChartPaths.ts +14 -1
- package/src/hooks/useCrosshair.ts +29 -2
- package/src/hooks/useLiveDot.ts +16 -5
- package/src/hooks/useMarkers.ts +43 -11
- package/src/hooks/useMultiSeriesLinePaths.ts +2 -1
- package/src/hooks/usePanScroll.ts +253 -0
- package/src/hooks/usePinchZoom.ts +189 -0
- package/src/hooks/useReferenceDrag.ts +254 -0
- package/src/hooks/useReferenceLine.ts +56 -9
- package/src/hooks/useReferenceLinePress.ts +16 -2
- package/src/hooks/useVisibleRange.ts +119 -0
- package/src/index.ts +17 -1
- package/src/math/markerCluster.ts +214 -0
- package/src/math/markers.ts +54 -9
- package/src/math/referenceDrag.ts +66 -0
- package/src/math/referenceGroup.ts +65 -0
- package/src/math/referenceLines.ts +76 -19
- package/src/types.ts +532 -21
package/src/math/markers.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { LiveChartPoint, Marker, SeriesConfig } from "../types";
|
|
2
|
+
import { interpolateAtTime } from "./interpolate";
|
|
2
3
|
import { splineValueAtTime } from "./spline";
|
|
3
4
|
|
|
4
5
|
/** Screen-space position for one marker, index-aligned with the marker array. */
|
|
@@ -6,6 +7,16 @@ export interface ProjectedMarker {
|
|
|
6
7
|
x: number;
|
|
7
8
|
y: number;
|
|
8
9
|
visible: boolean;
|
|
10
|
+
/** Collapsed cluster member that the representative stands in for — not drawn,
|
|
11
|
+
* not hit-tested. Set by the cluster pass; `false` outside `markerCluster`. */
|
|
12
|
+
hidden: boolean;
|
|
13
|
+
/** This marker is the representative (count badge) of a collapsed cluster. */
|
|
14
|
+
isGrouped: boolean;
|
|
15
|
+
/** Size of the collapsed cluster this marker represents (`0` when not grouped). */
|
|
16
|
+
groupCount: number;
|
|
17
|
+
/** Index of the cluster's representative marker for collapsed members (and the
|
|
18
|
+
* representative itself), else `-1`. Used to gather members on tap. */
|
|
19
|
+
groupRep: number;
|
|
9
20
|
}
|
|
10
21
|
|
|
11
22
|
export interface ProjectMarkersOpts {
|
|
@@ -23,6 +34,11 @@ export interface ProjectMarkersOpts {
|
|
|
23
34
|
series?: SeriesConfig[];
|
|
24
35
|
/** Single-series line data; anchors markers that omit `value` (and `seriesId`). */
|
|
25
36
|
lineData?: LiveChartPoint[];
|
|
37
|
+
/** When the single-series line is drawn with `line.curve === "linear"`, anchor
|
|
38
|
+
* `lineData` markers on the straight chord (linear interpolation) instead of the
|
|
39
|
+
* monotone spline so the glyph sits exactly on the rendered line. Multi-series
|
|
40
|
+
* markers read their curve per-series from {@link SeriesConfig.curve}. */
|
|
41
|
+
lineLinear?: boolean;
|
|
26
42
|
}
|
|
27
43
|
|
|
28
44
|
/** How far off-chart (px) a marker may sit before it is culled. */
|
|
@@ -41,6 +57,12 @@ function projectInto(
|
|
|
41
57
|
target: ProjectedMarker,
|
|
42
58
|
): void {
|
|
43
59
|
"worklet";
|
|
60
|
+
// Reset cluster fields so a reused buffer slot defaults to un-clustered; the
|
|
61
|
+
// cluster pass (when it runs) overwrites them. Lets anchored mode skip the pass.
|
|
62
|
+
target.hidden = false;
|
|
63
|
+
target.isGrouped = false;
|
|
64
|
+
target.groupCount = 0;
|
|
65
|
+
target.groupRep = -1;
|
|
44
66
|
const w = opts.canvasWidth;
|
|
45
67
|
const h = opts.canvasHeight;
|
|
46
68
|
const chartLeft = opts.padLeft;
|
|
@@ -66,16 +88,23 @@ function projectInto(
|
|
|
66
88
|
} else if (seriesId !== undefined && opts.series) {
|
|
67
89
|
for (let j = 0; j < opts.series.length; j++) {
|
|
68
90
|
if (opts.series[j].id === seriesId) {
|
|
69
|
-
//
|
|
70
|
-
// exactly on the
|
|
71
|
-
|
|
91
|
+
// Anchor on the same interpolation the series is rendered with, so the
|
|
92
|
+
// glyph sits exactly on the line: the linear chord for `curve: "linear"`,
|
|
93
|
+
// the monotone spline otherwise.
|
|
94
|
+
v =
|
|
95
|
+
opts.series[j].curve === "linear"
|
|
96
|
+
? interpolateAtTime(opts.series[j].data, time)
|
|
97
|
+
: splineValueAtTime(opts.series[j].data, time);
|
|
72
98
|
break;
|
|
73
99
|
}
|
|
74
100
|
}
|
|
75
101
|
} else if (opts.lineData) {
|
|
76
|
-
// Single-series anchor: omit `value` to pin the marker to the line at `time
|
|
77
|
-
//
|
|
78
|
-
|
|
102
|
+
// Single-series anchor: omit `value` to pin the marker to the line at `time`.
|
|
103
|
+
// Match the rendered curve — straight chord when `line.curve === "linear"`,
|
|
104
|
+
// the monotone spline otherwise.
|
|
105
|
+
v = opts.lineLinear
|
|
106
|
+
? interpolateAtTime(opts.lineData, time)
|
|
107
|
+
: splineValueAtTime(opts.lineData, time);
|
|
79
108
|
}
|
|
80
109
|
if (v === null) {
|
|
81
110
|
target.visible = false;
|
|
@@ -108,7 +137,15 @@ export function projectMarkers(
|
|
|
108
137
|
for (let i = 0; i < markers.length; i++) {
|
|
109
138
|
let cur = out[i];
|
|
110
139
|
if (!cur) {
|
|
111
|
-
cur = {
|
|
140
|
+
cur = {
|
|
141
|
+
x: 0,
|
|
142
|
+
y: 0,
|
|
143
|
+
visible: false,
|
|
144
|
+
hidden: false,
|
|
145
|
+
isGrouped: false,
|
|
146
|
+
groupCount: 0,
|
|
147
|
+
groupRep: -1,
|
|
148
|
+
};
|
|
112
149
|
out[i] = cur;
|
|
113
150
|
}
|
|
114
151
|
const m = markers[i];
|
|
@@ -129,7 +166,15 @@ export function projectPoint(
|
|
|
129
166
|
opts: ProjectMarkersOpts,
|
|
130
167
|
): ProjectedMarker {
|
|
131
168
|
"worklet";
|
|
132
|
-
const target: ProjectedMarker = {
|
|
169
|
+
const target: ProjectedMarker = {
|
|
170
|
+
x: 0,
|
|
171
|
+
y: 0,
|
|
172
|
+
visible: false,
|
|
173
|
+
hidden: false,
|
|
174
|
+
isGrouped: false,
|
|
175
|
+
groupCount: 0,
|
|
176
|
+
groupRep: -1,
|
|
177
|
+
};
|
|
133
178
|
projectInto(time, value, seriesId, opts, target);
|
|
134
179
|
return target;
|
|
135
180
|
}
|
|
@@ -162,7 +207,7 @@ export function nearestMarkerIndex(
|
|
|
162
207
|
let bestD = radius * radius;
|
|
163
208
|
for (let i = 0; i < positions.length; i++) {
|
|
164
209
|
const p = positions[i];
|
|
165
|
-
if (!p.visible) continue;
|
|
210
|
+
if (!p.visible || p.hidden) continue;
|
|
166
211
|
const dx = p.x - x;
|
|
167
212
|
const dy = p.y - y;
|
|
168
213
|
const d = dx * dx + dy * dy;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure, worklet-safe helpers for dragging a Form-A reference line along the
|
|
3
|
+
* Y-axis. Kept free of hooks / SharedValues so they unit-test without Reanimated
|
|
4
|
+
* (the gesture wiring lives in {@link useReferenceDrag}).
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/** Clamp a value to an optional `[min, max]` bound (order-independent). No-op when
|
|
8
|
+
* `bounds` is omitted. */
|
|
9
|
+
export function clampToBounds(
|
|
10
|
+
value: number,
|
|
11
|
+
bounds?: [number, number],
|
|
12
|
+
): number {
|
|
13
|
+
"worklet";
|
|
14
|
+
if (!bounds) return value;
|
|
15
|
+
const lo = Math.min(bounds[0], bounds[1]);
|
|
16
|
+
const hi = Math.max(bounds[0], bounds[1]);
|
|
17
|
+
return Math.min(hi, Math.max(lo, value));
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Index of the draggable line whose handle-Y is nearest the touch `y`, within
|
|
22
|
+
* `slop` px — or `-1` when none is in reach. `handleYs` is index-aligned with the
|
|
23
|
+
* chart's `referenceLines`; entries `< 0` (not draggable / off-screen / not laid
|
|
24
|
+
* out) are skipped. Ties favor the later (topmost-drawn) line.
|
|
25
|
+
*/
|
|
26
|
+
export function nearestDraggableIndex(
|
|
27
|
+
handleYs: number[],
|
|
28
|
+
y: number,
|
|
29
|
+
slop: number,
|
|
30
|
+
): number {
|
|
31
|
+
"worklet";
|
|
32
|
+
let best = -1;
|
|
33
|
+
let bestDist = slop;
|
|
34
|
+
for (let i = 0; i < handleYs.length; i++) {
|
|
35
|
+
const hy = handleYs[i];
|
|
36
|
+
if (hy < 0) continue;
|
|
37
|
+
const d = Math.abs(hy - y);
|
|
38
|
+
if (d <= bestDist) {
|
|
39
|
+
bestDist = d;
|
|
40
|
+
best = i;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return best;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Whether a line's value sits **outside** its watched interval — the trigger for
|
|
48
|
+
* `onDragOut` / `onDragIn` (edge-detected by the caller). When `bounds` is set the
|
|
49
|
+
* watched interval is `bounds` (at-or-past a bound counts as out, since the drag
|
|
50
|
+
* clamps there); otherwise it's the visible `[min, max]` Y-range (out = scrolled /
|
|
51
|
+
* dragged off-screen).
|
|
52
|
+
*/
|
|
53
|
+
export function referenceValueOut(
|
|
54
|
+
value: number,
|
|
55
|
+
min: number,
|
|
56
|
+
max: number,
|
|
57
|
+
bounds?: [number, number],
|
|
58
|
+
): boolean {
|
|
59
|
+
"worklet";
|
|
60
|
+
if (bounds) {
|
|
61
|
+
const lo = Math.min(bounds[0], bounds[1]);
|
|
62
|
+
const hi = Math.max(bounds[0], bounds[1]);
|
|
63
|
+
return value <= lo || value >= hi;
|
|
64
|
+
}
|
|
65
|
+
return value < min || value > max;
|
|
66
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure, worklet-safe clustering for reference-line grouping — collapse Form-A
|
|
3
|
+
* lines whose value-Y positions sit near each other into one count handle. Free of
|
|
4
|
+
* hooks / SharedValues so it unit-tests without Reanimated; the per-frame call +
|
|
5
|
+
* rendering live in the controller / `ReferenceLineGroupOverlay`.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/** One collapsed cluster of nearby reference lines. */
|
|
9
|
+
export interface ReferenceGroup {
|
|
10
|
+
/** Centroid Y (canvas px) of the cluster — where the count handle is drawn. */
|
|
11
|
+
cy: number;
|
|
12
|
+
/** Number of lines collapsed into the cluster (≥ 2). */
|
|
13
|
+
count: number;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** Result of clustering a frame's reference-line Y positions. */
|
|
17
|
+
export interface ReferenceGrouping {
|
|
18
|
+
/**
|
|
19
|
+
* Index-aligned with the input Ys: `true` when this line's individual tag is
|
|
20
|
+
* collapsed into a cluster (a multi-line group) and should be suppressed.
|
|
21
|
+
*/
|
|
22
|
+
hidden: boolean[];
|
|
23
|
+
/** One entry per multi-line cluster (singletons render normally, never here). */
|
|
24
|
+
groups: ReferenceGroup[];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Single-linkage cluster of reference-line handle Ys: lines whose sorted Y gaps are
|
|
29
|
+
* all `<= radius` chain into one group. Entries `< 0` (not a Form-A line / off the
|
|
30
|
+
* canvas) are ignored. Returns which lines are collapsed (`hidden`) plus a centroid
|
|
31
|
+
* + count per multi-line cluster. A non-positive `radius` disables grouping.
|
|
32
|
+
*/
|
|
33
|
+
export function groupReferenceLines(
|
|
34
|
+
ys: number[],
|
|
35
|
+
radius: number,
|
|
36
|
+
): ReferenceGrouping {
|
|
37
|
+
"worklet";
|
|
38
|
+
const hidden: boolean[] = [];
|
|
39
|
+
for (let i = 0; i < ys.length; i++) hidden.push(false);
|
|
40
|
+
const groups: ReferenceGroup[] = [];
|
|
41
|
+
if (radius <= 0) return { hidden, groups };
|
|
42
|
+
|
|
43
|
+
const pts: { i: number; y: number }[] = [];
|
|
44
|
+
for (let i = 0; i < ys.length; i++) {
|
|
45
|
+
if (ys[i] >= 0) pts.push({ i, y: ys[i] });
|
|
46
|
+
}
|
|
47
|
+
pts.sort((a, b) => a.y - b.y);
|
|
48
|
+
|
|
49
|
+
let c = 0;
|
|
50
|
+
while (c < pts.length) {
|
|
51
|
+
let j = c;
|
|
52
|
+
let sum = pts[c].y;
|
|
53
|
+
while (j + 1 < pts.length && pts[j + 1].y - pts[j].y <= radius) {
|
|
54
|
+
j++;
|
|
55
|
+
sum += pts[j].y;
|
|
56
|
+
}
|
|
57
|
+
const count = j - c + 1;
|
|
58
|
+
if (count > 1) {
|
|
59
|
+
for (let k = c; k <= j; k++) hidden[pts[k].i] = true;
|
|
60
|
+
groups.push({ cy: sum / count, count });
|
|
61
|
+
}
|
|
62
|
+
c = j + 1;
|
|
63
|
+
}
|
|
64
|
+
return { hidden, groups };
|
|
65
|
+
}
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
FontWeight,
|
|
3
|
+
ReferenceLine,
|
|
4
|
+
ReferenceLineBadgeConfig,
|
|
5
|
+
} from "../types";
|
|
2
6
|
|
|
3
7
|
/** Which of the three reference-line forms a `ReferenceLine` resolves to. */
|
|
4
8
|
export type ReferenceLineForm = "line" | "value-band" | "time-band" | "none";
|
|
@@ -40,24 +44,86 @@ export function collectReferenceValues(lines: ReferenceLine[]): number[] {
|
|
|
40
44
|
return out;
|
|
41
45
|
}
|
|
42
46
|
|
|
43
|
-
/**
|
|
44
|
-
|
|
45
|
-
|
|
47
|
+
/**
|
|
48
|
+
* Fully-resolved badge **style/shape** + anchor — the resolved counterpart of
|
|
49
|
+
* {@link BadgeStyleConfig} (`position` / `icon` / `showText` plus the style knobs).
|
|
50
|
+
* Shared by the reference-line badge ({@link ResolvedReferenceBadge}) and the
|
|
51
|
+
* grouping count pill ({@link ResolvedReferenceGroupBadge}). Unset colors stay
|
|
52
|
+
* `undefined` so the overlay applies the appropriate theme default at render time.
|
|
53
|
+
*/
|
|
54
|
+
export interface ResolvedReferenceBadgeStyle {
|
|
55
|
+
position: "left" | "center" | "right";
|
|
46
56
|
/** Leading glyph, or "" for none. */
|
|
47
57
|
icon: string;
|
|
48
|
-
/** Whether the text label is shown. */
|
|
58
|
+
/** Whether the text label is shown (false → icon-only). */
|
|
49
59
|
showText: boolean;
|
|
50
|
-
/** undefined → theme tooltipBg at render time. */
|
|
51
60
|
background: string | undefined;
|
|
52
|
-
/** undefined → the line color at render time. */
|
|
53
61
|
borderColor: string | undefined;
|
|
62
|
+
/** Border stroke width in px. Default `1`. */
|
|
63
|
+
borderWidth: number;
|
|
54
64
|
radius: number;
|
|
65
|
+
textColor: string | undefined;
|
|
66
|
+
/** Per-badge font knobs; undefined → the chart font. */
|
|
67
|
+
fontSize: number | undefined;
|
|
68
|
+
fontFamily: string | undefined;
|
|
69
|
+
fontWeight: FontWeight | undefined;
|
|
70
|
+
/** Nudge the whole badge from its anchor, in px. Default `0`. */
|
|
71
|
+
offsetX: number;
|
|
72
|
+
offsetY: number;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** Fully-resolved presentation for a Form-A reference-line badge — the shared
|
|
76
|
+
* style/shape plus the in-range / legacy-text flags. */
|
|
77
|
+
export interface ResolvedReferenceBadge extends ResolvedReferenceBadgeStyle {
|
|
55
78
|
/** Show the pill at the value when in range (`badge`) vs only off-screen (legacy `offAxisBadge`). */
|
|
56
79
|
inRange: boolean;
|
|
57
80
|
/** Legacy `"word: value"` text format (off-axis badge) vs the `label`/value format. */
|
|
58
81
|
legacyText: boolean;
|
|
59
82
|
}
|
|
60
83
|
|
|
84
|
+
/** Fully-resolved styling for the grouping **count pill** — exactly the shared
|
|
85
|
+
* badge style/shape (no in-range / legacy concepts). */
|
|
86
|
+
export type ResolvedReferenceGroupBadge = ResolvedReferenceBadgeStyle;
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Resolves the shared style/shape + anchor of a {@link BadgeStyleConfig}-shaped
|
|
90
|
+
* badge config. `flat` supplies a reference line's flat `badge*` fallbacks
|
|
91
|
+
* (`badgeBackground` / `badgeBorderColor` / `badgeRadius`); omit it for the group
|
|
92
|
+
* pill. Theme defaults for the unset colors are applied at render time. Worklet —
|
|
93
|
+
* also called from the {@link resolveReferenceBadge} worklet.
|
|
94
|
+
*/
|
|
95
|
+
function resolveReferenceBadgeStyle(
|
|
96
|
+
cfg: ReferenceLineBadgeConfig | undefined,
|
|
97
|
+
flat?: ReferenceLine,
|
|
98
|
+
): ResolvedReferenceBadgeStyle {
|
|
99
|
+
"worklet";
|
|
100
|
+
return {
|
|
101
|
+
position: cfg?.position ?? "left",
|
|
102
|
+
icon: cfg?.icon ?? "",
|
|
103
|
+
showText: cfg?.text ?? true,
|
|
104
|
+
background: cfg?.background ?? flat?.badgeBackground,
|
|
105
|
+
borderColor: cfg?.borderColor ?? flat?.badgeBorderColor,
|
|
106
|
+
borderWidth: cfg?.borderWidth ?? 1,
|
|
107
|
+
radius: cfg?.radius ?? flat?.badgeRadius ?? 5,
|
|
108
|
+
textColor: cfg?.textColor,
|
|
109
|
+
fontSize: cfg?.fontSize,
|
|
110
|
+
fontFamily: cfg?.fontFamily,
|
|
111
|
+
fontWeight: cfg?.fontWeight,
|
|
112
|
+
offsetX: cfg?.offsetX ?? 0,
|
|
113
|
+
offsetY: cfg?.offsetY ?? 0,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Resolves the grouping count-pill styling from a {@link ReferenceLineBadgeConfig}
|
|
119
|
+
* (the same shape a per-line badge uses). Pure — driven only by the config.
|
|
120
|
+
*/
|
|
121
|
+
export function resolveReferenceGroupBadge(
|
|
122
|
+
badge?: ReferenceLineBadgeConfig,
|
|
123
|
+
): ResolvedReferenceGroupBadge {
|
|
124
|
+
return resolveReferenceBadgeStyle(badge);
|
|
125
|
+
}
|
|
126
|
+
|
|
61
127
|
/**
|
|
62
128
|
* Resolves a Form-A reference line's badge presentation from the new `badge`
|
|
63
129
|
* config or the legacy `offAxisBadge` flag (the `badge` config wins). Returns
|
|
@@ -70,24 +136,15 @@ export function resolveReferenceBadge(
|
|
|
70
136
|
if (rl.badge) {
|
|
71
137
|
const cfg = rl.badge === true ? undefined : rl.badge;
|
|
72
138
|
return {
|
|
73
|
-
|
|
74
|
-
icon: cfg?.icon ?? "",
|
|
75
|
-
showText: cfg?.text ?? true,
|
|
76
|
-
background: cfg?.background ?? rl.badgeBackground,
|
|
77
|
-
borderColor: cfg?.borderColor ?? rl.badgeBorderColor,
|
|
78
|
-
radius: cfg?.radius ?? rl.badgeRadius ?? 5,
|
|
139
|
+
...resolveReferenceBadgeStyle(cfg, rl),
|
|
79
140
|
inRange: true,
|
|
80
141
|
legacyText: false,
|
|
81
142
|
};
|
|
82
143
|
}
|
|
83
144
|
if (rl.offAxisBadge) {
|
|
145
|
+
// Legacy off-axis badge: no config object, but the flat `badge*` fallbacks apply.
|
|
84
146
|
return {
|
|
85
|
-
|
|
86
|
-
icon: "",
|
|
87
|
-
showText: true,
|
|
88
|
-
background: rl.badgeBackground,
|
|
89
|
-
borderColor: rl.badgeBorderColor,
|
|
90
|
-
radius: rl.badgeRadius ?? 5,
|
|
147
|
+
...resolveReferenceBadgeStyle(undefined, rl),
|
|
91
148
|
inRange: false,
|
|
92
149
|
legacyText: true,
|
|
93
150
|
};
|