react-native-livechart 4.11.0 → 4.12.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.
Files changed (67) hide show
  1. package/dist/components/CrosshairLine.d.ts +3 -1
  2. package/dist/components/CrosshairLine.d.ts.map +1 -1
  3. package/dist/components/CustomReferenceLineOverlay.d.ts +15 -10
  4. package/dist/components/CustomReferenceLineOverlay.d.ts.map +1 -1
  5. package/dist/components/DotOverlay.d.ts +3 -5
  6. package/dist/components/DotOverlay.d.ts.map +1 -1
  7. package/dist/components/LiveChart.d.ts.map +1 -1
  8. package/dist/components/LiveChartSeries.d.ts.map +1 -1
  9. package/dist/components/PerSeriesTooltipOverlay.d.ts +19 -0
  10. package/dist/components/PerSeriesTooltipOverlay.d.ts.map +1 -0
  11. package/dist/components/ReferenceLineOverlay.d.ts +20 -6
  12. package/dist/components/ReferenceLineOverlay.d.ts.map +1 -1
  13. package/dist/components/YAxisOverlay.d.ts +3 -1
  14. package/dist/components/YAxisOverlay.d.ts.map +1 -1
  15. package/dist/core/liveIndicatorVisibility.d.ts +9 -0
  16. package/dist/core/liveIndicatorVisibility.d.ts.map +1 -0
  17. package/dist/core/resolveConfig.d.ts +29 -0
  18. package/dist/core/resolveConfig.d.ts.map +1 -1
  19. package/dist/hooks/crosshairSeries.d.ts +10 -2
  20. package/dist/hooks/crosshairSeries.d.ts.map +1 -1
  21. package/dist/hooks/crosshairShared.d.ts +33 -2
  22. package/dist/hooks/crosshairShared.d.ts.map +1 -1
  23. package/dist/hooks/delayedPanGuard.d.ts +66 -8
  24. package/dist/hooks/delayedPanGuard.d.ts.map +1 -1
  25. package/dist/hooks/useChartPaths.d.ts +5 -9
  26. package/dist/hooks/useChartPaths.d.ts.map +1 -1
  27. package/dist/hooks/useCrosshair.d.ts +7 -1
  28. package/dist/hooks/useCrosshair.d.ts.map +1 -1
  29. package/dist/hooks/useCrosshairSeries.d.ts +22 -3
  30. package/dist/hooks/useCrosshairSeries.d.ts.map +1 -1
  31. package/dist/hooks/useMomentum.d.ts +1 -1
  32. package/dist/hooks/useMomentum.d.ts.map +1 -1
  33. package/dist/hooks/usePanScroll.d.ts +15 -1
  34. package/dist/hooks/usePanScroll.d.ts.map +1 -1
  35. package/dist/index.d.ts +1 -1
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/math/lerp.d.ts.map +1 -1
  38. package/dist/math/momentum.d.ts +1 -1
  39. package/dist/math/momentum.d.ts.map +1 -1
  40. package/dist/math/referenceLines.d.ts +7 -0
  41. package/dist/math/referenceLines.d.ts.map +1 -1
  42. package/dist/types.d.ts +160 -18
  43. package/dist/types.d.ts.map +1 -1
  44. package/package.json +1 -1
  45. package/src/components/CrosshairLine.tsx +4 -1
  46. package/src/components/CustomReferenceLineOverlay.tsx +42 -13
  47. package/src/components/DotOverlay.tsx +24 -8
  48. package/src/components/LiveChart.tsx +157 -37
  49. package/src/components/LiveChartSeries.tsx +128 -16
  50. package/src/components/PerSeriesTooltipOverlay.tsx +287 -0
  51. package/src/components/ReferenceLineOverlay.tsx +274 -141
  52. package/src/components/YAxisOverlay.tsx +5 -1
  53. package/src/core/liveIndicatorVisibility.ts +25 -0
  54. package/src/core/resolveConfig.ts +86 -0
  55. package/src/hooks/crosshairSeries.ts +262 -33
  56. package/src/hooks/crosshairShared.ts +36 -2
  57. package/src/hooks/delayedPanGuard.ts +111 -6
  58. package/src/hooks/useChartPaths.ts +25 -15
  59. package/src/hooks/useCrosshair.ts +57 -4
  60. package/src/hooks/useCrosshairSeries.ts +95 -7
  61. package/src/hooks/useMomentum.ts +8 -1
  62. package/src/hooks/usePanScroll.ts +46 -5
  63. package/src/index.ts +1 -0
  64. package/src/math/lerp.ts +7 -0
  65. package/src/math/momentum.ts +22 -5
  66. package/src/math/referenceLines.ts +38 -0
  67. package/src/types.ts +168 -18
