@guiexpert/table 1.1.93 → 1.1.94
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -0
- package/css/main.css +142 -0
- package/css/table-classes.css +34 -0
- package/css/table-color-vars.css +32 -0
- package/css/table-pivot.css +42 -0
- package/css/table-row-group.css +25 -0
- package/css/table-tree.css +9 -0
- package/index.cjs +44 -36
- package/index.d.ts +39 -0
- package/index.js +6247 -3509
- package/lib/table/aggregation/aggregate-internals.d.ts +30 -0
- package/lib/table/aggregation/aggregate-spec.if.d.ts +51 -0
- package/lib/table/aggregation/aggregate.d.ts +58 -0
- package/lib/table/aggregation/aggregator-name.type.d.ts +39 -0
- package/lib/table/aggregation/aggregator.if.d.ts +51 -0
- package/lib/table/aggregation/aggregators.d.ts +37 -0
- package/lib/table/aggregation/create-value-getter.d.ts +18 -0
- package/lib/table/aggregation/selection-aggregates.if.d.ts +35 -0
- package/lib/table/aggregation/value-accessor.type.d.ts +13 -0
- package/lib/table/data/common/row-number-column-def.d.ts +107 -0
- package/lib/table/data/common/row-number-columns.d.ts +17 -0
- package/lib/table/data/common/row-number-options.d.ts +19 -0
- package/lib/table/data/common/row-number-options.if.d.ts +44 -0
- package/lib/table/data/tablemodel/areamodel/aggregate-footer-options.if.d.ts +73 -0
- package/lib/table/data/tablemodel/areamodel/area-model-aggregate-footer.d.ts +145 -0
- package/lib/table/data/tablemodel/areamodel/area-model-cell-groups.d.ts +18 -1
- package/lib/table/data/tablemodel/areamodel/area-model-pivot-footer.d.ts +47 -0
- package/lib/table/data/tablemodel/areamodel/area-model-pivot.d.ts +250 -0
- package/lib/table/data/tablemodel/areamodel/area-model-row-groups.d.ts +314 -0
- package/lib/table/data/tablemodel/areamodel/area-model-tree.d.ts +14 -0
- package/lib/table/data/tablemodel/areamodel/area-model.if.d.ts +39 -0
- package/lib/table/data/tablemodel/areamodel/derived-values-change.if.d.ts +30 -0
- package/lib/table/factory/pivot-factory.d.ts +63 -0
- package/lib/table/factory/pivot-table-model-para.if.d.ts +44 -0
- package/lib/table/factory/row-group-factory.d.ts +70 -0
- package/lib/table/factory/row-group-table-model-para.if.d.ts +66 -0
- package/lib/table/factory/table-factory.d.ts +45 -1
- package/lib/table/instanceof-workaround.d.ts +143 -6
- package/lib/table/pivot/area-model-pivot-header.d.ts +9 -0
- package/lib/table/pivot/pivot-column-def.d.ts +28 -0
- package/lib/table/pivot/pivot-column-info.if.d.ts +25 -0
- package/lib/table/pivot/pivot-config.if.d.ts +58 -0
- package/lib/table/pivot/pivot-internals.d.ts +13 -0
- package/lib/table/pivot/pivot-layout.d.ts +40 -0
- package/lib/table/pivot/pivot-result.d.ts +157 -0
- package/lib/table/pivot/pivot-table-model.d.ts +86 -0
- package/lib/table/pivot/pivot-value.type.d.ts +67 -0
- package/lib/table/render-scope.d.ts +61 -4
- package/lib/table/renderer/aggregate-cell-renderer.d.ts +27 -0
- package/lib/table/renderer/row-number-cell-renderer.d.ts +27 -0
- package/lib/table/rowgroup/group-rows-internals.d.ts +14 -0
- package/lib/table/rowgroup/group-rows-options.if.d.ts +13 -0
- package/lib/table/rowgroup/group-rows.d.ts +48 -0
- package/lib/table/rowgroup/row-group-column-def.d.ts +26 -0
- package/lib/table/rowgroup/row-group-column-options.if.d.ts +27 -0
- package/lib/table/rowgroup/row-group-detail-row.d.ts +8 -0
- package/lib/table/rowgroup/row-group-field.type.d.ts +56 -0
- package/lib/table/rowgroup/row-group-internals.d.ts +31 -0
- package/lib/table/rowgroup/row-group-layout.d.ts +13 -0
- package/lib/table/rowgroup/row-group-model-options.if.d.ts +39 -0
- package/lib/table/rowgroup/row-group.d.ts +51 -0
- package/lib/table/rowgroup/row-group.if.d.ts +48 -0
- package/lib/table/selection/selection-aggregator.d.ts +37 -0
- package/lib/table/selection/selection-service.d.ts +7 -0
- package/lib/table/service/convenience-dom.service.d.ts +5 -0
- package/lib/table/table-api.d.ts +112 -1
- package/lib/table/table-scope.d.ts +19 -0
- package/package.json +3 -2
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { ValueAccessor } from '../aggregation/value-accessor.type.js';
|
|
2
|
+
import { AggregatorRef } from '../aggregation/aggregator-name.type.js';
|
|
3
|
+
import { AggregatorIf } from '../aggregation/aggregator.if.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* One value of a pivot table in full form: where the value of a row comes from, how it is aggregated, and how its
|
|
7
|
+
* columns are named. The short form is just the {@link ValueAccessor} (`"umsatz"` = the sum of umsatz).
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* const revenue: PivotValueIf<Order> = { value: "total", label: "Revenue" }; // sum
|
|
11
|
+
* const orders: PivotValueIf<Order> = { value: "id", aggregator: "count", label: "Orders" };
|
|
12
|
+
* const avgPrice: PivotValueIf<Order> = {
|
|
13
|
+
* value: o => o.total / o.quantity, aggregator: "avg", label: "Avg. price",
|
|
14
|
+
* format: v => v === undefined ? "" : `${(v as number).toFixed(2)} €`
|
|
15
|
+
* };
|
|
16
|
+
*
|
|
17
|
+
* @typeParam T - the row type
|
|
18
|
+
* @since 1.1.94
|
|
19
|
+
* @category Pivot
|
|
20
|
+
*/
|
|
21
|
+
export interface PivotValueIf<T = any> {
|
|
22
|
+
/** The value of a row: a property path (`"umsatz"`, `"order.total"`) or a function. */
|
|
23
|
+
value: ValueAccessor<T>;
|
|
24
|
+
/** A built-in aggregator by name (`"sum"`, `"avg"`, `"count"` …) or an own {@link AggregatorIf}. Default `"sum"`. */
|
|
25
|
+
aggregator?: AggregatorRef;
|
|
26
|
+
/**
|
|
27
|
+
* The id of the value – part of the column properties and the name in {@link PivotResult.getValue}.
|
|
28
|
+
* Default: `"<aggregator>(<path>)"`, e.g. `"sum(umsatz)"`; for a function `"<aggregator>(value<N>)"`.
|
|
29
|
+
*/
|
|
30
|
+
name?: string;
|
|
31
|
+
/** The header of its columns (with several values). Default: the name. Text only – never HTML. */
|
|
32
|
+
label?: string;
|
|
33
|
+
/** The text of a result in a cell. Default: numbers with at most two decimals (`"1,234.5"`). Excel gets the raw value. */
|
|
34
|
+
format?: (result: unknown) => string;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* A value of a pivot table: a property path or function (summed) or the full form {@link PivotValueIf}.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* const values: PivotValue<Sale>[] = ["umsatz", { value: "umsatz", aggregator: "count", label: "Count" }];
|
|
41
|
+
*
|
|
42
|
+
* @typeParam T - the row type
|
|
43
|
+
* @since 1.1.94
|
|
44
|
+
* @category Pivot
|
|
45
|
+
*/
|
|
46
|
+
export type PivotValue<T = any> = ValueAccessor<T> | PivotValueIf<T>;
|
|
47
|
+
/**
|
|
48
|
+
* A value of a pivot table as the table uses it: name, label, aggregator and format resolved
|
|
49
|
+
* ({@link PivotResult.values}, {@link PivotColumnInfoIf.value}).
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* const pivotBody = pivotModel.getPivotBody();
|
|
53
|
+
* pivotBody.getResult().values.map(v => v.name); // ["sum(umsatz)"]
|
|
54
|
+
*
|
|
55
|
+
* @since 1.1.94
|
|
56
|
+
* @category Pivot
|
|
57
|
+
*/
|
|
58
|
+
export interface PivotValueInfoIf {
|
|
59
|
+
/** The id ({@link PivotValueIf.name}). */
|
|
60
|
+
readonly name: string;
|
|
61
|
+
/** The header label. */
|
|
62
|
+
readonly label: string;
|
|
63
|
+
/** The aggregator. */
|
|
64
|
+
readonly aggregator: AggregatorIf;
|
|
65
|
+
/** The format of a result, if one was given. */
|
|
66
|
+
readonly format?: (result: unknown) => string;
|
|
67
|
+
}
|
|
@@ -8,6 +8,7 @@ import { RendererCleanupFnType } from './renderer/renderer-cleanup-fn.type.js';
|
|
|
8
8
|
import { AreaIdent } from './data/tablemodel/area-ident.type.js';
|
|
9
9
|
import { SideIdent } from './data/side-ident.type.js';
|
|
10
10
|
import { DivScope } from './data/div-scope.type.js';
|
|
11
|
+
import { DerivedValuesChangeIf } from './data/tablemodel/areamodel/derived-values-change.if.js';
|
|
11
12
|
import { AreaModelIf } from './data/tablemodel/areamodel/area-model.if.js';
|
|
12
13
|
import { ArgsAdjustColumnsToRowParentParams } from './data/common/args-adjust-columns-to-row-parent-params.js';
|
|
13
14
|
import { ArgsRenderCellDiv } from './data/common/args-render-cell-div.js';
|
|
@@ -116,6 +117,15 @@ export declare class RenderScope extends EleScope {
|
|
|
116
117
|
* @return {void}
|
|
117
118
|
*/
|
|
118
119
|
repaint(): void;
|
|
120
|
+
/**
|
|
121
|
+
* Drops cached, derived values of the area models ({@link AreaModelIf.invalidateDerivedValues}, e.g. the totals of an
|
|
122
|
+
* {@link AreaModelAggregateFooter}) – called where data may have changed (filter, sorting, editing, `updateCells`,
|
|
123
|
+
* the public `tableApi.repaint()` / `repaintHard()`), not on scrolling.
|
|
124
|
+
*
|
|
125
|
+
* @param {DerivedValuesChangeIf} [change] - the changed rows of an edit or `updateCells()` (models may recompute less)
|
|
126
|
+
* @since 1.1.94
|
|
127
|
+
*/
|
|
128
|
+
invalidateAggregates(change?: DerivedValuesChangeIf): void;
|
|
119
129
|
/**
|
|
120
130
|
* Repaints the UI by resetting the size of the wrapper div,
|
|
121
131
|
* adjusting the containers and rows, and performing additional adjustments
|
|
@@ -183,6 +193,16 @@ export declare class RenderScope extends EleScope {
|
|
|
183
193
|
* @returns {void}
|
|
184
194
|
*/
|
|
185
195
|
updateCells(events: TableCellUpdateEventIf[], repaintAll?: boolean): void;
|
|
196
|
+
/**
|
|
197
|
+
* After `updateCells()` without a repaint: draws the rendered aggregate cells of the group rows of a row grouping
|
|
198
|
+
* again (they follow the changed rows; labels and counts don't change – a moved row repaints the whole table).
|
|
199
|
+
*/
|
|
200
|
+
protected rerenderGroupRowCells(): void;
|
|
201
|
+
/**
|
|
202
|
+
* After `updateCells()` without a repaint: draws the rendered cells of a footer with cached totals again (only if the
|
|
203
|
+
* footer implements {@link AreaModelIf.invalidateDerivedValues}, and not if the events changed the footer itself).
|
|
204
|
+
*/
|
|
205
|
+
protected rerenderDerivedFooterCells(events: TableCellUpdateEventIf[]): void;
|
|
186
206
|
/**
|
|
187
207
|
* Rerenders the content of a table cell based on the given parameters.
|
|
188
208
|
*
|
|
@@ -360,11 +380,48 @@ export declare class RenderScope extends EleScope {
|
|
|
360
380
|
*
|
|
361
381
|
* @protected
|
|
362
382
|
*
|
|
363
|
-
* @returns {
|
|
364
|
-
*
|
|
365
|
-
|
|
383
|
+
* @returns {number} The column index of the tree arrow column: the first data column (0, behind a row number
|
|
384
|
+
* column 1), one more with a visible row checkbox column.
|
|
385
|
+
*/
|
|
386
|
+
protected getTreeArrowColumnIndex(): number;
|
|
387
|
+
/**
|
|
388
|
+
* Index of the first column that is not a row number column: 1 behind a {@link RowNumberColumnDef}, otherwise 0.
|
|
389
|
+
* The checkbox of `showCheckboxWihoutExtraColumn` and the tree arrow are bound to it.
|
|
390
|
+
*
|
|
391
|
+
* @returns {number} 0 or 1
|
|
392
|
+
* @since 1.1.93
|
|
393
|
+
*/
|
|
394
|
+
getFirstDataColumnIndex(): number;
|
|
395
|
+
/** false for a row number column: it has no resize handle (its width follows the numbers). */
|
|
396
|
+
protected isColumnResizable(columnIndex: number): boolean;
|
|
397
|
+
/**
|
|
398
|
+
* The last measured text of the row number column and its width (measured again only when the text changes).
|
|
399
|
+
* `approximate`: measured with the font of the host before a number cell existed – measured again with the font of
|
|
400
|
+
* a rendered number cell in the next render pass.
|
|
401
|
+
*/
|
|
402
|
+
private rowNumberWidth?;
|
|
403
|
+
/** true while the containers are adjusted to a new row number width (no second change in that nested pass). */
|
|
404
|
+
private adjustingRowNumberWidth;
|
|
405
|
+
/** the approximate first width is measured again once (see adjustAfterScrolling). */
|
|
406
|
+
private rowNumberRemeasureScheduled;
|
|
407
|
+
/**
|
|
408
|
+
* Fits the width of a leading row number column ({@link RowNumberColumnDef}) to its largest number. Cheap on every
|
|
409
|
+
* render pass: only the text of the largest number is compared; it is measured (canvas) only when it changed.
|
|
410
|
+
*
|
|
411
|
+
* @returns {boolean} true if the width changed (the containers must be adjusted)
|
|
412
|
+
* @since 1.1.93
|
|
413
|
+
*/
|
|
414
|
+
protected adjustRowNumberColumnWidth(): boolean;
|
|
415
|
+
/** A rendered label of a number cell – its font and padding are what the numbers need. */
|
|
416
|
+
private findRowNumberLabel;
|
|
417
|
+
/**
|
|
418
|
+
* Width in px of a row number text: with the font and padding of a rendered number cell label; before the first
|
|
419
|
+
* number cell exists with the font of the host and 6 px padding on each side (then `approximate` is true).
|
|
420
|
+
* Digits are measured as "0" (tabular figures: all digits are as wide as the widest).
|
|
421
|
+
*
|
|
422
|
+
* @returns {[number, boolean]} the width and whether it is approximate
|
|
366
423
|
*/
|
|
367
|
-
protected
|
|
424
|
+
protected measureRowNumberText(text: string): [number, boolean];
|
|
368
425
|
protected addAndRenderCellDiv({ areaModel, areaIdent, sideIdent, rowIndex, index, left, width, height, top, parent, lastRowOfModel }: ArgsRenderCellDiv): [HTMLDivElement, RendererCleanupFnType | undefined];
|
|
369
426
|
/**
|
|
370
427
|
* Applies CSS classes to an HTML element.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { AreaModelIf } from '../data/tablemodel/areamodel/area-model.if.js';
|
|
2
|
+
import { CellRendererIf } from './cell-render.if.js';
|
|
3
|
+
import { DomServiceIf } from '../service/dom-service.if.js';
|
|
4
|
+
import { AreaIdent } from '../data/tablemodel/area-ident.type.js';
|
|
5
|
+
import { RendererCleanupFnType } from './renderer-cleanup-fn.type.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Writes the formatted text of a cell (`areaModel.getTextValueAt`) as a text node – never as HTML – in the label
|
|
9
|
+
* structure of a normal cell (`.ge-table-label-div > .ge-table-label`). {@link AreaModelAggregateFooter} uses it for
|
|
10
|
+
* its results (`"1,234.5"` instead of the raw `1234.4999999`) and labels when the column has no footer renderer.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* // an own footer model that formats in getTextValueAt and shows that text
|
|
14
|
+
* class MyFooter extends AreaModel {
|
|
15
|
+
* private readonly renderer = new AggregateCellRenderer();
|
|
16
|
+
* override getCellRenderer(_row: number, _col: number): CellRendererIf { return this.renderer; }
|
|
17
|
+
* override getTextValueAt(_row: number, _col: number): string { return "Σ 42"; }
|
|
18
|
+
* }
|
|
19
|
+
*
|
|
20
|
+
* @since 1.1.94
|
|
21
|
+
* @category Aggregation
|
|
22
|
+
*/
|
|
23
|
+
export declare class AggregateCellRenderer implements CellRendererIf {
|
|
24
|
+
/** Marker (works across copies of the core). */
|
|
25
|
+
readonly type = "AggregateCellRenderer";
|
|
26
|
+
render(cellDiv: HTMLDivElement, rowIndex: number, columnIndex: number, areaIdent: AreaIdent, areaModel: AreaModelIf, _cellValue: any, domService: DomServiceIf): RendererCleanupFnType | undefined;
|
|
27
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { AreaModelIf } from '../data/tablemodel/areamodel/area-model.if.js';
|
|
2
|
+
import { CellRendererIf } from './cell-render.if.js';
|
|
3
|
+
import { DomServiceIf } from '../service/dom-service.if.js';
|
|
4
|
+
import { AreaIdent } from '../data/tablemodel/area-ident.type.js';
|
|
5
|
+
import { RendererCleanupFnType } from './renderer-cleanup-fn.type.js';
|
|
6
|
+
import { RowNumberColumnDef } from '../data/common/row-number-column-def.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Renders the number of a body row – the body renderer of {@link RowNumberColumnDef}. The text is set as a text node
|
|
10
|
+
* (never as HTML), in the same label structure as a normal cell (`.ge-table-label-div > .ge-table-label`).
|
|
11
|
+
*
|
|
12
|
+
* The table uses it for a `RowNumberColumnDef` with every body model (also own {@link AreaModel}s without renderers).
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* const columnDef = new RowNumberColumnDef();
|
|
16
|
+
* const renderer = columnDef.rendererMap.body; // a RowNumberCellRenderer
|
|
17
|
+
*
|
|
18
|
+
* @since 1.1.93
|
|
19
|
+
* @category Row numbers
|
|
20
|
+
*/
|
|
21
|
+
export declare class RowNumberCellRenderer implements CellRendererIf {
|
|
22
|
+
private readonly columnDef;
|
|
23
|
+
/** Marker (works across copies of the core). */
|
|
24
|
+
readonly type = "RowNumberCellRenderer";
|
|
25
|
+
constructor(columnDef: Pick<RowNumberColumnDef, "getRowNumberText">);
|
|
26
|
+
render(cellDiv: HTMLDivElement, rowIndex: number, columnIndex: number, areaIdent: AreaIdent, areaModel: AreaModelIf, _cellValue: any, domService: DomServiceIf): RendererCleanupFnType | undefined;
|
|
27
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { RowGroup } from './row-group.js';
|
|
2
|
+
import { ResolvedRowGroupField } from './row-group-internals.js';
|
|
3
|
+
import { ResolvedAggregateSpec } from '../aggregation/aggregate-internals.js';
|
|
4
|
+
|
|
5
|
+
/** {@link groupRows} with resolved levels. @internal */
|
|
6
|
+
export declare function groupRowsResolved<T>(rows: ArrayLike<T>, fields: ResolvedRowGroupField<T>[], emptyLabel: string): RowGroup<T>[];
|
|
7
|
+
/** {@link aggregateRowGroups} with resolved specs. @internal */
|
|
8
|
+
export declare function aggregateRowGroupsResolved<T>(groups: RowGroup<T>[], specs: ResolvedAggregateSpec<T>[], accept?: (sourceIndex: number) => boolean): Record<string, unknown>;
|
|
9
|
+
/** The totals: the merged states of the given groups. @internal */
|
|
10
|
+
export declare function totalsOf<T>(groups: RowGroup<T>[], specs: ResolvedAggregateSpec<T>[]): Record<string, unknown>;
|
|
11
|
+
/** Aggregates the rows of a group of the last level. @internal */
|
|
12
|
+
export declare function computeLeaf<T>(group: RowGroup<T>, specs: ResolvedAggregateSpec<T>[], accept?: (i: number) => boolean): void;
|
|
13
|
+
/** A group above the last level: merges the states of its sub-groups (they stay unchanged). @internal */
|
|
14
|
+
export declare function mergeChildren<T>(group: RowGroup<T>, specs: ResolvedAggregateSpec<T>[]): void;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options of {@link groupRows}.
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* const groups = groupRows(orders, ["country"], { emptyLabel: "(no country)" });
|
|
6
|
+
*
|
|
7
|
+
* @since 1.1.94
|
|
8
|
+
* @category Row grouping
|
|
9
|
+
*/
|
|
10
|
+
export interface GroupRowsOptionsIf {
|
|
11
|
+
/** The label of the group of empty keys (`null`, `undefined`, `""`). Default `"(empty)"`. */
|
|
12
|
+
emptyLabel?: string;
|
|
13
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { RowGroupField } from './row-group-field.type.js';
|
|
2
|
+
import { GroupRowsOptionsIf } from './group-rows-options.if.js';
|
|
3
|
+
import { AggregateSpecMap } from '../aggregation/aggregate-spec.if.js';
|
|
4
|
+
import { RowGroup } from './row-group.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Groups rows by one or more levels – the engine behind {@link AreaModelRowGroups} (and pivot tables). One pass over
|
|
8
|
+
* the rows with nested `Map`s: keys are compared as values (`1` and `"1"` are different groups, two dates of the same
|
|
9
|
+
* time one group); `null`, `undefined` and `""` form one group (label `"(empty)"`), which is always last. Groups are
|
|
10
|
+
* ordered by the `order` of their level (default ascending); the rows of a group stay in source order. The rows are
|
|
11
|
+
* not changed.
|
|
12
|
+
*
|
|
13
|
+
* Aggregates are filled by {@link aggregateRowGroups}.
|
|
14
|
+
*
|
|
15
|
+
* @param {ArrayLike<T>} rows - the rows
|
|
16
|
+
* @param {RowGroupField<T>[]} groupBy - the levels, top first: property paths, functions or {@link RowGroupFieldIf}
|
|
17
|
+
* @param {GroupRowsOptionsIf} [options] - e.g. the label of empty keys
|
|
18
|
+
* @returns {RowGroup<T>[]} the groups of the top level (empty for no levels or no rows)
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* const groups = groupRows(sales, ["region", "produkt"]);
|
|
22
|
+
* groups[0].label; // "Nord"
|
|
23
|
+
* groups[0].children[0].getRows(); // the rows of Nord › A
|
|
24
|
+
*
|
|
25
|
+
* @since 1.1.94
|
|
26
|
+
* @category Row grouping
|
|
27
|
+
*/
|
|
28
|
+
export declare function groupRows<T = any>(rows: ArrayLike<T>, groupBy: RowGroupField<T>[], options?: GroupRowsOptionsIf): RowGroup<T>[];
|
|
29
|
+
/**
|
|
30
|
+
* Computes the aggregates of all groups ({@link RowGroupIf.results}) and their row counts ({@link RowGroupIf.count}).
|
|
31
|
+
* A group of the last level aggregates its rows; every group above **merges** the states of its sub-groups – an
|
|
32
|
+
* average stays the average of all rows (sum and count are merged), never the average of averages.
|
|
33
|
+
*
|
|
34
|
+
* @param {RowGroup<T>[]} groups - the top-level groups of {@link groupRows}
|
|
35
|
+
* @param {AggregateSpecMap<T>} aggregations - key → aggregator (`{ umsatz: "sum" }`, see {@link AggregateSpecMap})
|
|
36
|
+
* @param {(sourceIndex: number) => boolean} [accept] - a filter: only rows it accepts count (index into the source rows)
|
|
37
|
+
* @returns {Record<string, unknown>} the totals over all groups
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* const groups = groupRows(sales, ["region", "produkt"]);
|
|
41
|
+
* const totals = aggregateRowGroups(groups, { umsatz: "avg" });
|
|
42
|
+
* groups[0].results.umsatz; // 90 – Nord: (100 + 50 + 120) / 3, not the mean of A (110) and B (50)
|
|
43
|
+
* totals.umsatz; // 75
|
|
44
|
+
*
|
|
45
|
+
* @since 1.1.94
|
|
46
|
+
* @category Row grouping
|
|
47
|
+
*/
|
|
48
|
+
export declare function aggregateRowGroups<T = any>(groups: RowGroup<T>[], aggregations: AggregateSpecMap<T>, accept?: (sourceIndex: number) => boolean): Record<string, unknown>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ColumnDef } from '../data/tablemodel/column/column-def.js';
|
|
2
|
+
import { RowGroupColumnOptionsIf } from './row-group-column-options.if.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The group column of a row grouping: arrows, indentation and the group labels (`"Nord (3)"`). Created by
|
|
6
|
+
* {@link RowGroupFactory.createTableModel}; the column is sortable (by group key) and not editable. Its property is
|
|
7
|
+
* {@link RowGroupColumnDef.PROPERTY} – sort and state refer to it like to any column.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* const tableModel = RowGroupFactory.createTableModel<Sale>({ rows: sales, columnDefs, groupBy: ["region"] });
|
|
11
|
+
* const groupColumn = tableModel.getColumnDefs()?.find(isRowGroupColumnDef);
|
|
12
|
+
*
|
|
13
|
+
* @since 1.1.94
|
|
14
|
+
* @category Row grouping
|
|
15
|
+
*/
|
|
16
|
+
export declare class RowGroupColumnDef extends ColumnDef {
|
|
17
|
+
/** The property of the group column. */
|
|
18
|
+
static readonly PROPERTY = "RowGroupColumn";
|
|
19
|
+
/** Marker for {@link isRowGroupColumnDef} (works across copies of the core). */
|
|
20
|
+
readonly type = "RowGroupColumnDef";
|
|
21
|
+
/** The options with defaults. */
|
|
22
|
+
readonly options: RowGroupColumnOptionsIf;
|
|
23
|
+
/** True if the header follows the grouping (no own `headerLabel`). */
|
|
24
|
+
readonly autoHeaderLabel: boolean;
|
|
25
|
+
constructor(options?: Partial<RowGroupColumnOptionsIf>);
|
|
26
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { SizeIf } from '../data/common/size.if.js';
|
|
2
|
+
import { RowGroupIf } from './row-group.if.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Options of the group column ({@link RowGroupColumnDef}) – the column with the arrows and the group labels.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* RowGroupFactory.createTableModel<Sale>({
|
|
9
|
+
* rows: sales, columnDefs, groupBy: ["region"],
|
|
10
|
+
* groupColumn: { headerLabel: "Region", width: px160, label: g => `${g.label} – ${g.count} sales` }
|
|
11
|
+
* });
|
|
12
|
+
*
|
|
13
|
+
* @since 1.1.94
|
|
14
|
+
* @category Row grouping
|
|
15
|
+
*/
|
|
16
|
+
export interface RowGroupColumnOptionsIf<T = any> {
|
|
17
|
+
/** The header text. Default: the names of the levels, e.g. `"Region › Produkt"` (follows {@link TableApi.setRowGroupBy}). */
|
|
18
|
+
headerLabel?: string;
|
|
19
|
+
/** The width. Default 220 px. */
|
|
20
|
+
width: SizeIf;
|
|
21
|
+
/** Show the number of rows behind the key: `"Nord (3)"`. Default true. */
|
|
22
|
+
showCount: boolean;
|
|
23
|
+
/** An own label of a group row (text, never HTML). Default: `"<key> (<count>)"`. */
|
|
24
|
+
label?: (group: RowGroupIf<T>) => string;
|
|
25
|
+
/** Fix the column on the left (it comes behind row numbers and the checkbox column). Default true. */
|
|
26
|
+
fixed: boolean;
|
|
27
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { TreeRow } from '../data/common/tree-row.js';
|
|
2
|
+
import { TreeRowIf } from '../data/common/tree-row-if.js';
|
|
3
|
+
|
|
4
|
+
/** A detail row: a tree row with the index of its object in the source rows. */
|
|
5
|
+
export declare class RowGroupDetailRow<T> extends TreeRow<T> {
|
|
6
|
+
readonly sourceIndex: number;
|
|
7
|
+
constructor(data: T, parent: TreeRowIf<any> | undefined, deep: number, sourceIndex: number);
|
|
8
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { ValueAccessor } from '../aggregation/value-accessor.type.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The order of the groups of one level: ascending (`"asc"`, the default), descending, in the order the keys first
|
|
5
|
+
* appear in the rows (`"insertion"`), or an own comparison of two keys. Empty keys (`null`, `undefined`, `""`) are
|
|
6
|
+
* always last.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* const months: RowGroupOrder = (a, b) => MONTHS.indexOf(a as string) - MONTHS.indexOf(b as string);
|
|
10
|
+
*
|
|
11
|
+
* @since 1.1.94
|
|
12
|
+
* @category Row grouping
|
|
13
|
+
*/
|
|
14
|
+
export type RowGroupOrder = "asc" | "desc" | "insertion" | ((a: unknown, b: unknown) => number);
|
|
15
|
+
/**
|
|
16
|
+
* One level of a row grouping in full form: where the key of a row comes from and how the groups of the level are
|
|
17
|
+
* named and ordered. The short form is just the {@link ValueAccessor} (`"region"` or a function).
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* // year › month from a date, newest year first, month names as labels
|
|
21
|
+
* const groupBy: RowGroupField<Order>[] = [
|
|
22
|
+
* { name: "year", label: "Year", value: o => new Date(o.date).getFullYear(), order: "desc" },
|
|
23
|
+
* { name: "month", label: "Month", value: o => new Date(o.date).getMonth(), format: m => MONTHS[m as number] }
|
|
24
|
+
* ];
|
|
25
|
+
*
|
|
26
|
+
* @typeParam T - the row type
|
|
27
|
+
* @since 1.1.94
|
|
28
|
+
* @category Row grouping
|
|
29
|
+
*/
|
|
30
|
+
export interface RowGroupFieldIf<T = any> {
|
|
31
|
+
/** The key of a row: a property path (`"region"`, `"address.city"`) or a function (computed keys). */
|
|
32
|
+
value: ValueAccessor<T>;
|
|
33
|
+
/**
|
|
34
|
+
* The id of the level – part of the group ids that remember expanded groups ({@link RowGroupIf.id}).
|
|
35
|
+
* Default: the property path; for a function `"level<N>"` (give functions a name if you switch between them).
|
|
36
|
+
*/
|
|
37
|
+
name?: string;
|
|
38
|
+
/** The name of the level, e.g. in the header of the group column. Default: the header label of the column with this property, otherwise the name. */
|
|
39
|
+
label?: string;
|
|
40
|
+
/** The text of a key in the group label. Default: the key as text, dates as date (en-US), empty keys `emptyLabel`. Text only – never HTML. */
|
|
41
|
+
format?: (key: unknown) => string;
|
|
42
|
+
/** The order of the groups of this level. Default `"asc"`. */
|
|
43
|
+
order?: RowGroupOrder;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* One level of a row grouping: a property path (`"region"`), a function (`o => o.date.getFullYear()`) or the full form
|
|
47
|
+
* {@link RowGroupFieldIf}.
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* const groupBy: RowGroupField<Sale>[] = ["region", s => s.produkt.toUpperCase()];
|
|
51
|
+
*
|
|
52
|
+
* @typeParam T - the row type
|
|
53
|
+
* @since 1.1.94
|
|
54
|
+
* @category Row grouping
|
|
55
|
+
*/
|
|
56
|
+
export type RowGroupField<T = any> = ValueAccessor<T> | RowGroupFieldIf<T>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { RowGroupField } from './row-group-field.type.js';
|
|
2
|
+
|
|
3
|
+
/** A level of a grouping, resolved for a pass over the rows. */
|
|
4
|
+
export interface ResolvedRowGroupField<T = any> {
|
|
5
|
+
name: string;
|
|
6
|
+
/** the given label (undefined: the factory takes the column header) */
|
|
7
|
+
label?: string;
|
|
8
|
+
/** the property path, undefined for a function */
|
|
9
|
+
path?: string;
|
|
10
|
+
getKey: (row: T) => unknown;
|
|
11
|
+
format?: (key: unknown) => string;
|
|
12
|
+
/** the order of the groups (empty keys last) */
|
|
13
|
+
compare: (a: unknown, b: unknown) => number;
|
|
14
|
+
}
|
|
15
|
+
/** The key of the group of empty keys (`null`, `undefined`, `""`). */
|
|
16
|
+
export declare const EMPTY_GROUP_KEY: null;
|
|
17
|
+
/** `null`, `undefined` and `""` form one group. */
|
|
18
|
+
export declare function isEmptyGroupKey(key: unknown): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* The natural order of two non-empty group keys: numbers, dates (by time), booleans (false first), text (natural,
|
|
21
|
+
* "A2" before "A10"); keys of different types by type in this order.
|
|
22
|
+
*/
|
|
23
|
+
export declare function compareGroupKeys(a: unknown, b: unknown): number;
|
|
24
|
+
export declare function resolveRowGroupField<T>(field: RowGroupField<T>, level: number): ResolvedRowGroupField<T>;
|
|
25
|
+
export declare function resolveRowGroupFields<T>(groupBy: RowGroupField<T>[] | undefined): ResolvedRowGroupField<T>[];
|
|
26
|
+
/** The key as text with its type – part of the group id (`1` and `"1"` differ, dates by time). */
|
|
27
|
+
export declare function typedGroupKey(key: unknown): string;
|
|
28
|
+
/** The default text of a group key. */
|
|
29
|
+
export declare function defaultGroupKeyLabel(key: unknown, emptyLabel: string): string;
|
|
30
|
+
/** The level labels of a grouping, e.g. for the header of the group column. */
|
|
31
|
+
export declare function rowGroupLevelLabels<T>(fields: ResolvedRowGroupField<T>[], headerOf: (path: string) => string | undefined): string[];
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { TableModelIf } from '../data/tablemodel/table-model.if.js';
|
|
2
|
+
import { ColumnDefIf } from '../data/tablemodel/column/column-def.if.js';
|
|
3
|
+
import { RowGroupField } from './row-group-field.type.js';
|
|
4
|
+
|
|
5
|
+
/** The header text of the group column for these levels, e.g. "Region › Produkt". */
|
|
6
|
+
export declare function rowGroupHeaderLabel(groupBy: RowGroupField[], columnDefs: ColumnDefIf[]): string;
|
|
7
|
+
/**
|
|
8
|
+
* Adapts the columns of a row grouping to its current levels: hides the columns of the grouped properties (and shows
|
|
9
|
+
* the ones it hid before that are no longer grouped) and sets the header of the group column.
|
|
10
|
+
*
|
|
11
|
+
* @returns true if the body is a row grouping
|
|
12
|
+
*/
|
|
13
|
+
export declare function updateRowGroupLayout(tableModel: TableModelIf): boolean;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { RowGroupField } from './row-group-field.type.js';
|
|
2
|
+
import { AggregateSpecMap } from '../aggregation/aggregate-spec.if.js';
|
|
3
|
+
import { RowGroupIf } from './row-group.if.js';
|
|
4
|
+
import { RowGroupColumnOptionsIf } from './row-group-column-options.if.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Which groups are expanded: all (`true`), none (`false`), the levels above a number (`1` = the top level is open, its
|
|
8
|
+
* sub-groups are closed; `0` = all closed), or a function per group.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* const onlyNorth: RowGroupExpanded<Sale> = group => group.path[0] === "Nord";
|
|
12
|
+
*
|
|
13
|
+
* @since 1.1.94
|
|
14
|
+
* @category Row grouping
|
|
15
|
+
*/
|
|
16
|
+
export type RowGroupExpanded<T = any> = boolean | number | ((group: RowGroupIf<T>) => boolean);
|
|
17
|
+
/**
|
|
18
|
+
* Options of an {@link AreaModelRowGroups} (the factory {@link RowGroupFactory.createTableModel} fills them).
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* const body = new AreaModelRowGroups<Sale>(sales, columnDefs, { groupBy: ["region"], aggregations: { umsatz: "sum" } });
|
|
22
|
+
*
|
|
23
|
+
* @since 1.1.94
|
|
24
|
+
* @category Row grouping
|
|
25
|
+
*/
|
|
26
|
+
export interface RowGroupModelOptionsIf<T = any> {
|
|
27
|
+
/** The levels, top first. An empty list shows the rows without groups. */
|
|
28
|
+
groupBy: RowGroupField<T>[];
|
|
29
|
+
/** The aggregates of the group rows; the key is the property of the column that shows it (`{ umsatz: "sum" }`). */
|
|
30
|
+
aggregations?: AggregateSpecMap<T>;
|
|
31
|
+
/** Which groups are expanded at the start and in new paths after regrouping. Default true. */
|
|
32
|
+
expanded?: RowGroupExpanded<T>;
|
|
33
|
+
/** The label of the group of empty keys (`null`, `undefined`, `""`). Default `"(empty)"`. */
|
|
34
|
+
emptyLabel?: string;
|
|
35
|
+
/** Label options of the group column (`showCount`, `label`). */
|
|
36
|
+
groupColumn?: Partial<RowGroupColumnOptionsIf<T>>;
|
|
37
|
+
/** Hide the columns of the grouped properties (their values are in the group column). Default true. */
|
|
38
|
+
hideGroupedColumns?: boolean;
|
|
39
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { RowGroupIf } from './row-group.if.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A group of a row grouping (see {@link RowGroupIf}). Created by {@link groupRows} and {@link AreaModelRowGroups} –
|
|
5
|
+
* you don't create groups yourself.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* const groups = groupRows(sales, ["region"]);
|
|
9
|
+
* aggregateRowGroups(groups, { umsatz: "sum" });
|
|
10
|
+
* groups.map(g => `${g.label}: ${g.results.umsatz}`); // ["Nord: 270", "Süd: 180"]
|
|
11
|
+
*
|
|
12
|
+
* @typeParam T - the row type
|
|
13
|
+
* @since 1.1.94
|
|
14
|
+
* @category Row grouping
|
|
15
|
+
*/
|
|
16
|
+
export declare class RowGroup<T = any> implements RowGroupIf<T> {
|
|
17
|
+
readonly key: unknown;
|
|
18
|
+
readonly label: string;
|
|
19
|
+
readonly level: number;
|
|
20
|
+
readonly field: string;
|
|
21
|
+
readonly path: readonly unknown[];
|
|
22
|
+
readonly parent: RowGroup<T> | undefined;
|
|
23
|
+
/** @internal the source rows */
|
|
24
|
+
readonly source: ArrayLike<T>;
|
|
25
|
+
/** Marker for {@link isRowGroup}. */
|
|
26
|
+
readonly type = "RowGroup";
|
|
27
|
+
readonly children: RowGroup<T>[];
|
|
28
|
+
count: number;
|
|
29
|
+
results: Record<string, unknown>;
|
|
30
|
+
/** @internal indices into the source rows (last level only), in source order */
|
|
31
|
+
readonly sourceIndices: number[];
|
|
32
|
+
/** @internal aggregation states (one per spec), kept for merging and partial updates */
|
|
33
|
+
states: unknown[];
|
|
34
|
+
/** @internal the filter of the last aggregation (source index → kept) */
|
|
35
|
+
accept?: (sourceIndex: number) => boolean;
|
|
36
|
+
/** @internal parts of the id: level name + typed key per level */
|
|
37
|
+
readonly idParts: [string, string][];
|
|
38
|
+
constructor(key: unknown, label: string, level: number, field: string, path: readonly unknown[], parent: RowGroup<T> | undefined,
|
|
39
|
+
/** @internal the source rows */
|
|
40
|
+
source: ArrayLike<T>, typedKey: string);
|
|
41
|
+
/** A stable id from level names and keys, e.g. `rowgroup:[["region","s:Nord"]]`. */
|
|
42
|
+
get id(): string;
|
|
43
|
+
/** True for a group of the last level (it holds rows, no sub-groups). */
|
|
44
|
+
isLeaf(): boolean;
|
|
45
|
+
getRows(filtered?: boolean): T[];
|
|
46
|
+
/**
|
|
47
|
+
* The source indices of all rows of the group (and its sub-groups), group by group.
|
|
48
|
+
* @internal
|
|
49
|
+
*/
|
|
50
|
+
collectIndices(filtered: boolean, ret: number[]): number[];
|
|
51
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A group of a row grouping – the `data` of a group row in an {@link AreaModelRowGroups} and the result of
|
|
3
|
+
* {@link groupRows}. Groups of the last level hold the rows; groups above hold sub-groups.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* // the group of a clicked row
|
|
7
|
+
* const group = model.getRowGroup(rowIndex);
|
|
8
|
+
* if (group) console.log(group.path, group.count, group.results.umsatz); // ["Nord", "A"], 2, 220
|
|
9
|
+
*
|
|
10
|
+
* @typeParam T - the row type
|
|
11
|
+
* @since 1.1.94
|
|
12
|
+
* @category Row grouping
|
|
13
|
+
*/
|
|
14
|
+
export interface RowGroupIf<T = any> {
|
|
15
|
+
/** Marker for {@link isRowGroup} (works across copies of the core). */
|
|
16
|
+
readonly type: "RowGroup";
|
|
17
|
+
/** The key of the group, as the rows have it (`null` for the group of empty keys: `null`, `undefined`, `""`). */
|
|
18
|
+
readonly key: unknown;
|
|
19
|
+
/** The key as text (`format` of the level, otherwise the default text). */
|
|
20
|
+
readonly label: string;
|
|
21
|
+
/** The level, 0 = top. */
|
|
22
|
+
readonly level: number;
|
|
23
|
+
/** The name of the level ({@link RowGroupFieldIf.name}). */
|
|
24
|
+
readonly field: string;
|
|
25
|
+
/** The keys from the top level down to this group. */
|
|
26
|
+
readonly path: readonly unknown[];
|
|
27
|
+
/**
|
|
28
|
+
* A stable id built from the level names and keys – the same data give the same id (persistence of expanded groups).
|
|
29
|
+
* Keys that are objects or symbols get an id per page load only (they can't be stored).
|
|
30
|
+
*/
|
|
31
|
+
readonly id: string;
|
|
32
|
+
/** The parent group, undefined on the top level. */
|
|
33
|
+
readonly parent: RowGroupIf<T> | undefined;
|
|
34
|
+
/** The sub-groups, empty on the last level. */
|
|
35
|
+
readonly children: RowGroupIf<T>[];
|
|
36
|
+
/** The number of rows in the group (after the filter). */
|
|
37
|
+
readonly count: number;
|
|
38
|
+
/** The aggregates of the group by key (after the filter), e.g. `{ umsatz: 270 }`. */
|
|
39
|
+
readonly results: Record<string, unknown>;
|
|
40
|
+
/**
|
|
41
|
+
* The rows of the group and of all sub-groups, in the order of the grouped view: sub-group by sub-group, the rows of a
|
|
42
|
+
* group in source order – or sorted, after the table sorted them.
|
|
43
|
+
*
|
|
44
|
+
* @param {boolean} [filtered=true] - only the rows the filter keeps
|
|
45
|
+
* @returns {T[]} a new array
|
|
46
|
+
*/
|
|
47
|
+
getRows(filtered?: boolean): T[];
|
|
48
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { TableModelIf } from '../data/tablemodel/table-model.if.js';
|
|
2
|
+
import { SelectionModelIf } from './selection-model.if.js';
|
|
3
|
+
import { SelectionAggregatesIf } from '../aggregation/selection-aggregates.if.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Computes count, sum, average, minimum and maximum of the selected body cells ({@link SelectionAggregatesIf}) – what
|
|
7
|
+
* {@link TableApi.getSelectionAggregates} returns, e.g. for a status bar under the table.
|
|
8
|
+
*
|
|
9
|
+
* Counted are the selected cells of the visible data columns (no row numbers, no checkbox column); the numbers are the
|
|
10
|
+
* cell values (`getValueAt`) of type `number`. Negative ranges (Ctrl/⌘-click) are respected. A selection whose ranges
|
|
11
|
+
* cover more than {@link maxCells} cells is not computed (`capped: true`).
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* SelectionAggregator.maxCells = 5_000_000; // allow bigger selections
|
|
15
|
+
* const a = new SelectionAggregator().aggregate(tableModel, selectionModel);
|
|
16
|
+
*
|
|
17
|
+
* @since 1.1.94
|
|
18
|
+
* @category Aggregation
|
|
19
|
+
*/
|
|
20
|
+
export declare class SelectionAggregator {
|
|
21
|
+
/**
|
|
22
|
+
* Upper limit for the cells of the selected ranges (Ctrl+A on millions of rows). Like
|
|
23
|
+
* {@link CopyService.maxCopyCells}: above it nothing is computed.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* SelectionAggregator.maxCells = 2_000_000;
|
|
27
|
+
*/
|
|
28
|
+
static maxCells: number;
|
|
29
|
+
/**
|
|
30
|
+
* @param {TableModelIf} tableModel - the table model (body rows, columns, visibility)
|
|
31
|
+
* @param {SelectionModelIf | undefined} selectionModel - the selection; none → all zero
|
|
32
|
+
* @returns {SelectionAggregatesIf} the aggregates of the selected cells
|
|
33
|
+
*/
|
|
34
|
+
aggregate(tableModel: TableModelIf, selectionModel: SelectionModelIf | undefined): SelectionAggregatesIf;
|
|
35
|
+
/** The visible data columns between c1 and c2 (no hidden, row number or checkbox columns). */
|
|
36
|
+
private dataColumns;
|
|
37
|
+
}
|