DataView
DataView
Section titled “DataView”DataView provides a mapping layer between logical (visible) row indices and physical (CellStore) row indices. When sorting or filtering is active, logical row 0 may map to physical row 500. When no sort/filter is active, DataView operates as a zero-overhead passthrough.
Architecture
Section titled “Architecture”Logical rows (what user sees) ↕ DataView mappingPhysical rows (CellStore storage)All engine subsystems (selection, editing, rendering) work with logical indices. CellStore operations use physical indices. DataView translates between the two.
import { DataView } from '@witqq/spreadsheet';
const view = new DataView({ totalRowCount: 10000 });DataViewConfig
Section titled “DataViewConfig”interface DataViewConfig { totalRowCount: number;}getPhysicalRow(logicalRow)
Section titled “getPhysicalRow(logicalRow)”Convert a logical (visible) row index to its physical (CellStore) row index:
const physRow = view.getPhysicalRow(0); // First visible row → actual storage rowReturns -1 if the logical row has no mapping (out of range).
getLogicalRow(physicalRow)
Section titled “getLogicalRow(physicalRow)”Convert a physical row index back to logical. Returns undefined if the row is hidden (filtered out):
const logRow = view.getLogicalRow(500);if (logRow === undefined) { console.log('Row 500 is filtered out');}visibleRowCount
Section titled “visibleRowCount”Number of visible rows after filtering:
console.log(view.visibleRowCount); // e.g., 7500 (after filter)totalRowCount
Section titled “totalRowCount”Total physical rows (before filtering):
console.log(view.totalRowCount); // e.g., 10000isPassthrough()
Section titled “isPassthrough()”True when logical === physical (no sort/filter active). In passthrough mode, getPhysicalRow returns the input directly with zero overhead:
if (view.isPassthrough()) { console.log('No sort/filter — direct mapping');}recompute(physicalIndices)
Section titled “recompute(physicalIndices)”Set a new mapping. physicalIndices[logicalRow] = physicalRow. Called by SortEngine and FilterEngine after sorting/filtering:
// After sorting: logical row 0 = physical row 42, etc.view.recompute([42, 15, 88, 3, 201, ...]);console.log(view.visibleRowCount); // length of indices arrayAlso builds a reverse mapping (Map<physical, logical>) for getLogicalRow().
reset()
Section titled “reset()”Reset to passthrough (identity mapping):
view.reset();console.log(view.isPassthrough()); // trueconsole.log(view.visibleRowCount === view.totalRowCount); // truesetTotalRowCount(count)
Section titled “setTotalRowCount(count)”Update total row count when rows are added or removed. In passthrough mode, this also updates visibleRowCount:
view.setTotalRowCount(15000); // e.g., after pushRowsIntegration with Sort/Filter Pipeline
Section titled “Integration with Sort/Filter Pipeline”The sort/filter pipeline uses DataView as the output layer:
FilterEngine.apply() → produces filtered physical indices → SortEngine.sort() → reorders filtered indices → DataView.recompute(finalIndices)When both are cleared:
DataView.reset() → passthrough modeIntegration with StreamingAdapter
Section titled “Integration with StreamingAdapter”StreamingAdapter.updateRow() and StreamingAdapter.deleteRow() use DataView.getPhysicalRow() internally. This ensures that operations on logical indices (what the user sees) correctly target the right physical rows, even when sort/filter is active.
See Also
Section titled “See Also”- Sorting — multi-column sort via DataView
- Filtering — 14 filter operators via DataView
- Streaming Data — live row updates with DataView integration