Skip to main content
Live example: app/demo/overlay-bridge.tsx in the example app.

A custom React Native overlay glued to the auto-rescaling axis

When the built-in lines and badges aren’t enough — a draggable order book, an avg-entry / liquidation overlay with your own chrome — renderOverlay hands you the chart’s price↔pixel / time↔pixel scale so you can hand-roll an overlay in plain React Native that stays glued to the auto-rescaling axis. The callback receives a ChartOverlayContext. The returned tree mounts full-bleed over the canvas with pointerEvents="box-none", so empty areas still scrub. renderOverlay is available on both LiveChart and LiveChartSeries; the same context reports each chart’s resolved plot rectangle.

The easy path — usePriceY / useTimeX

Render one component per level and call usePriceY(ctx, price) — it returns a SharedValue<number> that tracks the rescaling axis for you. Read it in your useAnimatedStyle like any SharedValue; no need to think about subscriptions.
useTimeX(ctx, time) is the time→x sibling. Both are hooks, so call them once per element (one component per level / annotation).

The manual path — scale + the pure mappings

For one-off math (e.g. a gesture handler) or to keep everything in one worklet, read scale.get() yourself and feed the snapshot to the pure priceToY / yToPrice / timeToX / xToTime mappings:
On the manual path, reactivity comes from reading scale.get() inside the worklet — the mappings are pure and don’t read it for you. A style that only calls priceToY(price, …) without touching scale.get() won’t re-run and the overlay will freeze. (The usePriceY / useTimeX hooks handle this for you.)
These are the same projections the engine uses internally for the live dot, the scrub crosshair, and the order-ticket drag — so a custom overlay lines up pixel-for-pixel with the chart. On a multi-series chart, use s.plot.left / s.plot.right for a custom off-axis badge or connector: those values already account for the chart’s actual Y-axis gutter and any insets override.