package/src/types.ts CHANGED
@@ -63,6 +63,11 @@ export type BadgeVariant = "default" | "minimal";
63
63
  * - **Form C** — vertical time band between `from` and `to` (unix seconds).
64
64
  */
65
65
  export interface ReferenceLine {
66
+ /**
67
+ * Stable identifier for this line. Supply a unique value when `referenceLines`
68
+ * may be reordered so the chart preserves the line's rendered identity.
69
+ */
70
+ id?: string;
66
71
  /** Form A — the Y-axis value where the horizontal line is drawn. */
67
72
  value?: number;
68
73
  /** Form B — horizontal band lower Y bound (paired with `valueTo`). */
@@ -254,14 +259,16 @@ export interface ReferenceLineBadgeConfig extends BadgeStyleConfig {
254
259
 
255
260
  /**
256
261
  * Context passed to a custom {@link LiveChartProps.renderReferenceLine} or
257
- * {@link LiveChartSeriesProps.renderReferenceLine}. The chart floats the element
258
- * you return over the canvas and pins it to the line's value on
259
- * the UI thread (vertically centered on the line, horizontally at the badge /
260
- * label position) — so it tracks the rescaling axis and any drag smoothly without
261
- * JS re-renders, just like {@link TooltipRenderProps}. Replaces the built-in pill
262
- * badge / gutter label for that line; return `null`/`undefined` to keep the
263
- * built-in. Bind the SharedValues to animated text (e.g. an animated `TextInput`)
264
- * for the value to update on the UI thread too.
262
+ * {@link LiveChartProps.renderOffAxisReferenceLine} (and their
263
+ * `LiveChartSeries` counterparts). The chart floats the element you return over
264
+ * the canvas and pins it to the line's value on the UI thread (vertically centered
265
+ * on the line, horizontally at the badge / label position) — so it tracks the
266
+ * rescaling axis and any drag smoothly without JS re-renders, just like
267
+ * {@link TooltipRenderProps}. `renderReferenceLine` replaces the built-in pill /
268
+ * gutter label in every state; `renderOffAxisReferenceLine` replaces it only while
269
+ * the value is pinned above or below the visible plot. Bind the SharedValues to
270
+ * animated text (e.g. an animated `TextInput`) for the value to update on the UI
271
+ * thread too.
265
272
  */
266
273
  export interface ReferenceLineRenderProps {
267
274
  /** The reference line being rendered. */
@@ -592,7 +599,9 @@ export interface BadgeConfig extends BadgeStyleConfig {
592
599
  * When the chart is scrolled back (see `timeScroll`), move the live-price
593
600
  * indicators — the badge, the value line, and the live dot — to the price at
594
601
  * the visible window's right edge instead of the live price, so they track the
595
- * last visible price as you pan. Default `false`.
602
+ * last visible price as you pan. The badge's momentum color is derived at that
603
+ * same historical edge, so incoming live ticks do not recolor it. Default
604
+ * `false`.
596
605
  *
597
606
  * @experimental
598
607
  */
@@ -716,10 +725,102 @@ export interface XAxisConfig {
716
725
  minGap?: number;
717
726
  }
718
727
 
728
+ /**
729
+ * Morfi-style on-canvas tooltip for {@link LiveChartSeries}: a time-range pill
730
+ * above the guide plus one value pill at every visible series intersection.
731
+ *
732
+ * Enable it with `scrub={{ seriesTooltip: true }}` or pass this object to style
733
+ * and format the readout. It is ignored by the single-series {@link LiveChart}.
734
+ */
735
+ export interface PerSeriesTooltipConfig {
736
+ /**
737
+ * Keep the value pills pinned to the visible series endpoints while idle.
738
+ * The guide and time pill remain hidden until a scrub starts. Default `false`.
739
+ */
740
+ alwaysShow?: boolean;
741
+ /**
742
+ * Bucket width used by the time-range pill, in seconds. Omit to infer it from
743
+ * the latest positive interval in the first visible series.
744
+ */
745
+ bucketSeconds?: number;
746
+ /**
747
+ * Format a value pill. The second argument identifies the series so one chart
748
+ * can dispatch to different unit formatters. Defaults to the chart's
749
+ * `formatValue`.
750
+ *
751
+ * Runs on the UI thread and must be worklet-safe.
752
+ */
753
+ formatSeriesValue?: (value: number, seriesId: string) => string;
754
+ /**
755
+ * Format the time pill from the bucket's start/end unix seconds. The end is
756
+ * clamped to the chart's current-time anchor, so the live bucket never claims
757
+ * to end in the future. Defaults to two chart `formatTime` labels joined by
758
+ * an en dash.
759
+ *
760
+ * Runs on the UI thread and must be worklet-safe.
761
+ */
762
+ formatTimeRange?: (from: number, to: number) => string;
763
+ /** Truncate labels longer than this many characters with `…`. Default `14`. */
764
+ maxLabelChars?: number;
765
+
766
+ /** Guide color. Omit to use `scrub.crosshairLineColor`, then the theme. */
767
+ guideColor?: string;
768
+ /** Guide stroke width in px. Default `1`. */
769
+ guideWidth?: number;
770
+ /**
771
+ * Guide dash pattern. `true` uses `[3, 3]`; an array supplies explicit Skia
772
+ * dash intervals; `false` draws a solid guide. Default `[3, 3]`.
773
+ */
774
+ guideDashPattern?: boolean | number[];
775
+
776
+ /** Time-pill background. Omit to use `scrub.tooltipBackground`, then the theme. */
777
+ timePillBackground?: string;
778
+ /** Time-pill text color. Omit to use `scrub.tooltipColor`, then the theme. */
779
+ timePillColor?: string;
780
+ /** Time-pill border color. Omit to use `scrub.tooltipBorderColor`, then the theme. */
781
+ timePillBorderColor?: string;
782
+ /** Time-pill corner radius in px. Default `6`. */
783
+ timePillRadius?: number;
784
+ /** Time-pill horizontal padding in px. Default `8`. */
785
+ timePillPaddingX?: number;
786
+ /** Time-pill vertical padding in px. Default `4`. */
787
+ timePillPaddingY?: number;
788
+
789
+ /** Series-pill background. Omit to use `scrub.tooltipBackground`, then the theme. */
790
+ seriesPillBackground?: string;
791
+ /** Series label color. Omit to use the theme tooltip text. */
792
+ seriesPillLabelColor?: string;
793
+ /** Formatted series value color. Omit to use `seriesPillLabelColor`. */
794
+ seriesPillValueColor?: string;
795
+ /** Series-pill border color. Omit to use `scrub.tooltipBorderColor`, then the theme. */
796
+ seriesPillBorderColor?: string;
797
+ /** Series-pill corner radius in px. Default `6`. */
798
+ seriesPillRadius?: number;
799
+ /** Series-pill horizontal padding in px. Default `8`. */
800
+ seriesPillPaddingX?: number;
801
+ /** Series-pill vertical padding in px. Default `4`. */
802
+ seriesPillPaddingY?: number;
803
+ /** Diameter of the series-colour dot inside each pill, in px. Default `8`. */
804
+ seriesPillDotSize?: number;
805
+ /** Gap between the colour dot and label, in px. Default `6`. */
806
+ seriesPillDotGap?: number;
807
+ /** Gap between the label and formatted value, in px. Default `6`. */
808
+ seriesPillLabelValueGap?: number;
809
+ /** Diameter of the dot drawn at each line/guide intersection. Default `8`. */
810
+ intersectionDotSize?: number;
811
+ }
812
+
719
813
  /** Crosshair scrub configuration. */
720
814
  export interface ScrubConfig {
721
815
  /** Show the value/time tooltip pill while scrubbing. Default `true`. */
722
816
  tooltip?: boolean;
817
+ /**
818
+ * Opt into the Morfi-style per-series pill tooltip on `LiveChartSeries`.
819
+ * `true` uses defaults; an object enables and configures it; `false`/omitted
820
+ * preserves the existing guide-only multi-series scrub. Ignored by
821
+ * single-series `LiveChart`. Default `false`.
822
+ */
823
+ seriesTooltip?: boolean | PerSeriesTooltipConfig;
723
824
  /**
724
825
  * Opacity of the chart content to the *right* of the crosshair (the "future")
725
826
  * while scrubbing — `0` fully fades it out, `1` disables the dim. Implemented
@@ -965,7 +1066,8 @@ export interface ChartScale {
965
1066
 
966
1067
  /**
967
1068
  * The price↔pixel / time↔pixel bridge handed to a custom
968
- * {@link LiveChartProps.renderOverlay}.
1069
+ * {@link LiveChartProps.renderOverlay} or
1070
+ * {@link LiveChartSeriesProps.renderOverlay}.
969
1071
  *
970
1072
  * **Easiest path — the `usePriceY` / `useTimeX` hooks.** They project a price / time
971
1073
  * to a `SharedValue<number>` that tracks the live axis for you; just read it in
@@ -1620,6 +1722,15 @@ export interface TimeScrollConfig {
1620
1722
  * if set, otherwise `500`.
1621
1723
  */
1622
1724
  scrubHoldMs?: number;
1725
+ /**
1726
+ * Hide the live badge, dot, and dashed value line while scrolled back through
1727
+ * history. Default `true`: all three mark the LIVE price, which is off-screen
1728
+ * once the window is frozen behind the live edge, so they'd point at a price
1729
+ * that isn't in view. Set `false` to keep them visible while scrolled back.
1730
+ * Ignored when `badge.followViewEdge` is on — there the group tracks the
1731
+ * visible edge price, which IS in view.
1732
+ */
1733
+ hideLiveOnScrollBack?: boolean;
1623
1734
  }
1624
1735
 
1625
1736
  /**
@@ -2008,8 +2119,9 @@ export interface LiveChartCoreProps {
2008
2119
  *
2009
2120
  * Defaults differ per chart: `LiveChart` shows it (`true`); `LiveChartSeries`
2010
2121
  * hides it (`false`) — with multiple lines the dot can only track the leading
2011
- * series, so the crosshair + per-series tooltips mark the scrub point instead.
2012
- * Pass `true` / a config to opt a multi-series chart in.
2122
+ * series. The crosshair and, when enabled, the per-series tooltip's own
2123
+ * intersection dots — mark the scrub point instead. Pass `true` / a config to
2124
+ * opt a multi-series chart in.
2013
2125
  */
2014
2126
  selectionDot?: boolean | SelectionDotConfig;
2015
2127
  /** Called once when the user starts scrubbing/panning the chart. */
@@ -2161,19 +2273,36 @@ export interface LiveChartProps extends LiveChartCoreProps {
2161
2273
  * pins it to the line's value on the UI thread (see {@link ReferenceLineRenderProps}),
2162
2274
  * so it tracks the rescaling axis and any drag without JS re-renders. Called per
2163
2275
  * Form-A line; return `null`/`undefined` to keep that line's built-in tag. Works
2164
- * with `badge: false` too (replace the plain gutter label). Single-series only.
2276
+ * with `badge: false` too (replace the plain gutter label). For a left- or
2277
+ * right-pinned `badge`, the chart retains the dashed connector and measures the
2278
+ * custom tag so the connector starts at its outer edge. Single-series only.
2165
2279
  */
2166
2280
  renderReferenceLine?: (
2167
2281
  ctx: ReferenceLineRenderProps,
2168
2282
  ) => ReactElement | null | undefined;
2283
+ /**
2284
+ * Render only a Form-A line's **off-axis** tag as a custom React Native element.
2285
+ * The chart keeps the standard Skia tag / gutter label while the value is in
2286
+ * range, then switches to this element when it pins above or below the plot.
2287
+ * With a left- or right-pinned `badge` (or legacy `offAxisBadge`), its dashed
2288
+ * connector stays native and begins after the measured custom tag. Return
2289
+ * `null`/`undefined` to opt a line out based on its static `line` / `index`;
2290
+ * use the `edge` SharedValue inside the returned element to animate a caret.
2291
+ * `renderReferenceLine` takes precedence if both callbacks handle one line.
2292
+ * Single-series only.
2293
+ */
2294
+ renderOffAxisReferenceLine?: (
2295
+ ctx: ReferenceLineRenderProps,
2296
+ ) => ReactElement | null | undefined;
2169
2297
  /**
2170
2298
  * Collapse Form-A reference lines whose handles sit near the same value into a
2171
2299
  * single count handle (e.g. a stack of working orders at adjacent prices reads
2172
2300
  * as one "×3" tag). `true` = defaults, `false`/omitted = off, or pass a
2173
2301
  * {@link ReferenceLineGroupingConfig} to tune the proximity radius. Lines a
2174
- * {@link LiveChartProps.renderReferenceLine} owns are excluded (their custom tag
2175
- * draws itself), so the count reflects only collapsed built-in tags. Single-series
2176
- * only. Default off.
2302
+ * {@link LiveChartProps.renderReferenceLine} or
2303
+ * {@link LiveChartProps.renderOffAxisReferenceLine} owns are excluded (their
2304
+ * custom tag draws itself), so the count reflects only collapsed built-in tags.
2305
+ * Single-series only. Default off.
2177
2306
  */
2178
2307
  referenceLineGrouping?: boolean | ReferenceLineGroupingConfig;
2179
2308
  /**
@@ -2195,18 +2324,39 @@ export interface LiveChartProps extends LiveChartCoreProps {
2195
2324
  export interface LiveChartSeriesProps extends LiveChartCoreProps {
2196
2325
  /** Array of series definitions. Must be a SharedValue for UI-thread reads. */
2197
2326
  series: SharedValue<SeriesConfig[]>;
2327
+ /**
2328
+ * Render a custom overlay floated over the canvas, handed the live
2329
+ * price↔pixel / time↔pixel {@link ChartOverlayContext}. Use its `scale` snapshot
2330
+ * and mapping worklets to position React Native UI against this chart's resolved
2331
+ * plot bounds (including any axis or explicit inset). The tree mounts full-bleed
2332
+ * with `pointerEvents="box-none"`; return `null`/`undefined` for no overlay.
2333
+ */
2334
+ renderOverlay?: (ctx: ChartOverlayContext) => ReactElement | null | undefined;
2198
2335
  /**
2199
2336
  * Render a Form-A reference line's tag as a custom **React Native** element
2200
2337
  * instead of the built-in Skia pill / gutter label. The chart pins the returned
2201
2338
  * element to the line's live Y position on the UI thread (see
2202
2339
  * {@link ReferenceLineRenderProps}), including off-axis edge pinning. Return
2203
2340
  * `null`/`undefined` to keep that line's built-in tag. The line stroke always
2204
- * remains visible, and `badge.position` / `labelPosition` controls the custom
2205
- * tag's left, center, or right anchor.
2341
+ * remains visible; a left- or right-pinned badge also keeps its dashed connector,
2342
+ * starting after the measured custom tag. `badge.position` / `labelPosition`
2343
+ * controls the custom tag's left, center, or right anchor.
2206
2344
  */
2207
2345
  renderReferenceLine?: (
2208
2346
  ctx: ReferenceLineRenderProps,
2209
2347
  ) => ReactElement | null | undefined;
2348
+ /**
2349
+ * Render only a Form-A line's **off-axis** tag as a custom React Native element.
2350
+ * The normal in-range Skia tag / gutter label stays visible, while an edge-pinned
2351
+ * custom tag replaces it above or below the plot. A left- or right-pinned
2352
+ * `badge` (or legacy `offAxisBadge`) retains its native dashed connector, measured
2353
+ * against the custom tag. Return `null`/`undefined` to opt a static `line` /
2354
+ * `index` out; use the `edge` SharedValue inside the returned element to animate
2355
+ * its caret. `renderReferenceLine` takes precedence for the same line.
2356
+ */
2357
+ renderOffAxisReferenceLine?: (
2358
+ ctx: ReferenceLineRenderProps,
2359
+ ) => ReactElement | null | undefined;
2210
2360
  /** Called when a series toggle chip is tapped. */
2211
2361
  onSeriesToggle?: (id: string, visible: boolean) => void;
2212
2362
  /**