react-native-livechart 4.4.0 → 4.5.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/LiveChart.d.ts.map +1 -1
- package/dist/components/LiveChartSeries.d.ts.map +1 -1
- package/dist/components/LoadingOverlay.d.ts +9 -1
- package/dist/components/LoadingOverlay.d.ts.map +1 -1
- package/dist/constants.d.ts +14 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/core/resolveConfig.d.ts +35 -1
- package/dist/core/resolveConfig.d.ts.map +1 -1
- package/dist/hooks/useChartPaths.d.ts +5 -1
- package/dist/hooks/useChartPaths.d.ts.map +1 -1
- package/dist/hooks/useChartReveal.d.ts +3 -1
- package/dist/hooks/useChartReveal.d.ts.map +1 -1
- package/dist/hooks/useModeBlend.d.ts +4 -1
- package/dist/hooks/useModeBlend.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/math/squiggly.d.ts +8 -5
- package/dist/math/squiggly.d.ts.map +1 -1
- package/dist/types.d.ts +82 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/LiveChart.tsx +126 -42
- package/src/components/LiveChartSeries.tsx +95 -26
- package/src/components/LoadingOverlay.tsx +25 -6
- package/src/constants.ts +17 -0
- package/src/core/resolveConfig.ts +63 -0
- package/src/hooks/useChartPaths.ts +11 -1
- package/src/hooks/useChartReveal.ts +7 -2
- package/src/hooks/useModeBlend.ts +5 -3
- package/src/index.ts +2 -0
- package/src/math/squiggly.ts +21 -7
- package/src/types.ts +84 -2
|
@@ -14,6 +14,7 @@ import type {
|
|
|
14
14
|
LineStyleConfig,
|
|
15
15
|
LiveChartMetrics,
|
|
16
16
|
LiveChartMetricsOverride,
|
|
17
|
+
LoadingConfig,
|
|
17
18
|
MarkerClusterConfig,
|
|
18
19
|
DotConfig,
|
|
19
20
|
DotRingConfig,
|
|
@@ -29,6 +30,7 @@ import type {
|
|
|
29
30
|
ThresholdConfig,
|
|
30
31
|
ThresholdLineConfig,
|
|
31
32
|
TradeEvent,
|
|
33
|
+
TransitionConfig,
|
|
32
34
|
ValueLineConfig,
|
|
33
35
|
VolumeConfig,
|
|
34
36
|
XAxisConfig,
|
|
@@ -45,6 +47,8 @@ import {
|
|
|
45
47
|
EMPTY_STATE_METRICS_DEFAULTS,
|
|
46
48
|
FADE_EDGE_WIDTH,
|
|
47
49
|
GRID_METRICS_DEFAULTS,
|
|
50
|
+
LOADING_WAVE_AMPLITUDE,
|
|
51
|
+
LOADING_WAVE_SPEED,
|
|
48
52
|
MOTION_METRICS_DEFAULTS,
|
|
49
53
|
RETURN_TO_LIVE_MS,
|
|
50
54
|
} from "../constants";
|
|
@@ -165,6 +169,8 @@ export interface ResolvedScrubConfig {
|
|
|
165
169
|
tooltipShowTime: boolean;
|
|
166
170
|
/** Press-and-hold delay (ms) before scrubbing activates. 0 = immediate. */
|
|
167
171
|
panGestureDelay: number;
|
|
172
|
+
/** Fade markers + reference lines out while scrubbing. */
|
|
173
|
+
hideOverlaysOnScrub: boolean;
|
|
168
174
|
}
|
|
169
175
|
|
|
170
176
|
export interface ResolvedScrubActionConfig {
|
|
@@ -477,6 +483,32 @@ export function resolveReturnToLiveMs(
|
|
|
477
483
|
return d > 0 ? d : 0;
|
|
478
484
|
}
|
|
479
485
|
|
|
486
|
+
/**
|
|
487
|
+
* Resolved transition durations. `undefined` for a field means "use the
|
|
488
|
+
* component's built-in default" (so we don't duplicate the default constants
|
|
489
|
+
* here); a number is an explicit duration in ms (clamped to ≥ 0).
|
|
490
|
+
*/
|
|
491
|
+
export interface ResolvedTransitionConfig {
|
|
492
|
+
reveal: number | undefined;
|
|
493
|
+
mode: number | undefined;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
const clampMs = (v: number | undefined): number | undefined =>
|
|
497
|
+
v == null ? undefined : v > 0 ? v : 0;
|
|
498
|
+
|
|
499
|
+
/**
|
|
500
|
+
* Resolves the `transitions` prop. `false` → all transitions instant (`0`);
|
|
501
|
+
* `true` / omitted → defaults (both `undefined` = use the built-in durations);
|
|
502
|
+
* an object → per-transition overrides (an omitted field keeps its default).
|
|
503
|
+
*/
|
|
504
|
+
export function resolveTransitions(
|
|
505
|
+
prop: boolean | TransitionConfig | undefined,
|
|
506
|
+
): ResolvedTransitionConfig {
|
|
507
|
+
if (prop === false) return { reveal: 0, mode: 0 };
|
|
508
|
+
if (prop == null || prop === true) return { reveal: undefined, mode: undefined };
|
|
509
|
+
return { reveal: clampMs(prop.reveal), mode: clampMs(prop.mode) };
|
|
510
|
+
}
|
|
511
|
+
|
|
480
512
|
const AXIS_LABEL_DEFAULTS: ResolvedAxisLabelConfig = {
|
|
481
513
|
format: undefined,
|
|
482
514
|
color: undefined,
|
|
@@ -571,6 +603,7 @@ const SCRUB_DEFAULTS: ResolvedScrubConfig = {
|
|
|
571
603
|
tooltipShowValue: true,
|
|
572
604
|
tooltipShowTime: true,
|
|
573
605
|
panGestureDelay: 0,
|
|
606
|
+
hideOverlaysOnScrub: false,
|
|
574
607
|
};
|
|
575
608
|
|
|
576
609
|
/**
|
|
@@ -590,6 +623,36 @@ export function resolveScrub(
|
|
|
590
623
|
return resolved;
|
|
591
624
|
}
|
|
592
625
|
|
|
626
|
+
export interface ResolvedLoadingConfig {
|
|
627
|
+
/** undefined → palette.gridLine */
|
|
628
|
+
color: string | undefined;
|
|
629
|
+
/** undefined → the chart's line strokeWidth */
|
|
630
|
+
strokeWidth: number | undefined;
|
|
631
|
+
/** Base breathing-wave amplitude (px). */
|
|
632
|
+
amplitude: number;
|
|
633
|
+
/** Breathing-wave speed multiplier. */
|
|
634
|
+
speed: number;
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
const LOADING_DEFAULTS: ResolvedLoadingConfig = {
|
|
638
|
+
color: undefined,
|
|
639
|
+
strokeWidth: undefined,
|
|
640
|
+
amplitude: LOADING_WAVE_AMPLITUDE,
|
|
641
|
+
speed: LOADING_WAVE_SPEED,
|
|
642
|
+
};
|
|
643
|
+
|
|
644
|
+
/**
|
|
645
|
+
* Resolves the `loading` prop to a fully-typed config or null (not loading).
|
|
646
|
+
* `true` → defaults (loading on, built-in look), object → merged with defaults
|
|
647
|
+
* (loading on, restyled), `false` / omitted → null. So a non-null result is the
|
|
648
|
+
* "is loading" flag and carries the resolved styling.
|
|
649
|
+
*/
|
|
650
|
+
export function resolveLoading(
|
|
651
|
+
prop: boolean | LoadingConfig | undefined,
|
|
652
|
+
): ResolvedLoadingConfig | null {
|
|
653
|
+
return resolveToggle(prop, LOADING_DEFAULTS, false);
|
|
654
|
+
}
|
|
655
|
+
|
|
593
656
|
const SCRUB_ACTION_DEFAULTS: ResolvedScrubActionConfig = {
|
|
594
657
|
icon: "+",
|
|
595
658
|
background: undefined,
|
|
@@ -35,6 +35,10 @@ export function useChartPaths(
|
|
|
35
35
|
*/
|
|
36
36
|
edgeValue?: SharedValue<number>,
|
|
37
37
|
followViewEdge = false,
|
|
38
|
+
/** Loading squiggle wave amplitude (px) for the reveal morph. Default 14. */
|
|
39
|
+
squiggleAmplitude = 14,
|
|
40
|
+
/** Loading squiggle wave speed multiplier for the reveal morph. Default 1. */
|
|
41
|
+
squiggleSpeed = 1,
|
|
38
42
|
) {
|
|
39
43
|
const lineBuilder = usePathBuilder();
|
|
40
44
|
const fillBuilder = usePathBuilder();
|
|
@@ -86,7 +90,13 @@ export function useChartPaths(
|
|
|
86
90
|
// Compute squiggly Y values at the same X positions as the real line
|
|
87
91
|
const centerY =
|
|
88
92
|
(engine.canvasHeight.get() - padding.bottom + padding.top) / 2;
|
|
89
|
-
const squigglyPts = squigglifyPts(
|
|
93
|
+
const squigglyPts = squigglifyPts(
|
|
94
|
+
realPts,
|
|
95
|
+
engine.timestamp.get(),
|
|
96
|
+
centerY,
|
|
97
|
+
squiggleAmplitude,
|
|
98
|
+
squiggleSpeed,
|
|
99
|
+
);
|
|
90
100
|
|
|
91
101
|
// Blend center-out: centre of chart reveals first, edges last
|
|
92
102
|
return blendPtsY(
|
|
@@ -60,6 +60,8 @@ export function useChartReveal(
|
|
|
60
60
|
hasData: SharedValue<boolean>,
|
|
61
61
|
/** Static charts skip the entry ramp: morphT snaps to its target, no `withTiming`. */
|
|
62
62
|
isStatic = false,
|
|
63
|
+
/** Reveal/collapse duration (ms). Default {@link CHART_REVEAL_DURATION_MS}; `0` snaps. */
|
|
64
|
+
revealDuration: number = CHART_REVEAL_DURATION_MS,
|
|
63
65
|
): ChartRevealState {
|
|
64
66
|
// Best-guess initial so the common case — a live chart that already has data
|
|
65
67
|
// and isn't loading — paints fully revealed with no flash. The reaction below
|
|
@@ -85,15 +87,18 @@ export function useChartReveal(
|
|
|
85
87
|
return;
|
|
86
88
|
}
|
|
87
89
|
if (prev !== chartVisible) {
|
|
90
|
+
// 0ms → withTiming resolves on the next frame (effectively a snap), so an
|
|
91
|
+
// explicit `transitions={{ reveal: 0 }}` / `transitions={false}` removes
|
|
92
|
+
// the grow-in without a special-case branch.
|
|
88
93
|
morphT.set(
|
|
89
94
|
withTiming(chartVisible ? 1 : 0, {
|
|
90
|
-
duration:
|
|
95
|
+
duration: revealDuration,
|
|
91
96
|
easing: Easing.out(Easing.cubic),
|
|
92
97
|
}),
|
|
93
98
|
);
|
|
94
99
|
}
|
|
95
100
|
},
|
|
96
|
-
[hasData, isStatic],
|
|
101
|
+
[hasData, isStatic, revealDuration],
|
|
97
102
|
);
|
|
98
103
|
|
|
99
104
|
const isEmpty = useDerivedValue(() => !isLoading.get() && !hasData.get());
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
type SharedValue,
|
|
8
8
|
} from "react-native-reanimated";
|
|
9
9
|
|
|
10
|
-
const MODE_BLEND_DURATION_MS = 300;
|
|
10
|
+
export const MODE_BLEND_DURATION_MS = 300;
|
|
11
11
|
|
|
12
12
|
export interface ModeBlendState {
|
|
13
13
|
/** 0 = fully line, 1 = fully candle */
|
|
@@ -28,17 +28,19 @@ export interface ModeBlendState {
|
|
|
28
28
|
export function useModeBlend(
|
|
29
29
|
isCandle: boolean,
|
|
30
30
|
lineOpacity: SharedValue<number>,
|
|
31
|
+
/** Crossfade duration (ms). Default {@link MODE_BLEND_DURATION_MS}; `0` snaps. */
|
|
32
|
+
duration: number = MODE_BLEND_DURATION_MS,
|
|
31
33
|
): ModeBlendState {
|
|
32
34
|
const modeBlend = useSharedValue(isCandle ? 1 : 0);
|
|
33
35
|
|
|
34
36
|
useEffect(() => {
|
|
35
37
|
modeBlend.set(
|
|
36
38
|
withTiming(isCandle ? 1 : 0, {
|
|
37
|
-
duration
|
|
39
|
+
duration,
|
|
38
40
|
easing: Easing.inOut(Easing.ease),
|
|
39
41
|
}),
|
|
40
42
|
);
|
|
41
|
-
}, [isCandle, modeBlend]);
|
|
43
|
+
}, [isCandle, modeBlend, duration]);
|
|
42
44
|
|
|
43
45
|
const lineGroupOpacity = useDerivedValue(
|
|
44
46
|
() => lineOpacity.get() * (1 - modeBlend.get()),
|
package/src/index.ts
CHANGED
|
@@ -64,6 +64,7 @@ export type {
|
|
|
64
64
|
LiveChartPoint,
|
|
65
65
|
LiveChartProps,
|
|
66
66
|
LiveChartSeriesProps,
|
|
67
|
+
LoadingConfig,
|
|
67
68
|
Marker,
|
|
68
69
|
MarkerClusterConfig,
|
|
69
70
|
MarkerGroupBadge,
|
|
@@ -97,6 +98,7 @@ export type {
|
|
|
97
98
|
ThresholdLineConfig,
|
|
98
99
|
TooltipRenderProps,
|
|
99
100
|
TradeEvent,
|
|
101
|
+
TransitionConfig,
|
|
100
102
|
ValueLineConfig,
|
|
101
103
|
VisibleRange,
|
|
102
104
|
VolumeConfig,
|
package/src/math/squiggly.ts
CHANGED
|
@@ -4,16 +4,26 @@ import type { ChartPadding } from "../draw/line";
|
|
|
4
4
|
* Composite sine squiggly — two overlapping frequencies with a breathing
|
|
5
5
|
* amplitude envelope. Matches the original web LiveChart loading animation.
|
|
6
6
|
*
|
|
7
|
-
* amplitude =
|
|
8
|
-
* y = centerY + amplitude * (sin(0.035*x + 1.2*t) + 0.45*sin(0.08*x + 2.1*t))
|
|
7
|
+
* amplitude = base * (0.4 + 0.6 * sin(0.8 * t·speed)) // 0.4×→1.0× base
|
|
8
|
+
* y = centerY + amplitude * (sin(0.035*x + 1.2*t·speed) + 0.45*sin(0.08*x + 2.1*t·speed))
|
|
9
|
+
*
|
|
10
|
+
* `base` (default `14`) scales the wave height; `speed` (default `1`) scales the
|
|
11
|
+
* time phase so the ripple/breathing runs faster or slower (`0` freezes it).
|
|
9
12
|
*/
|
|
10
|
-
export function squigglyYAt(
|
|
13
|
+
export function squigglyYAt(
|
|
14
|
+
x: number,
|
|
15
|
+
centerY: number,
|
|
16
|
+
t: number,
|
|
17
|
+
base = 14,
|
|
18
|
+
speed = 1,
|
|
19
|
+
): number {
|
|
11
20
|
"worklet";
|
|
12
|
-
const
|
|
21
|
+
const ts = t * speed;
|
|
22
|
+
const amplitude = base * (0.4 + 0.6 * Math.sin(0.8 * ts));
|
|
13
23
|
return (
|
|
14
24
|
centerY +
|
|
15
25
|
amplitude *
|
|
16
|
-
(Math.sin(0.035 * x + 1.2 *
|
|
26
|
+
(Math.sin(0.035 * x + 1.2 * ts) + 0.45 * Math.sin(0.08 * x + 2.1 * ts))
|
|
17
27
|
);
|
|
18
28
|
}
|
|
19
29
|
|
|
@@ -27,6 +37,8 @@ export function buildSquigglyPts(
|
|
|
27
37
|
canvasHeight: number,
|
|
28
38
|
padding: ChartPadding,
|
|
29
39
|
t: number,
|
|
40
|
+
base = 14,
|
|
41
|
+
speed = 1,
|
|
30
42
|
): number[] {
|
|
31
43
|
"worklet";
|
|
32
44
|
const leftEdge = padding.left;
|
|
@@ -41,7 +53,7 @@ export function buildSquigglyPts(
|
|
|
41
53
|
for (let i = 0; i < count; i++) {
|
|
42
54
|
const x = leftEdge + Math.min(i * step, chartW);
|
|
43
55
|
pts[i * 2] = x;
|
|
44
|
-
pts[i * 2 + 1] = squigglyYAt(x, centerY, t);
|
|
56
|
+
pts[i * 2 + 1] = squigglyYAt(x, centerY, t, base, speed);
|
|
45
57
|
}
|
|
46
58
|
return pts;
|
|
47
59
|
}
|
|
@@ -54,13 +66,15 @@ export function squigglifyPts(
|
|
|
54
66
|
flatPts: number[],
|
|
55
67
|
t: number,
|
|
56
68
|
centerY: number,
|
|
69
|
+
base = 14,
|
|
70
|
+
speed = 1,
|
|
57
71
|
): number[] {
|
|
58
72
|
"worklet";
|
|
59
73
|
const n = flatPts.length;
|
|
60
74
|
const out: number[] = new Array(n);
|
|
61
75
|
for (let i = 0; i < n; i += 2) {
|
|
62
76
|
out[i] = flatPts[i];
|
|
63
|
-
out[i + 1] = squigglyYAt(flatPts[i], centerY, t);
|
|
77
|
+
out[i + 1] = squigglyYAt(flatPts[i], centerY, t, base, speed);
|
|
64
78
|
}
|
|
65
79
|
return out;
|
|
66
80
|
}
|
package/src/types.ts
CHANGED
|
@@ -720,6 +720,23 @@ export interface ScrubConfig {
|
|
|
720
720
|
* Default `0`.
|
|
721
721
|
*/
|
|
722
722
|
panGestureDelay?: number;
|
|
723
|
+
/**
|
|
724
|
+
* Fade the annotation overlays — buy/sell **markers** and **reference lines**
|
|
725
|
+
* (both the built-in Skia tags/lines and any custom `renderMarker` /
|
|
726
|
+
* `renderReferenceLine` RN views) — out while scrubbing, so they don't clutter
|
|
727
|
+
* the crosshair read-out. Reverses on release.
|
|
728
|
+
*
|
|
729
|
+
* The fade is driven by the **scrub-active** state (not the crosshair's
|
|
730
|
+
* edge-proximity fade, which would resurface the overlays as the crosshair
|
|
731
|
+
* nears the live dot) and eased on the UI thread over `SCRUB_OVERLAY_FADE_MS`.
|
|
732
|
+
* It animates only a **group opacity** — the marker atlas and reference-line
|
|
733
|
+
* geometry are left intact (still one batched draw each), so it's far cheaper
|
|
734
|
+
* than emptying / rebuilding overlay data per scrub. The leading dot is
|
|
735
|
+
* governed separately by `selectionDot`.
|
|
736
|
+
*
|
|
737
|
+
* `false` / omitted keeps the overlays visible while scrubbing (default).
|
|
738
|
+
*/
|
|
739
|
+
hideOverlaysOnScrub?: boolean;
|
|
723
740
|
}
|
|
724
741
|
|
|
725
742
|
/**
|
|
@@ -1586,6 +1603,55 @@ export interface VisibleRange {
|
|
|
1586
1603
|
following: boolean;
|
|
1587
1604
|
}
|
|
1588
1605
|
|
|
1606
|
+
/**
|
|
1607
|
+
* Per-transition animation durations (ms). Passed as the object form of
|
|
1608
|
+
* {@link LiveChartCoreProps.transitions} to tune or disable the built-in
|
|
1609
|
+
* animations. Omit a field to keep its default; `0` makes that transition
|
|
1610
|
+
* instant (snap). Setting `transitions={false}` is shorthand for all `0`.
|
|
1611
|
+
*/
|
|
1612
|
+
export interface TransitionConfig {
|
|
1613
|
+
/**
|
|
1614
|
+
* Reveal / collapse transition — the grow-in when data first appears (and the
|
|
1615
|
+
* fade-out when it goes away or `loading` toggles). This is what plays on a
|
|
1616
|
+
* timeframe change and when a `line` chart's data appears (e.g. switching from
|
|
1617
|
+
* candle to line). Default `600`. `0` = instant.
|
|
1618
|
+
*/
|
|
1619
|
+
reveal?: number;
|
|
1620
|
+
/**
|
|
1621
|
+
* Candle ↔ line crossfade duration when `mode` changes. Single-series
|
|
1622
|
+
* `LiveChart` only (multi-series is always lines). Default `300`. `0` = instant.
|
|
1623
|
+
*/
|
|
1624
|
+
mode?: number;
|
|
1625
|
+
}
|
|
1626
|
+
|
|
1627
|
+
/**
|
|
1628
|
+
* Styling for the breathing-line loading shell (the {@link LiveChartCoreProps.loading}
|
|
1629
|
+
* state). Every field is optional — pass it as the object form of `loading` to
|
|
1630
|
+
* restyle the shell; omit a field to keep its default.
|
|
1631
|
+
*/
|
|
1632
|
+
export interface LoadingConfig {
|
|
1633
|
+
/**
|
|
1634
|
+
* Color of the loading squiggle **and** the skeleton Y-axis placeholders.
|
|
1635
|
+
* Default: the theme's `gridLine` color.
|
|
1636
|
+
*/
|
|
1637
|
+
color?: string;
|
|
1638
|
+
/**
|
|
1639
|
+
* Stroke width (px) of the loading squiggle. Default: the chart's line
|
|
1640
|
+
* `strokeWidth`.
|
|
1641
|
+
*/
|
|
1642
|
+
strokeWidth?: number;
|
|
1643
|
+
/**
|
|
1644
|
+
* Base wave amplitude (px) of the breathing squiggle — it breathes between
|
|
1645
|
+
* `0.4×` and `1.0×` this. Default `14`.
|
|
1646
|
+
*/
|
|
1647
|
+
amplitude?: number;
|
|
1648
|
+
/**
|
|
1649
|
+
* Multiplier on the breathing-wave animation cadence: `>1` ripples faster,
|
|
1650
|
+
* `<1` slower, `0` freezes it. Default `1`.
|
|
1651
|
+
*/
|
|
1652
|
+
speed?: number;
|
|
1653
|
+
}
|
|
1654
|
+
|
|
1589
1655
|
/** Props shared between `LiveChart` and `LiveChartSeries`. */
|
|
1590
1656
|
export interface LiveChartCoreProps {
|
|
1591
1657
|
/** Color scheme. Default `"dark"`. */
|
|
@@ -1602,11 +1668,27 @@ export interface LiveChartCoreProps {
|
|
|
1602
1668
|
timeWindow?: number;
|
|
1603
1669
|
/** Freeze chart scrolling. Resume catches up to real time. Default `false`. */
|
|
1604
1670
|
paused?: boolean;
|
|
1671
|
+
/**
|
|
1672
|
+
* Tune or disable the built-in transition animations. `true` / omitted keeps
|
|
1673
|
+
* the defaults; `false` makes them all instant (no grow-in on data
|
|
1674
|
+
* appear/timeframe change, no candle↔line crossfade); a {@link TransitionConfig}
|
|
1675
|
+
* sets per-transition durations in ms (`reveal`, `mode`), where `0` snaps that
|
|
1676
|
+
* one. Live value tracking is governed separately by `smoothing`; static-entry
|
|
1677
|
+
* suppression by `static`.
|
|
1678
|
+
*/
|
|
1679
|
+
transitions?: boolean | TransitionConfig;
|
|
1605
1680
|
/**
|
|
1606
1681
|
* Breathing-line loading shell. When this becomes `false`, the chart reveals
|
|
1607
1682
|
* only if there is data (≥2 line points or ≥2 committed candles).
|
|
1608
|
-
|
|
1609
|
-
|
|
1683
|
+
*
|
|
1684
|
+
* `true` shows the shell with the defaults; pass a {@link LoadingConfig} to
|
|
1685
|
+
* restyle it — `color` / `strokeWidth` for the squiggle + skeleton, `amplitude`
|
|
1686
|
+
* / `speed` for the breathing wave. `false` / omitted is "not loading". Toggle
|
|
1687
|
+
* between the config and `false` as data loads (e.g. `loading={isLoading && cfg}`).
|
|
1688
|
+
* The loading→live reveal duration is governed separately by
|
|
1689
|
+
* {@link TransitionConfig.reveal} (the `transitions` prop).
|
|
1690
|
+
*/
|
|
1691
|
+
loading?: boolean | LoadingConfig;
|
|
1610
1692
|
/**
|
|
1611
1693
|
* Value-lerp speed — how quickly the drawn value, time window, and Y-range chase
|
|
1612
1694
|
* their targets each frame (0 = frozen, 1 = instant). Equivalent to liveline's
|