SharedValues.
This is similar to a TradingView-style getBars / subscribeBars datafeed, but the adapter belongs
to your application. LiveChart stays compatible with fetch, TanStack Query, Apollo, generated
SDKs, NATS, or any other transport.
Runnable example:
app/demo/loading-data-on-scroll.tsx
uses a simulated paginated API and live subscription. Pan left repeatedly to watch pages prepend.The two demand callbacks
onVisibleRangeChangereports{ startSec, endSec, following }about once per second. Store the latest range so the loader knows how much time the next request must cover.onReachStartfires once when the visible left edge comes within one window-width of the oldest retained row. It re-arms after the retained edge moves far enough into the past.
1. Define an optional app-level adapter
An interface can make several chart screens consistent without making networking part of LiveChart itself:fetch + WebSocket implementation of that interface. Adapt the response fields
at this boundary so every chart row is already numeric and uses unix seconds:
2. Normalize, sort, and deduplicate pages
LiveChart expects timestamps in unix seconds and rows in ascending order. Page boundaries and a simultaneous live update can overlap, so deduplicate by timestamp every time a page is merged..set(mergedRows) for a fetched page is appropriate: page loads are infrequent and replacing
the array publishes one coherent snapshot. Use .modify(...) for high-frequency live appends so
the growing array is not cloned across the JS/UI boundary every tick.
3. Fetch the initial window and older pages
The loader below provides the important production guards:- one history drain at a time;
- abort and reset when the symbol or resolution changes;
- follow cursors through sparse pages until the requested time is covered;
- publish each successful page immediately, so a later failed page does not discard progress;
- stop when the server is exhausted or the client retention cap prevents the oldest edge moving.
onReachStart will not spin retries—it
is deliberately edge-triggered. Show a retry affordance that calls loadOlderHistory() again, or
retry through your query client with its normal backoff policy.
4. Subscribe to live line updates
Subscribe after the initial request starts and unsubscribe when the chart identity changes. Replace an update at the same timestamp; append a newer update; ignore older out-of-order ticks and let the next REST page reconcile them.The websocket does not need to be owned by the screen. A shared SDK or connection manager can
multiplex one socket across charts; the screen only needs a scoped subscribe/unsubscribe method.
Candlestick bars: committed history plus one live bar
For candlesticks, pass closed buckets throughcandles and the currently forming bucket through
liveCandle. Do not put the same bucket in both arrays.
mergeByTime helper before calling candles.set(...). On a
bucket rollover, either receive an explicit closed update as above or commit the previous
liveCandle before installing the new open bucket.
Using an infinite-query cache
If your SDK already exposes an infinite query, let it own request deduplication, retry, and cache lifetime. Flatten pages into chronological order and publish them when the cache changes:Production checklist
- Send and store timestamps in unix seconds; convert millisecond APIs at the boundary.
- Keep committed rows ascending by time and deduplicate page overlaps.
- Scope cursors and cache keys by symbol, resolution, metric, and chart mode.
- Seed about two visible windows, then fetch one additional window per scroll demand.
- Guard against overlapping requests and abort stale chart identities.
- Let retries happen through an explicit demand or visible retry control—not a render loop.
- Set a retention cap and stop backfilling when that cap prevents the oldest edge from moving.
- Keep closed candles separate from the single in-progress
liveCandle. - Unsubscribe realtime listeners on unmount or identity change.
- Log page failures, cursor stalls, and retention-cap stops with the chart identity attached.
LiveChart API reference for the callback contracts.