Skip to main content
Experimental. viewport supports single-series LiveChart in line and candle modes. Its API may change. LiveChartSeries does not yet support it.
Give each pane its own ViewportConfig: two Reanimated shared values that the engine adopts as its scroll/zoom state. Updating them moves the chart on the UI thread, and the chart’s pan/pinch gestures write those same values. ViewportConfig extends ChartViewportControl (the shared-value pair) with optional behavior settings. Like the other chart features, pass an object to configure it or viewport={false} to disable external control; omitted also uses private state. There is no true shorthand because the two shared values are required. Configuration preserves those shared values by reference; their contents stay on the UI thread. A non-null end can be at or beyond the pane’s own live edge, which lets charts with different forming-candle boundaries share a view. The retained-history guard still applies: an end before the first point/bar falls back to live without clearing the shared value. Keep overlapping history in all panes.

Copy the leader’s drawn range

The app decides which pane leads. Keep separate pairs for leader and followers to avoid multiple charts writing the same state. Read the leader’s drawn range through renderOverlay, then copy it with useAnimatedReaction. This includes its window easing and avoids a React render per frame. Disable gestures on a follower while it is being driven.
Set windowSmoothing: false on a follower copying scale.window: that width is already drawn, so easing it again would make the follower trail a pinch or range change. The leader keeps normal smoothing. This flag affects only non-null window overrides; value/Y-range smoothing and the return to timeWindow after clearing the width keep their normal behavior. Separate engines may still publish on adjacent frames; this API does not promise an atomic render across canvases. For handoff, stop the old pane’s in-flight gesture/fling, switch the app’s leader selector, and reverse the copy direction. The new leader’s adopted pair already contains the prior view. Never leave both mirror directions active at once.

Defaults, reset, and sleep

Changing timeWindow, disabling timeScroll, or changing overscroll settings does not clear a supplied viewport. A non-null width overrides the new base window. An external end remains honored when scroll gestures are disabled. Gesture bounds still apply when the user actively pans or pinches that chart. ref.current?.resetZoom() nulls the supplied pair. The chart then returns to its configured width and live edge (a paused chart remains paused). In a sync group, reset the leader and let the mirror carry its drawn return into the followers. Clearing only a follower will be overwritten by its next leader update. autoSleep observes both supplied shared values, so a settled follower wakes when the leader moves. For idle testing, turn pulse off and freeze the data feed/clock; live scrolling or changing feeds can keep an engine awake.

Clock mapping belongs to the app

All times and widths use the chart’s time coordinate system. Panes using unix seconds can copy directly. If your app compresses session gaps into index time, map the visible edges into the follower’s coordinate system before writing its pair. The library does not infer market sessions or match bars between panes. If the mapping is nonlinear, convert both left and right edges and subtract to get the follower’s width.

Try the demo

The example app’s Synced charts screen uses one simulated instrument for 1m and 15m candles. Choose either leader, pan or pinch, switch leaders, and reset both. Turn off Immediate follower width to compare the extra easing. Freeze the feed and clock, wait for zero engine ticks, then move the leader to wake both panes. Changing the base window while zoomed demonstrates that the adopted width persists. Source: app/demo/synced-charts.tsx.

Switch leaders, pinch, change the base window, reset, then freeze the feed