UNPKG

devexpress-reporting

Version:

DevExpress Reporting provides the capability to develop a reporting application to create and customize reports.

167 lines (166 loc) 6.99 kB
/** * DevExpress HTML/JS Reporting (designer\controls\xrTable.js) * Version: 24.2.6 * Build date: Mar 18, 2025 * Copyright (c) 2012 - 2025 Developer Express Inc. ALL RIGHTS RESERVED * License: https://www.devexpress.com/Support/EULAs/universal.xml */ import { isFunction } from '@devexpress/analytics-core/analytics-internal'; import { deserializeArray } from '@devexpress/analytics-core/analytics-utils'; import * as ko from 'knockout'; import { TableCalculationProvider } from './utils/_tableCalculationProvider'; import { XRControlSurfaceBase, XRControlViewModel } from './xrControl'; import { XRTableRowViewModel } from './xrTableRow'; export class XRTableControlViewModel extends XRControlViewModel { _getAdjacentCells(condition) { const adjacentCells = []; this.rows().forEach((row) => { row.cells().filter((cell) => { return condition(cell); }).forEach((cell) => { adjacentCells.push(cell); }); }); return adjacentCells; } dispose() { super.dispose(); this.disposeObservableArray(this.rows); this.resetObservableArray(this.rows); } constructor(control, parent, serializer) { super(control, parent, serializer); this.rows = ko.observableArray(); this._disposables.push(this.rowsTotalWeight = ko.pureComputed(() => { let result = 0; this.rows().forEach(row => { result += row.weight(); }); return result; })); this._disposables.push(this.pixelHeightWeight = ko.pureComputed(() => { return this.size.height() !== 0 ? this.rowsTotalWeight() / this.size.height() : 0; })); const deserializedRows = deserializeArray(control.Rows, (item) => { return new XRTableRowViewModel(item, this, serializer); }); this.rows(deserializedRows()); this.tableCalculationProvider = new TableCalculationProvider(this); } updateRowLocation(row, deltaHeight) { const oldHeight = row.height(); const rowIndex = this.rows().indexOf(row); if (rowIndex > 0) { const topRowHeight = this.rows()[rowIndex - 1].height; const topHeight = topRowHeight() - deltaHeight; topRowHeight(topHeight > 0 ? topHeight : 0); } else { const deltaWeight = (row.weight() / oldHeight) * deltaHeight; row.weight(row.weight() + deltaWeight); this.location.y(this.location.y() - deltaHeight); this.size.height(this.size.height() + deltaHeight); } } addChild(control, position, onComponentAdded) { if (control instanceof XRTableRowViewModel) { if (this.rows().indexOf(control) === -1) { control.parentModel(this); if (position != null) { this.rows.splice(position, 0, control); } else { this.rows.push(control); } if (isFunction(onComponentAdded)) onComponentAdded({ parent: this, model: control }); } } else { throw new Error('Trying to add non a row to the table.'); } } insertRow(selectedRow, isRowAbove, onComponentAdded) { const selectedRowHeight = selectedRow.height(), newRow = new XRTableRowViewModel({ '@ControlType': 'XRTableRow', '@Weight': selectedRow.weight(), '@HeightF': selectedRowHeight, }, this), indexSelectedRow = this.rows.indexOf(selectedRow); selectedRow.cells().forEach((cell) => { newRow.createChild({ '@ControlType': 'XRTableCell', '@Weight': cell.weight(), '@Multiline': 'true' }); }); this.addChild(newRow, indexSelectedRow + (isRowAbove ? 0 : 1), onComponentAdded); this.size.height(this.size.height() + selectedRowHeight); } removeChild(selectedRow) { if (this.rows().length > 0 && this.rows().indexOf(selectedRow) !== -1) { const index = this.rows().indexOf(selectedRow); this.size.height(this.size.height() - selectedRow.height()); this.rows.splice(index, 1); } if (this.rows().length === 0) { this.parentModel().removeChild(this); } } insertColumn(selectedCell, isRight, onComponentAdded) { const selectedCellX = selectedCell.surface.rect().left, selectedCellRight = selectedCell.surface.rect().left + selectedCell.surface.rect().width, adjacentCells = this._getAdjacentCells((cell) => { return isRight ? ((cell.surface.rect().left + cell.surface.rect().width) === selectedCellRight) : (cell.surface.rect().left === selectedCellX); }); adjacentCells.forEach((cell) => { cell.parentModel().insertCellCopy(cell, isRight, onComponentAdded); }); } addColumnToCalculation(diff, last = false) { const rows = this.rows(); for (let i = 0; i < rows.length; i++) { rows[i].addCellToCalculation(last ? rows[i].cells().length - 1 : 0, diff); } } } export class XRTableSurface extends XRControlSurfaceBase { _getChildrenHolderName() { return 'rows'; } dispose() { super.dispose(); this.disposeObservableArray(this.rows); this.resetObservableArray(this.rows); } constructor(control, context) { super(control, context, XRTableSurface._unitProperties); this._isUpdating = false; this.template = 'dxrd-table'; this.selectiontemplate = 'dxrd-table-selection'; this._disposables.push(this.css = ko.pureComputed(() => { return {}; })); this._disposables.push(this.contentCss = ko.pureComputed(() => { return {}; })); } _isCellInColumn(cell, locationStart, locationEnd) { return Math.abs(cell.rect().left - locationStart) < 0.01 && Math.abs(cell.rect().left + cell.rect().width - locationEnd) < 0.01; } selectColumn(selection, cellSurface) { selection.initialize(this); const locationStart = cellSurface.rect().left, locationEnd = locationStart + cellSurface.rect().width; selection.selecting({ control: cellSurface, cancel: false }); this.rows().forEach((rowSurface) => { rowSurface.cells().forEach((cellSurface) => { if (this._isCellInColumn(cellSurface, locationStart, locationEnd)) { selection.selecting({ control: cellSurface, cancel: false }); return true; } }); }); } isThereIntersectionWithChildCollection() { return false; } } XRTableSurface._unitProperties = { _x: (o) => { return o.location.x; }, _y: (o) => { return o.location.y; }, _width: (o) => { return o.size.width; }, _height: (o) => { return o.size.height; } };