Skip to main content
Experimental. timeScroll and zoom are prototypes — the gesture model and API may still change. Both work on LiveChart (line and candle) and LiveChartSeries (multi-series line).
By default the chart follows the live edge. Enable timeScroll to pan back through history: drag (or fling) to scroll the window into the past, and the chart stops auto-following until you return to the live edge, where live-following resumes. One-finger plot scrubbing is unchanged.
Live example: app/demo/time-scroll.tsx in the example app.
<LiveChart data={data} value={value} timeScroll />
Panning is clamped to the earliest retained point, so keep enough history in data (or candles) to scroll into — seed a few windows’ worth and keep your buffer longer than the visible window.

Gestures

timeScroll: true uses the default drag-to-scroll gesture. Pass a TimeScrollConfig to pick the activation:
<LiveChart data={data} value={value} timeScroll={{ gesture: "axisDrag" }} />
  • "holdToScrub" (default) — a one-finger drag anywhere scrolls the timeline; scrubbing moves to a press-and-hold (Rainbow-style). A quick drag scrolls; hold, then drag, to scrub.
  • "axisDrag" — only a drag that starts on the bottom x-axis strip (“grab the time ruler”) scrolls. The plot area stays free, so a one-finger drag there scrubs immediately.

Hold duration (scrubHoldMs)

In holdToScrub, scrubHoldMs sets how long to press before scrub engages (so a quicker drag scrolls instead). Higher = more deliberate scrub, fewer accidental scrubs while scrolling. Default 500.
<LiveChart
  data={data}
  value={value}
  scrub
  timeScroll={{ gesture: "holdToScrub", scrubHoldMs: 350 }}
/>

Pinch-to-zoom (zoom)

Enable zoom for two-finger pinch-to-zoom of the visible window. Pinch out to zoom in (a narrower window), pinch in to zoom out — anchored at the focal point between your fingers, so the time under your fingers stays put. It composes with timeScroll: zoom level and scroll position are independent, and you can pan a zoomed-in window. Pinch is two-finger, so it never competes with the one-finger pan / scrub.
<LiveChart data={data} value={value} timeScroll zoom />
Bounds default sensibly — you can zoom in to timeWindow / 8 and out to the full retained data span. Pass a ZoomConfig to set them explicitly:
<LiveChart data={data} value={value} zoom={{ minTimeWindow: 5, maxTimeWindow: 3600 }} />
The Y-range auto-fits the visible window as you zoom, and candle bars re-flow to the new width.

Paging callbacks (onVisibleRangeChange, onReachStart)

To lazily page in history as the user scrolls/zooms back, two callbacks report the visible window:
<LiveChart
  data={data}
  value={value}
  timeScroll
  zoom
  onVisibleRangeChange={({ startSec, endSec, following }) => {
    // throttled to ~1 Hz; `following` is true at the live edge
  }}
  onReachStart={() => {
    // fires once when the left edge nears the oldest data — fetch older history here
  }}
/>
  • onVisibleRangeChange fires (throttled to ~1 Hz) with the window’s startSec / endSec and whether the chart is following the live edge.
  • onReachStart is a one-shot edge trigger: it fires once when the left edge comes within one window-width of the earliest retained point, then re-arms after you move back out — the cue to load the next page of older data. When the fetched data extends data / candles further back, it can fire again as you keep scrolling.

Full-width plot while scrolled (yAxis.float)

A normal chart reserves a right gutter for the price axis, so candles stop short of the edge. Pair timeScroll with yAxis: { float: true } and the plot runs full-width under a floating price axis — but only while you’re scrolled back. At the live edge (the default state) the chart keeps its normal gutter so the latest candle and the badge don’t sit under the floating labels; as soon as you scroll back, the plot expands under the axis so panned-in candles aren’t cut off, and it reverts when you return to live.
<LiveChart
  data={data}
  value={value}
  mode="candle"
  candles={candles}
  liveCandle={liveCandle}
  timeScroll
  yAxis={{ float: true }}
  badge={{ followViewEdge: true }}
/>

Track the visible edge (badge.followViewEdge)

While scrolled back, the live-price indicators normally stay at the (off-screen, still-advancing) live value. Set badge.followViewEdge so the badge, value line, and live dot instead track the price at the visible window’s right edge — the last price you can see — and snap back to the live value when you return to the live edge.

Notes

  • Both charts. timeScroll and zoom are wired into LiveChart and LiveChartSeries. In multi-series, each series’ dot / value label tracks its value at the visible right edge while scrolled (the dot rides the end of each line, not the live price).
  • Coexists with scrubbing. Plot-area scrub (and the order ticket) work alongside time-scroll — the gestures are disambiguated by region (axisDrag) or press-hold (holdToScrub). Pinch-zoom is two-finger, so it stays out of the one-finger gestures’ way.
  • axisDrag in multi-series doesn’t yet exclude the bottom-band from scrub; holdToScrub (the default) is the recommended gesture for LiveChartSeries.
  • See the LiveChart reference and TimeScrollConfig / ZoomConfig for every field.