Real-Time Data
ChartGPU is designed for live streaming. The recommended API is connectStream, which handles append-vs-update logic automatically.
connectStream
Pass a WebSocket or any AsyncIterable<Candle>. The chart decides whether to append or update based on the incoming timestamp:
- Same timestamp as last candle → updates in place (tick update while candle is forming)
- Newer timestamp → appends as a new candle
- Older timestamp → ignored
// WebSocket
const ws = new WebSocket('wss://feed.example.com/candles');
const disconnect = chart.connectStream(ws);
// Async iterable (custom generator, EventSource wrapper, etc.)
const disconnect2 = chart.connectStream(myAsyncGenerator());
// Stop streaming
disconnect();
// or: chart.disconnectStream();chart.destroy() calls disconnectStream automatically.
WebSocket Example (Binance)
Binance kline stream sends JSON where the candle fields are nested under k. Wrap the WebSocket with a transform to map to the Candle shape:
async function* binanceStream(symbol: string, tf: string): AsyncGenerator<Candle> {
const ws = new WebSocket(`wss://stream.binance.com:9443/ws/${symbol}@kline_${tf}`);
for await (const event of wsMessages(ws)) {
const { k } = JSON.parse(event.data);
yield {
open: parseFloat(k.o),
high: parseFloat(k.h),
low: parseFloat(k.l),
close: parseFloat(k.c),
timestamp: k.t,
volume: parseFloat(k.v),
};
}
}
chart.connectStream(binanceStream('btcusdt', '1m'));appendCandle
For manual control without connectStream:
chart.appendCandle({
open: 103.5,
high: 105.2,
low: 102.8,
close: 104.1,
timestamp: Date.now(),
volume: 85000,
});If the viewport is at the trailing edge, the chart advances automatically to keep the latest candle in view.
Updating the Last Candle
For manual tick-level updates:
const candles = chart.getCandles();
candles[candles.length - 1] = updatedCandle;
chart.setCandles(candles);connectStream handles this automatically — prefer it over manual updates.
Timeframe Switching
When the user changes the timeframe, fetch new candle data and reset:
chart.setTimeframe('5m');
chart.setCandles(await fetchCandles('5m'));setTimeframe fires the timeframeChange event which you can subscribe to:
chart.on('timeframeChange', (tf) => {
console.log('New timeframe:', tf);
});Events
chart.on('viewportChange', (viewport) => {
// viewport.start, viewport.end changed (pan/zoom)
});
chart.on('timeframeChange', (tf) => {
// User switched timeframe
});