react-native-livechart 4.20.0 → 4.21.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/AxisLabelOverlay.d.ts +5 -1
- package/dist/components/AxisLabelOverlay.d.ts.map +1 -1
- package/dist/components/CrosshairOverlay.d.ts +4 -2
- package/dist/components/CrosshairOverlay.d.ts.map +1 -1
- package/dist/components/CustomMarkerOverlay.d.ts.map +1 -1
- package/dist/components/CustomThresholdBadgeOverlay.d.ts +18 -0
- package/dist/components/CustomThresholdBadgeOverlay.d.ts.map +1 -0
- package/dist/components/CustomTooltipOverlay.d.ts +4 -2
- package/dist/components/CustomTooltipOverlay.d.ts.map +1 -1
- package/dist/components/DegenParticlesOverlay.d.ts.map +1 -1
- package/dist/components/ExtremaConnectorOverlay.d.ts +5 -1
- package/dist/components/ExtremaConnectorOverlay.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 +4 -2
- package/dist/components/MarkerOverlay.d.ts.map +1 -1
- package/dist/components/ReferenceLineOverlay.d.ts +10 -5
- package/dist/components/ReferenceLineOverlay.d.ts.map +1 -1
- package/dist/components/ReferenceLineSeriesOverlay.d.ts +19 -0
- package/dist/components/ReferenceLineSeriesOverlay.d.ts.map +1 -0
- package/dist/core/chartDataPresence.d.ts +8 -0
- package/dist/core/chartDataPresence.d.ts.map +1 -0
- package/dist/core/liveChartEngineTick.d.ts +6 -1
- package/dist/core/liveChartEngineTick.d.ts.map +1 -1
- package/dist/core/resolveConfig.d.ts +32 -1
- package/dist/core/resolveConfig.d.ts.map +1 -1
- package/dist/core/useLiveChartEngine.d.ts +9 -1
- package/dist/core/useLiveChartEngine.d.ts.map +1 -1
- package/dist/core/useLiveChartSeriesEngine.d.ts.map +1 -1
- package/dist/draw/candle.d.ts +3 -1
- package/dist/draw/candle.d.ts.map +1 -1
- package/dist/draw/candleGap.d.ts +14 -0
- package/dist/draw/candleGap.d.ts.map +1 -0
- package/dist/draw/lineGap.d.ts +25 -0
- package/dist/draw/lineGap.d.ts.map +1 -0
- package/dist/draw/markerAtlas.d.ts +3 -2
- package/dist/draw/markerAtlas.d.ts.map +1 -1
- package/dist/hooks/crosshairShared.d.ts +7 -3
- package/dist/hooks/crosshairShared.d.ts.map +1 -1
- package/dist/hooks/useCandleGapPaths.d.ts +12 -0
- package/dist/hooks/useCandleGapPaths.d.ts.map +1 -0
- package/dist/hooks/useChartPaths.d.ts +4 -1
- package/dist/hooks/useChartPaths.d.ts.map +1 -1
- package/dist/hooks/useChartReveal.d.ts +1 -1
- package/dist/hooks/useChartReveal.d.ts.map +1 -1
- package/dist/hooks/useCrosshair.d.ts +9 -5
- package/dist/hooks/useCrosshair.d.ts.map +1 -1
- package/dist/hooks/useDegen.d.ts.map +1 -1
- package/dist/hooks/useLineGapPaths.d.ts +10 -0
- package/dist/hooks/useLineGapPaths.d.ts.map +1 -0
- package/dist/hooks/useLiveChartHasData.d.ts +2 -2
- package/dist/hooks/useLiveChartHasData.d.ts.map +1 -1
- package/dist/hooks/useReferenceLine.d.ts +4 -3
- package/dist/hooks/useReferenceLine.d.ts.map +1 -1
- package/dist/hooks/useReferenceLineSeries.d.ts +23 -0
- package/dist/hooks/useReferenceLineSeries.d.ts.map +1 -0
- package/dist/hooks/useReverseMorphEngineInputs.d.ts.map +1 -1
- package/dist/hooks/useThreshold.d.ts +13 -13
- package/dist/hooks/useThreshold.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/math/candleGaps.d.ts +18 -0
- package/dist/math/candleGaps.d.ts.map +1 -0
- package/dist/math/referenceLineSeries.d.ts +12 -0
- package/dist/math/referenceLineSeries.d.ts.map +1 -0
- package/dist/math/referenceLines.d.ts +5 -5
- package/dist/math/referenceLines.d.ts.map +1 -1
- package/dist/math/spline.d.ts +5 -1
- package/dist/math/spline.d.ts.map +1 -1
- package/dist/types.d.ts +191 -17
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/AxisLabelOverlay.tsx +162 -81
- package/src/components/CrosshairOverlay.tsx +394 -147
- package/src/components/CustomMarkerOverlay.tsx +9 -6
- package/src/components/CustomThresholdBadgeOverlay.tsx +74 -0
- package/src/components/CustomTooltipOverlay.tsx +7 -3
- package/src/components/DegenParticlesOverlay.tsx +34 -23
- package/src/components/ExtremaConnectorOverlay.tsx +43 -3
- package/src/components/LiveChart.tsx +1918 -974
- package/src/components/LiveChartSeries.tsx +445 -296
- package/src/components/MarkerOverlay.tsx +215 -156
- package/src/components/ReferenceLineOverlay.tsx +113 -55
- package/src/components/ReferenceLineSeriesOverlay.tsx +141 -0
- package/src/core/chartDataPresence.ts +24 -0
- package/src/core/liveChartEngineTick.ts +34 -1
- package/src/core/resolveConfig.ts +186 -0
- package/src/core/useLiveChartEngine.ts +36 -1
- package/src/core/useLiveChartSeriesEngine.ts +2 -0
- package/src/draw/candle.ts +1 -1
- package/src/draw/candleGap.ts +132 -0
- package/src/draw/lineGap.ts +180 -0
- package/src/draw/markerAtlas.ts +8 -3
- package/src/hooks/crosshairShared.ts +92 -11
- package/src/hooks/useCandleGapPaths.ts +88 -0
- package/src/hooks/useChartPaths.ts +81 -22
- package/src/hooks/useChartReveal.ts +1 -1
- package/src/hooks/useCrosshair.ts +178 -69
- package/src/hooks/useDegen.ts +82 -53
- package/src/hooks/useLineGapPaths.ts +76 -0
- package/src/hooks/useLiveChartHasData.ts +8 -4
- package/src/hooks/useReferenceLine.ts +6 -5
- package/src/hooks/useReferenceLineSeries.ts +101 -0
- package/src/hooks/useReverseMorphEngineInputs.ts +11 -20
- package/src/hooks/useThreshold.ts +31 -22
- package/src/index.ts +15 -0
- package/src/math/candleGaps.ts +120 -0
- package/src/math/referenceLineSeries.ts +83 -0
- package/src/math/referenceLines.ts +34 -6
- package/src/math/spline.ts +15 -5
- package/src/types.ts +202 -17
|
@@ -30,6 +30,7 @@ import {
|
|
|
30
30
|
isConnectorMarker,
|
|
31
31
|
markerAppearanceSig,
|
|
32
32
|
type AtlasCell,
|
|
33
|
+
type MarkerAtlasPalette,
|
|
33
34
|
} from "../draw/markerAtlas";
|
|
34
35
|
import {
|
|
35
36
|
markersSignature,
|
|
@@ -45,6 +46,7 @@ import type {
|
|
|
45
46
|
LiveChartPalette,
|
|
46
47
|
LiveChartPoint,
|
|
47
48
|
Marker,
|
|
49
|
+
MarkerGroupBadge,
|
|
48
50
|
MarkerRenderContext,
|
|
49
51
|
SeriesConfig,
|
|
50
52
|
} from "../types";
|
|
@@ -85,7 +87,12 @@ function pushGroupCountBadge(
|
|
|
85
87
|
const bg = cells[groupBgSig(repColor)];
|
|
86
88
|
if (bg) {
|
|
87
89
|
transforms.push(
|
|
88
|
-
Skia.RSXform(
|
|
90
|
+
Skia.RSXform(
|
|
91
|
+
invScale * mul,
|
|
92
|
+
0,
|
|
93
|
+
cx - (bg.w * mul) / 2,
|
|
94
|
+
cy - (bg.h * mul) / 2,
|
|
95
|
+
),
|
|
89
96
|
);
|
|
90
97
|
sprites.push(bg.rect);
|
|
91
98
|
}
|
|
@@ -219,18 +226,7 @@ function ConnectorGlyph({
|
|
|
219
226
|
*
|
|
220
227
|
* Glyph precedence per marker: `image` → `icon` (text) → built-in `kind` shape.
|
|
221
228
|
*/
|
|
222
|
-
|
|
223
|
-
markers,
|
|
224
|
-
engine,
|
|
225
|
-
padding,
|
|
226
|
-
palette,
|
|
227
|
-
font,
|
|
228
|
-
series,
|
|
229
|
-
lineData,
|
|
230
|
-
lineLinear,
|
|
231
|
-
renderMarker,
|
|
232
|
-
cluster,
|
|
233
|
-
}: {
|
|
229
|
+
type MarkerOverlayProps = {
|
|
234
230
|
markers: SharedValue<Marker[]>;
|
|
235
231
|
engine: ChartEngineLayout;
|
|
236
232
|
padding: ChartPadding;
|
|
@@ -250,9 +246,24 @@ export function MarkerOverlay({
|
|
|
250
246
|
renderMarker?: (marker: Marker, ctx: MarkerRenderContext) => unknown;
|
|
251
247
|
/** Collision config; `"stacked"` fans/collapses co-located markers. */
|
|
252
248
|
cluster: ResolvedMarkerCluster;
|
|
253
|
-
}
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
function useMarkerOverlayModel({
|
|
252
|
+
markers,
|
|
253
|
+
engine,
|
|
254
|
+
padding,
|
|
255
|
+
palette,
|
|
256
|
+
font,
|
|
257
|
+
series,
|
|
258
|
+
lineData,
|
|
259
|
+
lineLinear,
|
|
260
|
+
renderMarker,
|
|
261
|
+
cluster,
|
|
262
|
+
}: MarkerOverlayProps) {
|
|
254
263
|
// Seed from the current markers at mount; the reaction below keeps it in sync.
|
|
255
|
-
const [snapshot, setSnapshot] = useState<Marker[]>(() =>
|
|
264
|
+
const [snapshot, setSnapshot] = useState<Marker[]>(() =>
|
|
265
|
+
markers.get().slice(),
|
|
266
|
+
);
|
|
256
267
|
|
|
257
268
|
// Read the `markers` prop from closure rather than a SharedValue passed
|
|
258
269
|
// through `scheduleOnRN` (which loses `.get()`); mirrors the data model.
|
|
@@ -295,44 +306,85 @@ export function MarkerOverlay({
|
|
|
295
306
|
return o;
|
|
296
307
|
}, [customKey]);
|
|
297
308
|
|
|
298
|
-
// Rebuild the atlas image only when the set of distinct appearances or the
|
|
299
|
-
// theme/font changes — never per frame. `markersSignature` already drives the
|
|
300
|
-
// snapshot, so this useMemo re-runs at most at the snapshot cadence.
|
|
301
|
-
const appearanceKey = useMemo(() => {
|
|
302
|
-
const sigs = new Set<string>();
|
|
303
|
-
for (let i = 0; i < snapshot.length; i++) {
|
|
304
|
-
const m = snapshot[i];
|
|
305
|
-
if (!isConnectorMarker(m) && !customIds[m.id])
|
|
306
|
-
sigs.add(markerAppearanceSig(m));
|
|
307
|
-
}
|
|
308
|
-
return Array.from(sigs).sort().join("\x1e");
|
|
309
|
-
}, [snapshot, customIds]);
|
|
310
|
-
// Cells bake in resolved colors; include the palette fields they depend on.
|
|
311
|
-
const paletteKey = `${palette.bgRgb.join(",")}|${palette.line}|${palette.refLine}|${palette.dotUp}|${palette.refLabel}`;
|
|
312
309
|
// Rasterize at the screen's device-pixel ratio so sprites stay crisp on
|
|
313
310
|
// retina canvases instead of being upscaled from a logical-sized texture.
|
|
314
311
|
const dpr = PixelRatio.get();
|
|
315
312
|
const clusterStacked = cluster.mode === "stacked";
|
|
313
|
+
const [paletteBgR, paletteBgG, paletteBgB] = palette.bgRgb;
|
|
314
|
+
const paletteLine = palette.line;
|
|
315
|
+
const paletteRefLine = palette.refLine;
|
|
316
|
+
const paletteDotUp = palette.dotUp;
|
|
317
|
+
const paletteRefLabel = palette.refLabel;
|
|
318
|
+
const atlasPalette = useMemo<MarkerAtlasPalette>(
|
|
319
|
+
() => ({
|
|
320
|
+
bgRgb: [paletteBgR, paletteBgG, paletteBgB],
|
|
321
|
+
line: paletteLine,
|
|
322
|
+
refLine: paletteRefLine,
|
|
323
|
+
dotUp: paletteDotUp,
|
|
324
|
+
refLabel: paletteRefLabel,
|
|
325
|
+
}),
|
|
326
|
+
[
|
|
327
|
+
paletteBgR,
|
|
328
|
+
paletteBgG,
|
|
329
|
+
paletteBgB,
|
|
330
|
+
paletteLine,
|
|
331
|
+
paletteRefLine,
|
|
332
|
+
paletteDotUp,
|
|
333
|
+
paletteRefLabel,
|
|
334
|
+
],
|
|
335
|
+
);
|
|
316
336
|
// A dedicated group badge (object form) bakes one extra atlas cell; its image
|
|
317
337
|
// identity + styling drive the rebuild key alongside the marker appearances.
|
|
318
338
|
const groupBadgeCfg =
|
|
319
339
|
typeof cluster.groupBadge === "object" ? cluster.groupBadge : undefined;
|
|
340
|
+
const hasGroupBadge = groupBadgeCfg !== undefined;
|
|
320
341
|
const groupBadgeImage = groupBadgeCfg?.image;
|
|
321
|
-
const
|
|
322
|
-
|
|
323
|
-
|
|
342
|
+
const groupBadgeIcon = groupBadgeCfg?.icon;
|
|
343
|
+
const groupBadgeColor = groupBadgeCfg?.color;
|
|
344
|
+
const groupBadgePill = groupBadgeCfg?.pill;
|
|
345
|
+
const groupBadgeSize = groupBadgeCfg?.size;
|
|
346
|
+
const groupBadgeLetterSpacing = groupBadgeCfg?.letterSpacing;
|
|
347
|
+
const atlasGroupBadge = useMemo<MarkerGroupBadge | undefined>(
|
|
348
|
+
() =>
|
|
349
|
+
hasGroupBadge
|
|
350
|
+
? {
|
|
351
|
+
image: groupBadgeImage,
|
|
352
|
+
icon: groupBadgeIcon,
|
|
353
|
+
color: groupBadgeColor,
|
|
354
|
+
pill: groupBadgePill,
|
|
355
|
+
size: groupBadgeSize,
|
|
356
|
+
letterSpacing: groupBadgeLetterSpacing,
|
|
357
|
+
}
|
|
358
|
+
: undefined,
|
|
359
|
+
[
|
|
360
|
+
hasGroupBadge,
|
|
361
|
+
groupBadgeImage,
|
|
362
|
+
groupBadgeIcon,
|
|
363
|
+
groupBadgeColor,
|
|
364
|
+
groupBadgePill,
|
|
365
|
+
groupBadgeSize,
|
|
366
|
+
groupBadgeLetterSpacing,
|
|
367
|
+
],
|
|
368
|
+
);
|
|
324
369
|
const atlas = useMemo(
|
|
325
370
|
() =>
|
|
326
371
|
buildMarkerAtlas(
|
|
327
372
|
snapshot.filter((m) => !customIds[m.id]),
|
|
328
|
-
|
|
373
|
+
atlasPalette,
|
|
329
374
|
font,
|
|
330
375
|
dpr,
|
|
331
376
|
clusterStacked,
|
|
332
|
-
|
|
377
|
+
atlasGroupBadge,
|
|
333
378
|
),
|
|
334
|
-
|
|
335
|
-
|
|
379
|
+
[
|
|
380
|
+
snapshot,
|
|
381
|
+
customIds,
|
|
382
|
+
atlasPalette,
|
|
383
|
+
font,
|
|
384
|
+
dpr,
|
|
385
|
+
clusterStacked,
|
|
386
|
+
atlasGroupBadge,
|
|
387
|
+
],
|
|
336
388
|
);
|
|
337
389
|
const cells: Record<string, AtlasCell> = atlas.cells;
|
|
338
390
|
const atlasImage = atlas.image;
|
|
@@ -367,133 +419,133 @@ export function MarkerOverlay({
|
|
|
367
419
|
// Single per-frame worklet: project all markers, then emit a transform +
|
|
368
420
|
// source rect for each visible atlas marker. Three mappers total regardless
|
|
369
421
|
// of marker count (this + the two thin readers below).
|
|
370
|
-
const atlasData = useDerivedValue(
|
|
371
|
-
()
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
422
|
+
const atlasData = useDerivedValue(() => {
|
|
423
|
+
const ms = markers.get();
|
|
424
|
+
const proj = projRef.current!;
|
|
425
|
+
proj.tick = !proj.tick;
|
|
426
|
+
const buf = proj.tick ? proj.a : proj.b;
|
|
427
|
+
projectMarkers(ms, buf, {
|
|
428
|
+
canvasWidth: engine.canvasWidth.get(),
|
|
429
|
+
canvasHeight: engine.canvasHeight.get(),
|
|
430
|
+
padTop: padding.top,
|
|
431
|
+
padBottom: padding.bottom,
|
|
432
|
+
padLeft: padding.left,
|
|
433
|
+
padRight: padding.right,
|
|
434
|
+
timestamp: engine.timestamp.get(),
|
|
435
|
+
displayWindow: engine.displayWindow.get(),
|
|
436
|
+
displayMin: engine.displayMin.get(),
|
|
437
|
+
displayMax: engine.displayMax.get(),
|
|
438
|
+
series: series?.get(),
|
|
439
|
+
lineData: lineData?.get(),
|
|
440
|
+
lineLinear,
|
|
441
|
+
});
|
|
442
|
+
clusterMarkers(ms, buf, {
|
|
443
|
+
config: cluster,
|
|
444
|
+
minY: 0,
|
|
445
|
+
maxY: engine.canvasHeight.get(),
|
|
446
|
+
});
|
|
447
|
+
const atlasFrames = atlasFrameRef.current!;
|
|
448
|
+
atlasFrames.tick = !atlasFrames.tick;
|
|
449
|
+
const frame = atlasFrames.tick ? atlasFrames.a : atlasFrames.b;
|
|
450
|
+
const transforms = frame.transforms;
|
|
451
|
+
const sprites = frame.sprites;
|
|
452
|
+
transforms.length = 0;
|
|
453
|
+
sprites.length = 0;
|
|
454
|
+
for (let i = 0; i < ms.length; i++) {
|
|
455
|
+
const pt = buf[i];
|
|
456
|
+
// Collapsed-cluster members fold into their representative's badge.
|
|
457
|
+
if (!pt.visible || pt.hidden) continue;
|
|
458
|
+
const m = ms[i];
|
|
459
|
+
if (isConnectorMarker(m)) continue;
|
|
460
|
+
// Custom-rendered markers are floated as RN views, not drawn here.
|
|
461
|
+
if (customIds[m.id]) continue;
|
|
462
|
+
// Collapsed cluster. By default a round count badge; with
|
|
463
|
+
// `groupBadge: "marker"` the representative marker's own glyph, or with a
|
|
464
|
+
// `MarkerGroupBadge` object a dedicated baked badge — either optionally
|
|
465
|
+
// carrying a corner count, all within this one `drawAtlas`.
|
|
466
|
+
if (pt.isGrouped) {
|
|
467
|
+
const repColor = m.color ?? defaultMarkerColor(m.kind, palette);
|
|
468
|
+
const gb = cluster.groupBadge;
|
|
469
|
+
// Pick the non-count glyph cell: a dedicated group badge (object form)
|
|
470
|
+
// or the representative marker's own appearance.
|
|
471
|
+
const glyphCell =
|
|
472
|
+
typeof gb === "object" && gb !== null
|
|
473
|
+
? cells[GROUP_BADGE_SIG]
|
|
474
|
+
: gb === "marker"
|
|
475
|
+
? cells[markerAppearanceSig(m)]
|
|
476
|
+
: undefined;
|
|
477
|
+
if (glyphCell) {
|
|
478
|
+
transforms.push(
|
|
479
|
+
Skia.RSXform(
|
|
480
|
+
invScale,
|
|
481
|
+
0,
|
|
482
|
+
pt.x - glyphCell.w / 2,
|
|
483
|
+
pt.y - glyphCell.h / 2,
|
|
484
|
+
),
|
|
485
|
+
);
|
|
486
|
+
sprites.push(glyphCell.rect);
|
|
487
|
+
if (cluster.showGroupCount) {
|
|
488
|
+
pushGroupCountBadge(
|
|
489
|
+
transforms,
|
|
490
|
+
sprites,
|
|
491
|
+
cells,
|
|
492
|
+
digitWidths,
|
|
493
|
+
invScale,
|
|
494
|
+
pt.x + (glyphCell.w / 2) * GROUP_CORNER_INSET,
|
|
495
|
+
pt.y - (glyphCell.h / 2) * GROUP_CORNER_INSET,
|
|
496
|
+
repColor,
|
|
497
|
+
pt.groupCount,
|
|
498
|
+
GROUP_CORNER_SCALE,
|
|
499
|
+
groupBadgeCfg?.letterSpacing ?? 0,
|
|
434
500
|
);
|
|
435
|
-
sprites.push(glyphCell.rect);
|
|
436
|
-
if (cluster.showGroupCount) {
|
|
437
|
-
pushGroupCountBadge(
|
|
438
|
-
transforms,
|
|
439
|
-
sprites,
|
|
440
|
-
cells,
|
|
441
|
-
digitWidths,
|
|
442
|
-
invScale,
|
|
443
|
-
pt.x + (glyphCell.w / 2) * GROUP_CORNER_INSET,
|
|
444
|
-
pt.y - (glyphCell.h / 2) * GROUP_CORNER_INSET,
|
|
445
|
-
repColor,
|
|
446
|
-
pt.groupCount,
|
|
447
|
-
GROUP_CORNER_SCALE,
|
|
448
|
-
groupBadgeCfg?.letterSpacing ?? 0,
|
|
449
|
-
);
|
|
450
|
-
}
|
|
451
|
-
continue;
|
|
452
501
|
}
|
|
453
|
-
// Default — or fall back here when a non-count badge has no baked cell
|
|
454
|
-
// (e.g. an empty group-badge config): the round count badge.
|
|
455
|
-
pushGroupCountBadge(
|
|
456
|
-
transforms,
|
|
457
|
-
sprites,
|
|
458
|
-
cells,
|
|
459
|
-
digitWidths,
|
|
460
|
-
invScale,
|
|
461
|
-
pt.x,
|
|
462
|
-
pt.y,
|
|
463
|
-
repColor,
|
|
464
|
-
pt.groupCount,
|
|
465
|
-
1,
|
|
466
|
-
groupBadgeCfg?.letterSpacing ?? 0,
|
|
467
|
-
);
|
|
468
502
|
continue;
|
|
469
503
|
}
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
504
|
+
// Default — or fall back here when a non-count badge has no baked cell
|
|
505
|
+
// (e.g. an empty group-badge config): the round count badge.
|
|
506
|
+
pushGroupCountBadge(
|
|
507
|
+
transforms,
|
|
508
|
+
sprites,
|
|
509
|
+
cells,
|
|
510
|
+
digitWidths,
|
|
511
|
+
invScale,
|
|
512
|
+
pt.x,
|
|
513
|
+
pt.y,
|
|
514
|
+
repColor,
|
|
515
|
+
pt.groupCount,
|
|
516
|
+
1,
|
|
517
|
+
groupBadgeCfg?.letterSpacing ?? 0,
|
|
476
518
|
);
|
|
477
|
-
|
|
519
|
+
continue;
|
|
478
520
|
}
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
521
|
+
const cell = cells[markerAppearanceSig(m)];
|
|
522
|
+
if (!cell) continue;
|
|
523
|
+
// Center the cell on the projected point. The cell's source rect is in
|
|
524
|
+
// device pixels, so scale by 1/dpr to land it at its logical size.
|
|
525
|
+
transforms.push(
|
|
526
|
+
Skia.RSXform(invScale, 0, pt.x - cell.w / 2, pt.y - cell.h / 2),
|
|
527
|
+
);
|
|
528
|
+
sprites.push(cell.rect);
|
|
529
|
+
}
|
|
530
|
+
return frame;
|
|
531
|
+
}, [
|
|
532
|
+
cells,
|
|
533
|
+
customIds,
|
|
534
|
+
invScale,
|
|
535
|
+
digitWidths,
|
|
536
|
+
markers,
|
|
537
|
+
engine,
|
|
538
|
+
padding,
|
|
539
|
+
palette,
|
|
540
|
+
series,
|
|
541
|
+
lineData,
|
|
542
|
+
lineLinear,
|
|
543
|
+
cluster,
|
|
544
|
+
]);
|
|
545
|
+
const transforms = useDerivedValue(
|
|
546
|
+
() => atlasData.get().transforms,
|
|
547
|
+
[atlasData],
|
|
495
548
|
);
|
|
496
|
-
const transforms = useDerivedValue(() => atlasData.get().transforms, [atlasData]);
|
|
497
549
|
const sprites = useDerivedValue(() => atlasData.get().sprites, [atlasData]);
|
|
498
550
|
|
|
499
551
|
const axisY = useDerivedValue(
|
|
@@ -502,6 +554,13 @@ export function MarkerOverlay({
|
|
|
502
554
|
|
|
503
555
|
const connectors = snapshot.filter(isConnectorMarker);
|
|
504
556
|
|
|
557
|
+
return { atlasImage, sprites, transforms, connectors, axisY };
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
export function MarkerOverlay(props: MarkerOverlayProps) {
|
|
561
|
+
const { engine, padding, palette, series, lineData, lineLinear } = props;
|
|
562
|
+
const { atlasImage, sprites, transforms, connectors, axisY } =
|
|
563
|
+
useMarkerOverlayModel(props);
|
|
505
564
|
return (
|
|
506
565
|
<Group>
|
|
507
566
|
{atlasImage && (
|