@syncfusion/ej2-spreadsheet
Version:
Feature-rich JavaScript Spreadsheet (Excel) control with built-in support for selection, editing, formatting, importing and exporting to Excel
121 lines (96 loc) • 7.84 kB
Markdown
# Chart Module data flow
## What It Does
Chart subsystem coordinates creation, rendering, updating, and lifecycle management of charts in the Spreadsheet Editor. It converts sheet ranges into chart series, manages chart overlays/components, persists chart models in the workbook, and wires UI interactions (design changes, resize, copy/paste, undo/redo) into workbook state.
Primary implementation files: `src/spreadsheet/integrations/chart.ts` (UI) and `src/workbook/integrations/chart.ts` (Core).
## Entry Points (UI)
**Class:** `SpreadsheetChart`
- Listens: `initiateChart`, `refreshChartCellObj`, `refreshChartCellModel`, `refreshChartCellOnInit`, `deleteChart`, `clearChartBorder`, `insertChart`, `chartRangeSelection`, `chartDesignTab`, `undoRedoForChartDesign`, `refreshChart`.
- Key handlers:
- `initiateChartHandler()` — compose series, infer axis/format, create/update chart component overlay.
- `refreshChartData()` — reconcile chart with sheet edits, hidden rows/cols, viewport changes.
- `refreshChartCellObj()` / `refreshChartCellModel()` — reattach overlays when charts move, and during undo/redo or import.
- `insertChartHandler()` — quick-create chart templates via UI.
- `chartDesignTabHandler()` / `undoRedoForChartDesign()` — apply UI-driven design changes and map them to undo/redo records.
## Entry Points (Core)
**Class:** `WorkbookChart`
- Listens: `setChart`, `deleteChartColl`, `refreshChartSize`, `focusChartBorder`, `importModelUpdate`.
- Key handlers:
- `setChartHandler()` — normalize/sort ranges, ensure IDs, attach chart model to `parent.chartColl` and anchor `CellModel.chart`, and dispatch `initiateChart` to UI.
- `updateChartsFromSheet()` — import persisted sheet chart models into runtime `chartColl` and `CellModel.chart`.
- `deleteChartColl()` — remove chart models from runtime collection.
- `refreshChartSize()` / `focusChartBorder()` — coordinate size/focus updates across sheets.
- `getIndexesFromChart()` — translate overlay client coordinates into anchor cell indexes via notifications.
## ASCII Core Logic Flow
User action (UI) → `SpreadsheetChart` (UI handlers)
↓
validate & compute series → render/refresh chart overlay
↓
UI triggers model change → `setChart` event → `WorkbookChart.setChartHandler()`
↓
persist/normalize model → attach to `chartColl` + `CellModel.chart`
↓
Core notifies UI → `initiateChart` / `refreshChart*` → UI re-renders overlay
↓
User modifies chart (design/resize/undo) → UI emits design/undo events → Core persists and updates state
## Operations (functions & responsibilities)
- `initiateChartHandler()` (UI)
- Calls `processChartRange()` to compute X/Y/label ranges and detect data types (date/number/string).
- Calls `getRangeData()` to read values/displayText for ranges, honoring formats and date parsing.
- Calls `processChartSeries()` to build `SeriesModel[]` or accumulation series, handling date axis, string series, and discontinuous ranges.
- Infers axis formatting via `getAxisFormat()`.
- Instantiates/updates chart component (Chart/AccumulationChart) and overlay element.
- `processChartRange()` (UI helper)
- Splits ranges into xRange, yRange, lRange; detects `isDateTime`, `isStringSeries`, `isCellFormat`, and single-row/col scenarios.
- `getRangeData()` (UI helper)
- Reads cell objects from sheet, returns values and displayText; supports `isDateTime` and `isScatter` modes.
- `processChartSeries()` (UI helper)
- Converts raw range data into the chart library series models, computes min/max for numeric/date axes, handles markers and labels.
- `setChartHandler()` (Core)
- Normalize/sort discontinuous ranges and convert to `{sheetName}!A1:B2` style.
- Generate or validate `chartModel.id` via `getUniqueID('e_spreadsheet_chart')`.
- Apply defaults: `theme`, `type`, `isSeriesInRows`, `height`, `width`, `markerSettings`.
- Attach model to `parent.chartColl`; set `cell.chart` via `setCell(row, col, sheet, { chart: [chartModel] })`.
- Notify UI with `initiateChart` event including `option: chartModel`.
- Handle flags: `isInitCell`, `isUndoRedo`, `isPaste`, `isCut`, `isUndo`, `isRedo` to maintain correct lifecycle during edits/copies/undo.
- `getIndexesFromChart()` (Core helper)
- Uses `addDPRValue()` to convert client coordinates; posts notifications `getChartRowIdxFromClientY` and `getChartColIdxFromClientX` to compute anchor row/col.
- `refreshChartData()`
- On cell edits or structural changes, determines whether chart data or axes need recomputation; updates chart component series or triggers full reprocess.
- Design change helpers
- `switchRowColumn()`, `switchChartType()`, `switchChartTheme()` — adjust series and component options and request re-render.
- `titleDlgHandler()` — manage title dialog lifecycle and apply title changes to model and UI.
## Validation & Safety
- Range normalization: `setChartHandler()` sorts/limits ranges to `usedRange` and normalizes discontinuous ranges before persisting.
- ID safety: always use `getUniqueID('e_spreadsheet_chart')` to avoid collisions.
- Protected state: operations check `parent.isPrintingProcessing` and sheet protection; skip attaching charts during printing or when not allowed.
- Undo/Redo: handlers accept `isUndo`/`isRedo` flags; UI publishes `undoRedoForChartDesign` and `setChart` supports replaying state changes.
- Hidden/removed sheets: `updateChartsFromSheet()` reattaches chart models safely during import/deserialize.
- Coordinate mapping: client → cell translation uses DPR adjustments and centralized notifications to avoid inconsistent anchor placement.
## Desired Outputs
User-facing
- Chart overlay anchored to a worksheet cell: draggable, resizable, shows title/legend/series/markers.
- Live design controls: change chart type, theme, markers, and switch row/column with immediate visual update.
- Range selection UI for editing chart source ranges and re-binding series.
- Clear focus/border and selection state for the active chart overlay.
- Undo/Redo for chart creation, deletion, and design changes.
System-level
- Events (cross-layer):
- UI → Core: `setChart` (create/persist chart model)
- Core → UI: `initiateChart` (render or refresh chart overlay)
- Update/Refresh: `refreshChart`, `refreshChartCellOnInit`, `refreshChartCellObj`, `refreshChartCellModel`
- Management: `deleteChartColl`, `importModelUpdate`, `focusChartBorder`
- Design/undo: `chartDesignTab`, `undoRedoForChartDesign`, `insertChart`, `chartRangeSelection`
- Model artifacts:
- Runtime collection: `parent.chartColl` holds `ExtendedChartModel[]`.
- Cell attachment: `CellModel.chart` array stores models anchored to a cell; `chartModel.address` records `[row, col]`.
- `ExtendedChartModel` core fields: `id`, `range`, `address`, `type`, `theme`, `isSeriesInRows`, `markerSettings`, `height`, `width`, `title`, `legendSettings`, axis configs.
- DOM / CSS hooks:
- Overlay element id/class pattern: chart overlay elements use `chartModel.id` and overlay id typically suffixed with `_overlay`.
- Active overlay class: `.e-ss-overlay-active` used to detect UI-active charts.
- Undo/Redo records:
- Chart add/edit/delete and design operations should be recorded and replayable using existing `isUndo`/`isRedo` hooks in handlers.
## Implementation Notes (short)
- Maintain strict UI/core split: `SpreadsheetChart` composes series and interacts with chart library; `WorkbookChart` persists and normalizes chart models.
- Always normalize and sort ranges in `setChartHandler()` before persisting to avoid duplicate/conflicting ranges.
- Use existing notifications (`getChartRowIdxFromClientY`, `getChartColIdxFromClientX`, `initiateChart`) when coordinating layout/attachment.
---