Skip to content

Infinite row model

For a huge flat source (millions to billions of rows) there is no tree to ship — the browser holds only a window of rows and requests the next block as you scroll. Sorting and filtering run in the engine over the whole dataset (get_rows_window) and only the requested slice comes back, so sort/filter stay correct and cheap no matter how big the source is. The frontend never orders or filters rows itself.

from dash import Input, Output, callback, no_update
from dash_tensor_grid import GridDataEngine, TensorGrid
engine = GridDataEngine(orders) # 1,000,000+ flat rows
N = orders.height
grid = TensorGrid(
id="grid",
column_defs=column_defs, # accessorKey / header / type / filterType per column
row_model="infinite", # window + block requests, not the full frame
row_count=N, # sizes the scrollbar
row_height=34,
)
# The grid emits `rows_request` as you scroll; the engine filters + sorts the WHOLE
# frame and returns just the requested [start_row, end_row) window.
@callback(
Output("grid", "rows_response"),
Output("grid", "row_count"),
Input("grid", "rows_request"),
prevent_initial_call=True,
)
def serve_block(req):
if not req:
return no_update, no_update
out = engine.get_rows_window(
req["start_row"], req["end_row"],
sort=req.get("sort"), filters=req.get("filters"),
)
resp = {"start_row": req["start_row"], "rows": out["rows"], "row_count": out["row_count"]}
return resp, out["row_count"]
  • The frontend does zero math. The engine filters and sorts the entire frame, then returns only the [start, end) window plus the filtered row_count (which sizes the scrollbar). Each returned row carries an absolute _index so getRowId stays stable across re-windows.
  • Server-mode facets. Because the client caches only a window, set/select value lists and range bounds can’t be derived client-side — supply them from the engine via column_facets (engine.facet_counts(col, filters=...)), faceted by the other active filters and recomputed only when the filter model changes, not on scroll. See examples/infinite_app.py.
  • Byte-identical. @tensorgrid/core’s getRowsWindow is a parity-verified port of the Polars get_rows_window (same nulls_last sort, same per-column filter semantics).
  • Reach for this only for a flat source. A large aggregated tree that fits in one payload uses virtualization; a tree too large to ship uses server / lazy mode.