Chapter 32 of 34
Live data without rebuilding the table
1,500 cell updates per second – only the changed, visible cells are redrawn.
After this chapter you can
- update single cells with updateCells()
- flash a cell with CSS classes
- keep permanent colours in the model
Many small changes
A ticker, a monitoring view, a trading screen: values change many times per second, but the rows stay the same. Rebuilding the table – or even repainting all visible cells – for every change would waste most of the frame.
updateCells: value + redraw of exactly these cells
import { ColumnDef, type ColumnDefIf, type TableApi, TableCellUpdateEvent, TableFactory, type TableModelIf, allRight, bodyLeft, px100, px120, px200} from "@guiexpert/table";
export interface Quote { symbol: string; name: string; price: number; change: number; volume: number }
const QUOTE_COLUMNS: ColumnDefIf[] = [ new ColumnDef("symbol", "Symbol", px100, bodyLeft), new ColumnDef("name", "Name", px200, bodyLeft), new ColumnDef("price", "Price", px120, allRight), // column 2 new ColumnDef("change", "Change %", px120, allRight), // column 3 new ColumnDef("volume", "Volume", px120, allRight) // column 4];
export function createQuoteModel(quotes: Quote[]): TableModelIf { return TableFactory.createTableModel({ rows: quotes, columnDefs: QUOTE_COLUMNS });}/** One tick: some quotes move – only their cells are updated. Returns the number of changed cells. */export function tick(api: TableApi, quotes: Quote[], moves: number): number { const events: TableCellUpdateEvent[] = []; for (let n = 0; n < moves; n++) { const row = Math.floor(Math.random() * quotes.length); const q = quotes[row]; const price = Math.max(1, Math.round(q.price * (1 + (Math.random() - 0.5) / 50) * 100) / 100); const change = Math.round((price - q.price) / q.price * 10000) / 100; const volume = q.volume + Math.floor(Math.random() * 500); const up = change >= 0; events.push( new TableCellUpdateEvent("body", row, 2, price, { "tick-up": up, "tick-down": !up }), new TableCellUpdateEvent("body", row, 3, change, { "tick-up": up, "tick-down": !up }), new TableCellUpdateEvent("body", row, 4, volume)); } api.updateCells(events); // writes the values into the model, redraws only these cells return events.length;}let cells = 0;let timer = window.setInterval(() => cells += tick(api, quotes, 50), 100); // 50 quotes every 100 ms- A
TableCellUpdateEvent= area, row, column, new value, and optionally CSS classes for this cell. TableApi.updateCells()writes the values into the model and redraws only the affected cells – if they are visible. Cells off screen just get the value and are drawn when you scroll there.updateCells(events, true)repaints the whole table instead.
Where the data comes from
WebSocket, Server-Sent Events, polling – collect the changes and call updateCells once per animation frame or
interval, not once per message. The showcase Crypto does that with real price data.
Next
A table that remembers sorting and scroll position: chapter 33 (Persist state).