@syncfusion/ej2-spreadsheet
Version:
Feature-rich JavaScript Spreadsheet (Excel) control with built-in support for selection, editing, formatting, importing and exporting to Excel
72 lines (65 loc) • 6.39 kB
Markdown
# Sheet Module data flow
## What It Does
- Summary: Provides the sheet data model (rows, columns, ranges, usedRange, pane/freeze info, protection) and renders sheet UI panels (row headers, column headers, content table, frozen panes). Handles initialization, virtualization-aware rendering, header/scroll layout, merge handling, and responsive updates to row/column size changes. See `src/workbook/base/sheet.ts` and `src/spreadsheet/renderer/sheet.ts`.
## Entry Points (UI / Core)
- UI (Renderer):
- `SheetRender.renderPanel()` — build DOM panels (`.e-main-panel`, `.e-row-header`, `.e-column-header`, `.e-sheet-content`).
- `SheetRender.renderTable(args)` — full table render for given viewport/cells; delegates per-cell work to `cellRenderer` and `rowRenderer`.
- `refreshRowContent`, `refreshColumnContent`, `updateRowContent`, `updateColContent` — incremental refresh APIs used by scrolling / virtualization / edits.
- `setPanelWidth`, `setPanelHeight`, `updateLeftColGroup`, `setHeaderPanelWidth` — layout helpers for frozen panes, scrollbars, and header sizing.
- Event listeners: registers `created`, `rowHeightChanged`, `colWidthChanged`, `spreadsheetDestroyed`.
- Core (Model / Utilities):
- `initSheet(context, sheet?, isImport?, isRefresh?)` — normalizes sheet properties, initializes rows/columns, pane top-left cell.
- `initRow(sheet, rows, isImport?, isRefresh?)` — processes row/cell indexes, comments, notes via `processComments` / `processNotes` and `processIdx`.
- Accessors: `getSheet`, `getSheetIndex`, `getSheetName`, `getSheetIndexFromId`, `getSheetNameFromAddress`, `getSheetIndexByName`.
- Helpers: `updateSelectedRange`, `getSelectedRange`, `getMaxSheetId`, `moveSheet`, `duplicateSheet`, `getNextPrevVisibleSheetIndex`.
## Core Logic Flow (ASCII)
Data / JSON import or runtime mutation
↓
`initSheet` → normalize sheet props → `initRow` (process cells, indexes, comments/notes)
↓
UI render requested (`renderTable` / incremental refresh)
↓
`renderTable` builds panels, colgroups, delegates each cell to `cellRenderer.render` with `CellRenderArgs`
↓
Post-render updates: `checkRowHeightChanged`, `checkTableWidth`, conditional formats, visible notes, merge border updates
↓
Runtime events: `rowHeightChanged` / `colWidthChanged` → recompute panel sizes (`setPanelWidth` / `setPanelHeight`) and refresh affected rows/cols
## Operations Handled (functions & implementation notes)
- `initSheet`:
- Ensures required sheet fields exist (`rowCount`, `colCount`, `topLeftCell`, `usedRange`, `rows`, `columns`, `ranges`).
- Sets `paneTopLeftCell` based on `frozenRows`/`frozenColumns` and `topLeftCell`.
- Calls `initRow` and `processIdx` to normalize row/column indices.
- `processComments` / `processNotes`:
- Convert legacy comment/note cell values into structured models with ids, timestamps and push into `sheet.comments`/`sheet.notes`.
- `renderPanel` / `initHeaderPanel` / `createHeaderTable`:
- Create DOM containers for headers and content, adding frozen-pane wrappers when required.
- `renderTable(args)`:
- Builds column groups and table structure, uses `rowRenderer.render()` for header rows, and iterates `args.cells` mapping addresses → indexes.
- For each cell, composes `CellRenderArgs` and calls `cellRenderer.render` which handles cell-level DOM creation and merge logic.
- Handles frozen rows/columns by rendering split regions and coordinating `viewport` indices.
- After DOM changes, triggers post-render checks (`checkRowHeightChanged`, `checkTableWidth`) and notifies `contentLoaded` and `dataBound`.
- Incremental refreshes (`updateRowContent`, `refreshRowContent`, `refreshColumnContent`, `updateColContent`):
- Clone fragments, patch only changed rows/cols, maintain colgroup widths and merge border bookkeeping for minimal DOM updates.
- Layout helpers (`setPanelWidth`, `setPanelHeight`, `getRowHeaderWidth`, `getColHeaderHeight`):
- Calculate header sizes including DPR adjustments via `getDPRValue`, scrollbar offsets, and frozen pane placements.
- Merge and virtualization handling:
- `updateMergeBorder` invoked after render to fix merged-cell borders.
- `checkRowMerge` / `checkColMerge` and `refreshFirstCell` used during virtualized updates to ensure merged spans render correctly.
## Validation & Safety
- Defensive initialization: `initSheet` and `initRow` create/normalize missing properties to avoid runtime undefineds.
- Virtualization-aware operations: functions use `skipHiddenIdx`, viewport indices, and cloned fragments to avoid repaint thrash and to preserve DOM while virtualizing.
- Frozen panes & headers: layout functions guard for `frozenRows`/`frozenColumns` and fallback behaviors when headers are hidden.
- Accessibility: renderer sets `aria-rowcount`, `aria-colcount`, `aria-colindex`/`aria-rowindex` on generated tables/rows.
- Merge/Span edge cases: merges are checked and refreshed during incremental updates to avoid broken layouts when rows/cols are added/removed.
## Desired Outputs
- User-Facing:
- Correctly rendered sheet grid with row/column headers, frozen panes, and smooth virtualization during scrolls.
- Responsive updates when row heights or column widths change, and visual indicators for hidden rows/columns.
- Accessible grid with appropriate ARIA attributes and keyboard focusability.
- System-Level:
- Model: `SheetModel` entries under `context.sheets[]` with normalized fields (`rows`, `columns`, `ranges`, `usedRange`, `paneTopLeftCell`, `frozenRows`, `frozenColumns`).
- Renderer DOM: containers and classes like `e-main-panel`, `e-row-header`, `e-column-header`, `e-sheet-content`, `e-sheet`, `e-rowhdr-table`, `e-colhdr-table`, `e-content-table` and generated `colgroup` widths.
- Services: renderer obtains `row` and `cell` services via service locator and delegates rendering accordingly.
- Events/Notifications: uses `beforeContentLoaded`, `contentLoaded`, `virtualContentLoaded`, `getUpdatedScrollPosition`, `spreadsheetCreated`, `editOperation`, `dataBound`, plus internal events like `rowHeightChanged` and `colWidthChanged`.
- Undo/Redo: model-mutating operations (sheet move/duplicate, createSheet) are wrapped with action events (`actionBegin`/`actionComplete`) and should interact with the workbook's undo/redo facilities where applicable.