@guiexpert/table 1.1.93 → 1.1.96

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.
Files changed (123) hide show
  1. package/README.md +25 -0
  2. package/css/main.css +334 -0
  3. package/css/table-calc.css +7 -0
  4. package/css/table-classes.css +34 -0
  5. package/css/table-color-vars.css +78 -0
  6. package/css/table-fill-batch.css +58 -0
  7. package/css/table-pivot.css +42 -0
  8. package/css/table-row-drag.css +81 -0
  9. package/css/table-row-group.css +25 -0
  10. package/css/table-tree.css +9 -0
  11. package/index.cjs +57 -47
  12. package/index.d.ts +67 -0
  13. package/index.js +11290 -4985
  14. package/lib/table/action/action-id.type.d.ts +1 -1
  15. package/lib/table/aggregation/aggregate-internals.d.ts +30 -0
  16. package/lib/table/aggregation/aggregate-spec.if.d.ts +51 -0
  17. package/lib/table/aggregation/aggregate.d.ts +58 -0
  18. package/lib/table/aggregation/aggregator-name.type.d.ts +39 -0
  19. package/lib/table/aggregation/aggregator.if.d.ts +51 -0
  20. package/lib/table/aggregation/aggregators.d.ts +37 -0
  21. package/lib/table/aggregation/create-value-getter.d.ts +18 -0
  22. package/lib/table/aggregation/selection-aggregates.if.d.ts +35 -0
  23. package/lib/table/aggregation/value-accessor.type.d.ts +13 -0
  24. package/lib/table/aria/aria-texts.d.ts +11 -0
  25. package/lib/table/aria/aria-texts.if.d.ts +87 -0
  26. package/lib/table/batch-edit/batch-edit-options.d.ts +21 -0
  27. package/lib/table/batch-edit/batch-edit-options.if.d.ts +20 -0
  28. package/lib/table/batch-edit/batch-edit-service.d.ts +104 -0
  29. package/lib/table/batch-edit/cell-change.if.d.ts +39 -0
  30. package/lib/table/batch-edit/cell-value-change.if.d.ts +18 -0
  31. package/lib/table/batch-edit/pending-cell-changes.d.ts +104 -0
  32. package/lib/table/calc/column-values.d.ts +55 -0
  33. package/lib/table/calc/show-values-as-internals.d.ts +4 -0
  34. package/lib/table/calc/show-values-as.d.ts +87 -0
  35. package/lib/table/calc/show-values-as.type.d.ts +55 -0
  36. package/lib/table/calc/value-getter-context.if.d.ts +35 -0
  37. package/lib/table/calc/value-getter.type.d.ts +36 -0
  38. package/lib/table/data/common/event/ge-batch-edit-event.d.ts +46 -0
  39. package/lib/table/data/common/event/ge-model-change-event.d.ts +27 -1
  40. package/lib/table/data/common/event/ge-row-drag-event.d.ts +89 -0
  41. package/lib/table/data/common/row-number-column-def.d.ts +107 -0
  42. package/lib/table/data/common/row-number-columns.d.ts +17 -0
  43. package/lib/table/data/common/row-number-options.d.ts +19 -0
  44. package/lib/table/data/common/row-number-options.if.d.ts +44 -0
  45. package/lib/table/data/options/table-options.d.ts +6 -0
  46. package/lib/table/data/options/table-options.if.d.ts +44 -0
  47. package/lib/table/data/tablemodel/areamodel/abstract-area-model.d.ts +66 -0
  48. package/lib/table/data/tablemodel/areamodel/aggregate-footer-options.if.d.ts +73 -0
  49. package/lib/table/data/tablemodel/areamodel/area-model-aggregate-footer.d.ts +150 -0
  50. package/lib/table/data/tablemodel/areamodel/area-model-array-of-arrays.d.ts +24 -0
  51. package/lib/table/data/tablemodel/areamodel/area-model-cell-groups.d.ts +18 -1
  52. package/lib/table/data/tablemodel/areamodel/area-model-object-array.d.ts +70 -0
  53. package/lib/table/data/tablemodel/areamodel/area-model-pivot-footer.d.ts +47 -0
  54. package/lib/table/data/tablemodel/areamodel/area-model-pivot.d.ts +281 -0
  55. package/lib/table/data/tablemodel/areamodel/area-model-row-groups.d.ts +336 -0
  56. package/lib/table/data/tablemodel/areamodel/area-model-tree.d.ts +97 -0
  57. package/lib/table/data/tablemodel/areamodel/area-model.if.d.ts +94 -0
  58. package/lib/table/data/tablemodel/areamodel/derived-values-change.if.d.ts +30 -0
  59. package/lib/table/data/tablemodel/column/column-def.d.ts +31 -1
  60. package/lib/table/data/tablemodel/column/column-def.if.d.ts +86 -0
  61. package/lib/table/event-adapter.d.ts +7 -0
  62. package/lib/table/event-listener.if.d.ts +32 -0
  63. package/lib/table/factory/pivot-factory.d.ts +63 -0
  64. package/lib/table/factory/pivot-table-model-para.if.d.ts +44 -0
  65. package/lib/table/factory/row-group-factory.d.ts +70 -0
  66. package/lib/table/factory/row-group-table-model-para.if.d.ts +66 -0
  67. package/lib/table/factory/table-factory.d.ts +56 -1
  68. package/lib/table/fill/compute-fill-changes.d.ts +67 -0
  69. package/lib/table/fill/fill-direction.type.d.ts +7 -0
  70. package/lib/table/fill/fill-handle-options.d.ts +29 -0
  71. package/lib/table/fill/fill-handle-options.if.d.ts +35 -0
  72. package/lib/table/fill/fill-handle-service.d.ts +55 -0
  73. package/lib/table/fill/fill-series.d.ts +60 -0
  74. package/lib/table/fill/fill-value-context.if.d.ts +36 -0
  75. package/lib/table/formula/compile-formula.d.ts +86 -0
  76. package/lib/table/formula/evaluator.d.ts +19 -0
  77. package/lib/table/formula/formula-ast.if.d.ts +42 -0
  78. package/lib/table/formula/formula-error.d.ts +59 -0
  79. package/lib/table/formula/formula-options.if.d.ts +41 -0
  80. package/lib/table/formula/formula-values.d.ts +13 -0
  81. package/lib/table/formula/functions.d.ts +18 -0
  82. package/lib/table/formula/parser.d.ts +10 -0
  83. package/lib/table/formula/tokenizer.d.ts +22 -0
  84. package/lib/table/instanceof-workaround.d.ts +143 -6
  85. package/lib/table/pivot/area-model-pivot-header.d.ts +9 -0
  86. package/lib/table/pivot/pivot-column-def.d.ts +28 -0
  87. package/lib/table/pivot/pivot-column-info.if.d.ts +25 -0
  88. package/lib/table/pivot/pivot-config.if.d.ts +58 -0
  89. package/lib/table/pivot/pivot-internals.d.ts +13 -0
  90. package/lib/table/pivot/pivot-layout.d.ts +40 -0
  91. package/lib/table/pivot/pivot-result.d.ts +157 -0
  92. package/lib/table/pivot/pivot-table-model.d.ts +86 -0
  93. package/lib/table/pivot/pivot-value.type.d.ts +80 -0
  94. package/lib/table/render-scope.d.ts +142 -4
  95. package/lib/table/renderer/aggregate-cell-renderer.d.ts +27 -0
  96. package/lib/table/renderer/edit/input-cell-renderer.d.ts +1 -1
  97. package/lib/table/renderer/edit/select-cell-renderer.d.ts +1 -1
  98. package/lib/table/renderer/row-number-cell-renderer.d.ts +27 -0
  99. package/lib/table/row-drag/move-rows.d.ts +157 -0
  100. package/lib/table/row-drag/row-drag-options.d.ts +28 -0
  101. package/lib/table/row-drag/row-drag-options.if.d.ts +36 -0
  102. package/lib/table/row-drag/row-drag-service.d.ts +130 -0
  103. package/lib/table/row-drag/row-drop-target.if.d.ts +29 -0
  104. package/lib/table/rowgroup/group-rows-internals.d.ts +14 -0
  105. package/lib/table/rowgroup/group-rows-options.if.d.ts +13 -0
  106. package/lib/table/rowgroup/group-rows.d.ts +48 -0
  107. package/lib/table/rowgroup/row-group-column-def.d.ts +26 -0
  108. package/lib/table/rowgroup/row-group-column-options.if.d.ts +27 -0
  109. package/lib/table/rowgroup/row-group-detail-row.d.ts +8 -0
  110. package/lib/table/rowgroup/row-group-field.type.d.ts +56 -0
  111. package/lib/table/rowgroup/row-group-internals.d.ts +31 -0
  112. package/lib/table/rowgroup/row-group-layout.d.ts +13 -0
  113. package/lib/table/rowgroup/row-group-model-options.if.d.ts +39 -0
  114. package/lib/table/rowgroup/row-group.d.ts +51 -0
  115. package/lib/table/rowgroup/row-group.if.d.ts +48 -0
  116. package/lib/table/selection/selection-aggregator.d.ts +37 -0
  117. package/lib/table/selection/selection-service.d.ts +7 -0
  118. package/lib/table/service/convenience-dom.service.d.ts +5 -0
  119. package/lib/table/service/excel-service.d.ts +6 -0
  120. package/lib/table/service/excel-service.if.d.ts +35 -0
  121. package/lib/table/table-api.d.ts +389 -3
  122. package/lib/table/table-scope.d.ts +140 -0
  123. package/package.json +3 -2
@@ -0,0 +1,41 @@
1
+ import { FormulaError } from './formula-error.js';
2
+
3
+ /**
4
+ * A value inside a formula: a number, a text, a boolean, blank (`null`) or an error.
5
+ *
6
+ * @example
7
+ * const fn: FormulaFunction = (x: FormulaValue) => typeof x === "number" ? x * 1.19 : x;
8
+ *
9
+ * @since 1.1.95
10
+ * @category Calculated columns & formulas
11
+ */
12
+ export type FormulaValue = number | string | boolean | null | FormulaError;
13
+ /**
14
+ * An own function for formulas. It gets the evaluated arguments (never an error – an error argument is returned
15
+ * without calling the function) and returns a number, text, boolean or `null`. Anything else, an exception or
16
+ * `NaN` becomes `#VALUE!` resp. `#NUM!`.
17
+ *
18
+ * @example
19
+ * const VAT: FormulaFunction = (net) => Number(net) * 0.19;
20
+ * compileFormula("VAT([price])", { functions: { VAT } });
21
+ *
22
+ * @since 1.1.95
23
+ * @category Calculated columns & formulas
24
+ */
25
+ export type FormulaFunction = (...args: FormulaValue[]) => unknown;
26
+ /**
27
+ * Options of {@link compileFormula}.
28
+ *
29
+ * @example
30
+ * const options: FormulaOptionsIf = {
31
+ * functions: { NET: (gross) => Number(gross) / 1.19 }
32
+ * };
33
+ * ColumnDef.create({ property: "net", headerLabel: "Net", formula: "NET([gross])", formulaOptions: options });
34
+ *
35
+ * @since 1.1.95
36
+ * @category Calculated columns & formulas
37
+ */
38
+ export interface FormulaOptionsIf {
39
+ /** Own functions by name (case-insensitive). They may replace built-in ones. */
40
+ functions?: Record<string, FormulaFunction>;
41
+ }
@@ -0,0 +1,13 @@
1
+ import { FormulaError } from './formula-error.js';
2
+ import { FormulaValue } from './formula-options.if.js';
3
+
4
+ export declare function isBlank(v: FormulaValue): boolean;
5
+ /** A value from the data (a field) as formula value: Date → ms, function/object → #VALUE!. */
6
+ export declare function fromData(v: unknown, name: string, trusted?: boolean): FormulaValue;
7
+ export declare function toNumber(v: FormulaValue): number | FormulaError;
8
+ export declare function toText(v: FormulaValue): string | FormulaError;
9
+ export declare function toBoolean(v: FormulaValue): boolean | FormulaError;
10
+ /** A number result: NaN / ±Infinity → #NUM!, -0 → 0. */
11
+ export declare function numberResult(n: number): number | FormulaError;
12
+ /** Compares two values: numbers numerically, texts case-insensitively, blank = 0 = "" = FALSE. */
13
+ export declare function compareValues(a: FormulaValue, b: FormulaValue): number | FormulaError;
@@ -0,0 +1,18 @@
1
+ import { FormulaValue } from './formula-options.if.js';
2
+
3
+ /** A built-in function with eagerly evaluated arguments (errors are returned before the call). */
4
+ export interface BuiltInFunction {
5
+ readonly min: number;
6
+ readonly max: number;
7
+ readonly fn: (args: FormulaValue[]) => FormulaValue;
8
+ }
9
+ /** Functions with lazily evaluated arguments – handled by the evaluator itself. */
10
+ export declare const LAZY_FUNCTIONS: Record<string, {
11
+ min: number;
12
+ max: number;
13
+ }>;
14
+ /** SUM, AVG … with exactly one field reference: an aggregate over the (filtered) rows of the table. */
15
+ export declare const AGGREGATE_FUNCTIONS: Record<string, "sum" | "avg" | "min" | "max" | "count">;
16
+ /** Rounds half away from zero (like Excel) without binary artefacts: ROUND(1.005, 2) = 1.01. */
17
+ export declare function roundHalfAwayFromZero(x: number, digits: number): number;
18
+ export declare const BUILT_IN_FUNCTIONS: Record<string, BuiltInFunction>;
@@ -0,0 +1,10 @@
1
+ import { FormulaNode } from './formula-ast.if.js';
2
+
3
+ /** The maximum length of a formula (characters). */
4
+ export declare const MAX_FORMULA_LENGTH = 10000;
5
+ /** The maximum nesting depth (parentheses, function calls, unary operators). */
6
+ export declare const MAX_FORMULA_DEPTH = 64;
7
+ /** The maximum number of binary operators (a long chain is a deep tree, too). */
8
+ export declare const MAX_FORMULA_OPERATORS = 1000;
9
+ /** Parses a formula into an AST. Throws a {@link FormulaSyntaxError}. */
10
+ export declare function parseFormula(source: string): FormulaNode;
@@ -0,0 +1,22 @@
1
+ import { FormulaError } from './formula-error.js';
2
+
3
+ /** The kinds of tokens of a formula. */
4
+ export type FormulaTokenKind = "number" | "string" | "field" | "ident" | "op" | "(" | ")" | "," | "eof";
5
+ /** One token: kind, text (number/string already decoded) and position in the source. */
6
+ export interface FormulaToken {
7
+ readonly kind: FormulaTokenKind;
8
+ readonly text: string;
9
+ readonly value?: number;
10
+ readonly pos: number;
11
+ }
12
+ /** Thrown by tokenizer and parser, caught by `compileFormula` – never leaves the formula module. */
13
+ export declare class FormulaSyntaxError extends Error {
14
+ readonly pos: number;
15
+ constructor(message: string, pos: number);
16
+ toFormulaError(): FormulaError;
17
+ }
18
+ /**
19
+ * Splits a formula into tokens. Whitespace is ignored. Throws a {@link FormulaSyntaxError} for an unknown character,
20
+ * an unterminated string or field reference.
21
+ */
22
+ export declare function tokenize(source: string): FormulaToken[];
@@ -1,3 +1,13 @@
1
+ import { RowNumberColumnDef } from './data/common/row-number-column-def.js';
2
+ import { AreaModelAggregateFooter } from './data/tablemodel/areamodel/area-model-aggregate-footer.js';
3
+ import { AreaModelRowGroups } from './data/tablemodel/areamodel/area-model-row-groups.js';
4
+ import { RowGroupIf } from './rowgroup/row-group.if.js';
5
+ import { RowGroupColumnDef } from './rowgroup/row-group-column-def.js';
6
+ import { TreeRowIf } from './data/common/tree-row-if.js';
7
+ import { AreaModelPivot } from './data/tablemodel/areamodel/area-model-pivot.js';
8
+ import { PivotTableModel } from './pivot/pivot-table-model.js';
9
+ import { PivotColumnDef } from './pivot/pivot-column-def.js';
10
+
1
11
  /**
2
12
  * Checks if the given row is a tree row.
3
13
  *
@@ -17,6 +27,16 @@ export declare function isTreeRow(row: any): boolean;
17
27
  * @category Utilities
18
28
  */
19
29
  export declare function isAreaModelTree(model: any): boolean;
30
+ /**
31
+ * True for a {@link CheckboxCellRenderer} – also from another copy of the core (no `instanceof`).
32
+ *
33
+ * @example
34
+ * isCheckboxCellRenderer(new CheckboxCellRenderer()); // true
35
+ *
36
+ * @since 1.1.91
37
+ * @category Utilities
38
+ */
39
+ export declare function isCheckboxCellRenderer(o: any): boolean;
20
40
  /**
21
41
  * Checks if the given object is a CheckboxColumnDef.
22
42
  *
@@ -25,14 +45,131 @@ export declare function isAreaModelTree(model: any): boolean;
25
45
  *
26
46
  * @category Utilities
27
47
  */
48
+ export declare function isCheckboxColumnDef(o: any): boolean;
28
49
  /**
29
- * True for a {@link CheckboxCellRenderer} – also from another copy of the core (no `instanceof`).
50
+ * True for a {@link RowNumberColumnDef} – also from another copy of the core (no `instanceof`).
51
+ *
52
+ * @param {any} o - the object to check, e.g. `tableModel.getColumnDef(0)`
53
+ * @returns {boolean} true for a row number column
30
54
  *
31
55
  * @example
32
- * isCheckboxCellRenderer(new CheckboxCellRenderer()); // true
56
+ * const hasRowNumbers = isRowNumberColumnDef(tableModel.getColumnDef(0));
33
57
  *
34
- * @since 1.1.91
35
- * @category Utilities
58
+ * @since 1.1.93
59
+ * @category Row numbers
36
60
  */
37
- export declare function isCheckboxCellRenderer(o: any): boolean;
38
- export declare function isCheckboxColumnDef(o: any): boolean;
61
+ export declare function isRowNumberColumnDef(o: any): o is RowNumberColumnDef;
62
+ /**
63
+ * True for an {@link AreaModelAggregateFooter} – also from another copy of the core (no `instanceof`).
64
+ *
65
+ * @param {any} o - the object to check, e.g. `tableModel.getAreaModel("footer")`
66
+ * @returns {boolean} true for a footer with totals
67
+ *
68
+ * @example
69
+ * const footer = tableModel.getAreaModel("footer");
70
+ * const totals = isAreaModelAggregateFooter(footer) ? footer.getResults() : {};
71
+ *
72
+ * @since 1.1.94
73
+ * @category Aggregation
74
+ */
75
+ export declare function isAreaModelAggregateFooter(o: any): o is AreaModelAggregateFooter;
76
+ /**
77
+ * True for a group of a row grouping ({@link RowGroupIf}) – the `data` of a group row. Works across copies of the core.
78
+ *
79
+ * @param {any} o - the object to check, e.g. `treeRow.data`
80
+ * @returns {boolean} true for a group
81
+ *
82
+ * @example
83
+ * const row = tableModel.getBodyModel().getRowByIndex(rowIndex);
84
+ * if (isTreeRow(row) && isRowGroup(row.data)) console.log(row.data.label, row.data.count);
85
+ *
86
+ * @since 1.1.94
87
+ * @category Row grouping
88
+ */
89
+ export declare function isRowGroup(o: any): o is RowGroupIf;
90
+ /**
91
+ * True for a group row of a row grouping: a tree row whose `data` is a {@link RowGroupIf} (detail rows hold your objects).
92
+ *
93
+ * @param {any} row - a body row, e.g. `tableModel.getBodyModel().getRowByIndex(rowIndex)` or `mouseEvent.row`
94
+ * @returns {boolean} true for a group row
95
+ *
96
+ * @example
97
+ * const eventListener = new EventAdapter();
98
+ * eventListener.onMouseClicked = (evt: GeMouseEvent) => {
99
+ * const row = tableModel.getBodyModel().getRowByIndex(evt.rowIndex);
100
+ * if (isGroupRow(row)) console.log("group", row.data.path);
101
+ * };
102
+ *
103
+ * @since 1.1.94
104
+ * @category Row grouping
105
+ */
106
+ export declare function isGroupRow(row: any): row is TreeRowIf<RowGroupIf>;
107
+ /**
108
+ * True for the body model of a row grouping ({@link AreaModelRowGroups}). It is a tree as well
109
+ * (`isAreaModelTree` is true). Works across copies of the core.
110
+ *
111
+ * @param {any} o - the object to check, e.g. `tableModel.getBodyModel()`
112
+ * @returns {boolean} true for a row grouping
113
+ *
114
+ * @example
115
+ * const body = tableModel.getBodyModel();
116
+ * const groups = isAreaModelRowGroups(body) ? body.getGroups() : [];
117
+ *
118
+ * @since 1.1.94
119
+ * @category Row grouping
120
+ */
121
+ export declare function isAreaModelRowGroups(o: any): o is AreaModelRowGroups;
122
+ /**
123
+ * True for the group column of a row grouping ({@link RowGroupColumnDef}). Works across copies of the core.
124
+ *
125
+ * @param {any} o - the object to check, e.g. a column definition
126
+ * @returns {boolean} true for the group column
127
+ *
128
+ * @example
129
+ * const groupColumnIndex = (tableModel.getColumnDefs() ?? []).findIndex(isRowGroupColumnDef);
130
+ *
131
+ * @since 1.1.94
132
+ * @category Row grouping
133
+ */
134
+ export declare function isRowGroupColumnDef(o: any): o is RowGroupColumnDef;
135
+ /**
136
+ * True for the table model of a pivot table ({@link PivotTableModel}). Works across copies of the core.
137
+ *
138
+ * @param {any} o - the object to check, e.g. `tableApi.getTableModel()`
139
+ * @returns {boolean} true for a pivot table
140
+ *
141
+ * @example
142
+ * const model = tableApi.getTableModel();
143
+ * const config = isPivotTableModel(model) ? model.getPivotConfig() : undefined;
144
+ *
145
+ * @since 1.1.94
146
+ * @category Pivot
147
+ */
148
+ export declare function isPivotTableModel(o: any): o is PivotTableModel;
149
+ /**
150
+ * True for the body of a pivot table ({@link AreaModelPivot}). Works across copies of the core.
151
+ *
152
+ * @param {any} o - the object to check, e.g. `tableModel.getBodyModel()`
153
+ * @returns {boolean} true for a pivot body
154
+ *
155
+ * @example
156
+ * const body = tableModel.getBodyModel();
157
+ * const total = isAreaModelPivot(body) ? pivotBody.getResult().getValue() : undefined;
158
+ *
159
+ * @since 1.1.94
160
+ * @category Pivot
161
+ */
162
+ export declare function isAreaModelPivot(o: any): o is AreaModelPivot;
163
+ /**
164
+ * True for a value column of a pivot table ({@link PivotColumnDef}). Works across copies of the core.
165
+ *
166
+ * @param {any} o - the object to check, e.g. a column definition
167
+ * @returns {boolean} true for a value, subtotal or total column of a pivot
168
+ *
169
+ * @example
170
+ * const valueColumns = (tableModel.getColumnDefs() ?? []).filter(isPivotColumnDef);
171
+ *
172
+ * @since 1.1.94
173
+ * @category Pivot
174
+ */
175
+ export declare function isPivotColumnDef(o: any): o is PivotColumnDef;
@@ -0,0 +1,9 @@
1
+ import { AreaModelCellGroups } from '../data/tablemodel/areamodel/area-model-cell-groups.js';
2
+
3
+ /**
4
+ * The header of a pivot table: header groups with classes for the labels – column groups (`2026`, `Jan`) start at the
5
+ * left of their span (a wide group stays readable), column labels (`Q1`, `Revenue`) sit above their numbers.
6
+ */
7
+ export declare class AreaModelPivotHeader extends AreaModelCellGroups {
8
+ getCustomClassesAt(rowIndex: number, columnIndex: number): string[];
9
+ }
@@ -0,0 +1,28 @@
1
+ import { ColumnDef } from '../data/tablemodel/column/column-def.js';
2
+ import { SizeIf } from '../data/common/size.if.js';
3
+ import { PivotColumnInfoIf } from './pivot-column-info.if.js';
4
+
5
+ /**
6
+ * A value column of a pivot table – created by {@link PivotFactory} (you don't create them yourself). Its property is
7
+ * stable for the same column key and value (`pivot:[["monat","s:Jan"],"sum(umsatz)"]`), so widths and sorting are
8
+ * remembered like for any column; {@link AreaModelPivot.getColumnProperty} builds it for you.
9
+ *
10
+ * @example
11
+ * const columns = tableModel.getColumnDefs()?.filter(isPivotColumnDef) ?? [];
12
+ * columns.map(c => c.pivot.kind); // ["value", "value", "total"]
13
+ *
14
+ * @since 1.1.94
15
+ * @category Pivot
16
+ */
17
+ export declare class PivotColumnDef extends ColumnDef {
18
+ readonly pivot: PivotColumnInfoIf;
19
+ /** Marker for {@link isPivotColumnDef} (works across copies of the core). */
20
+ readonly type = "PivotColumnDef";
21
+ /**
22
+ * @param {string} property - the stable property
23
+ * @param {string} headerLabel - the label in the lowest header row
24
+ * @param {PivotColumnInfoIf} pivot - what the column shows
25
+ * @param {SizeIf} [width] - the width (default 100 px)
26
+ */
27
+ constructor(property: string, headerLabel: string, pivot: PivotColumnInfoIf, width?: SizeIf);
28
+ }
@@ -0,0 +1,25 @@
1
+ import { RowGroupIf } from '../rowgroup/row-group.if.js';
2
+ import { PivotValueInfoIf } from './pivot-value.type.js';
3
+
4
+ /**
5
+ * What a value column of a pivot table shows ({@link AreaModelPivot.getColumnInfo}): the values of one column key
6
+ * (`"value"`), the subtotal of a column group (`"subtotal"`, with {@link PivotConfigIf.columnSubtotals}) or the
7
+ * total over all column keys (`"total"`).
8
+ *
9
+ * @example
10
+ * const info = pivotModel.getPivotBody().getColumnInfo(columnIndex);
11
+ * if (info?.kind === "value") console.log(info.column?.path, info.value.name); // ["Jan"], "sum(umsatz)"
12
+ *
13
+ * @since 1.1.94
14
+ * @category Pivot
15
+ */
16
+ export interface PivotColumnInfoIf {
17
+ /** `"value"` – one column key, `"subtotal"` – a column group, `"total"` – all columns. */
18
+ readonly kind: "value" | "subtotal" | "total";
19
+ /** The column key (lowest level) or column group; undefined for the total. */
20
+ readonly column?: RowGroupIf;
21
+ /** The value shown in the column. */
22
+ readonly value: PivotValueInfoIf;
23
+ /** The index of the value in {@link PivotConfigIf.values}. */
24
+ readonly valueIndex: number;
25
+ }
@@ -0,0 +1,58 @@
1
+ import { RowGroupField } from '../rowgroup/row-group-field.type.js';
2
+ import { RowGroupExpanded } from '../rowgroup/row-group-model-options.if.js';
3
+ import { PivotValue } from './pivot-value.type.js';
4
+
5
+ /**
6
+ * What a pivot table shows: the row fields (grouped like a row grouping), the column fields (their values become
7
+ * columns) and the values (aggregated per row × column), plus subtotals and totals. Used by
8
+ * {@link PivotFactory.createTableModel}, {@link pivotRows} and {@link TableApi.setPivotConfig}.
9
+ *
10
+ * Fields have the form of a row grouping level ({@link RowGroupField}): a property path, a function (e.g. the quarter
11
+ * of a date) or {@link RowGroupFieldIf} with `label`, `format` and `order` – `groupBy` of a row grouping works as
12
+ * `rowFields`.
13
+ *
14
+ * @example
15
+ * const config: PivotConfigIf<Sale> = {
16
+ * rowFields: ["region", "produkt"],
17
+ * columnFields: [{ value: "monat", order: "insertion" }], // Jan before Feb (order in the data)
18
+ * values: ["umsatz"], // sum of umsatz
19
+ * emptyText: "–"
20
+ * };
21
+ *
22
+ * @typeParam T - the row type
23
+ * @since 1.1.94
24
+ * @category Pivot
25
+ */
26
+ export interface PivotConfigIf<T = any> {
27
+ /** The row levels, top first. Several levels form a hierarchy with subtotals. An empty list shows one total row. */
28
+ rowFields: RowGroupField<T>[];
29
+ /** The fields whose values become columns, top first. Several fields form a multi-row header. Default `[]` (totals only). */
30
+ columnFields?: RowGroupField<T>[];
31
+ /** The aggregated values (at least one): `"umsatz"` (sum) or {@link PivotValueIf}. With several values every column key gets one column per value. */
32
+ values: PivotValue<T>[];
33
+ /** Show the aggregates in the group rows (subtotals). Default true. */
34
+ subtotals?: boolean;
35
+ /**
36
+ * A total column behind every column group (e.g. "2026 Total" behind its quarters); the group gets a toggle and,
37
+ * when collapsed, shows only its total. Default: true with two or more column fields.
38
+ */
39
+ columnSubtotals?: boolean;
40
+ /** The total column(s) on the right: `"fixed"` (default, fixed on the right), `true` (last columns, scrolled) or `false`. */
41
+ totalColumn?: boolean | "fixed";
42
+ /** The total row in the footer. Default true. */
43
+ totalRow?: boolean;
44
+ /**
45
+ * The maximum number of column keys (of the lowest column level). More keys: the first ones are shown, a warning is
46
+ * logged and {@link PivotResult.truncated} is true – total column, subtotal columns and total row still count all rows.
47
+ * Default 1000.
48
+ */
49
+ maxColumns?: number;
50
+ /** Expanded row groups: `true` (default), `false`, open levels as a number (`0` = all closed) or a function per group. */
51
+ expanded?: RowGroupExpanded<T>;
52
+ /** The label of empty keys (`null`, `undefined`, `""`) – rows and columns. Default `"(empty)"`. */
53
+ emptyLabel?: string;
54
+ /** The text of a cell without data (the value stays `undefined`, not 0). Default `""`. */
55
+ emptyText?: string;
56
+ /** The word for totals: header of the total column, label of the total row, suffix of subtotal columns. Default `"Total"`. */
57
+ totalLabel?: string;
58
+ }
@@ -0,0 +1,13 @@
1
+ import { PivotValue, PivotValueInfoIf } from './pivot-value.type.js';
2
+
3
+ /** A value resolved for a pass over the rows. */
4
+ export interface ResolvedPivotValue<T = any> extends PivotValueInfoIf {
5
+ /** undefined for `count` (the value does not matter) */
6
+ readonly getValue?: (row: T) => unknown;
7
+ }
8
+ /** The default maximum number of column keys. */
9
+ export declare const DEFAULT_MAX_COLUMNS = 1000;
10
+ /** The default word for totals. */
11
+ export declare const DEFAULT_TOTAL_LABEL = "Total";
12
+ /** Resolves the values of a pivot configuration: aggregator, getter, unique name, label. */
13
+ export declare function resolvePivotValues<T>(values: PivotValue<T>[] | undefined): ResolvedPivotValue<T>[];
@@ -0,0 +1,40 @@
1
+ import { ColumnDefIf } from '../data/tablemodel/column/column-def.if.js';
2
+ import { CellGroupIf } from '../data/tablemodel/cellgroup/cell-group.if.js';
3
+ import { SizeIf } from '../data/common/size.if.js';
4
+ import { RowGroup } from '../rowgroup/row-group.js';
5
+ import { PivotConfigIf } from './pivot-config.if.js';
6
+ import { PivotResult } from './pivot-result.js';
7
+ import { PivotValueInfoIf } from './pivot-value.type.js';
8
+ import { RowGroupField } from '../rowgroup/row-group-field.type.js';
9
+
10
+ /** Columns, header groups and fixed right columns of a pivot. */
11
+ export interface PivotLayout {
12
+ /** leading columns (row numbers, group column) + value columns + total columns */
13
+ columnDefs: ColumnDefIf[];
14
+ /** the header groups, one leaf per column in the same order */
15
+ cellGroups: CellGroupIf[];
16
+ /** the number of total columns fixed on the right */
17
+ fixedRightColumnCount: number;
18
+ }
19
+ export interface PivotLayoutOptions {
20
+ /** width of a value column (default 100 px) */
21
+ valueWidth?: SizeIf;
22
+ /** ids of collapsed column groups (kept when the layout is built again) */
23
+ closedIds?: ReadonlySet<string>;
24
+ /** the widths of existing columns by property (kept when the layout is built again) */
25
+ widths?: ReadonlyMap<string, SizeIf>;
26
+ }
27
+ /** The property of a value column: column path + value name. */
28
+ export declare function pivotValueProperty(column: RowGroup, value: PivotValueInfoIf): string;
29
+ /** The property of a subtotal column of a column group. */
30
+ export declare function pivotSubtotalProperty(column: RowGroup, value: PivotValueInfoIf): string;
31
+ /** The property of a total column. */
32
+ export declare function pivotTotalProperty(value: PivotValueInfoIf): string;
33
+ /** The default name of a field path in a header: the last part, first letter upper case ("address.city" → "City"). */
34
+ export declare function humanizePath(path: string): string;
35
+ /** The header of the group column of a pivot: the row field labels, e.g. "Region › Produkt" ("" without row fields). */
36
+ export declare function pivotGroupHeaderLabel(rowFields: RowGroupField[]): string;
37
+ /** True if the subtotal columns are on (default: two or more column fields). */
38
+ export declare function hasColumnSubtotals(config: PivotConfigIf): boolean;
39
+ /** Builds the columns and the grouped header of a pivot. */
40
+ export declare function buildPivotLayout<T>(result: PivotResult<T>, config: PivotConfigIf<T>, leading: ColumnDefIf[], options?: PivotLayoutOptions): PivotLayout;
@@ -0,0 +1,157 @@
1
+ import { PivotConfigIf } from './pivot-config.if.js';
2
+ import { RowGroupIf } from '../rowgroup/row-group.if.js';
3
+ import { RowGroup } from '../rowgroup/row-group.js';
4
+ import { PivotValueInfoIf } from './pivot-value.type.js';
5
+
6
+ /**
7
+ * The result of a pivot ({@link pivotRows}, {@link AreaModelPivot.getResult}): the row and column hierarchies and the
8
+ * aggregated value of every combination – cells, subtotals and totals. DOM-free; the table reads its cells from here.
9
+ *
10
+ * - `getValue(row, column)` – a cell; leave out `row` for the column total, `column` for the row total, both for the
11
+ * grand total. Groups of higher levels give subtotals.
12
+ * - A combination without rows is `undefined` (not 0).
13
+ * - Every cell is computed from the rows (leaf cells) or by merging aggregation **states** – an average of a region is
14
+ * the average of its rows, never the average of the product averages. Order of the merges: first along the columns
15
+ * (column groups), then along the rows (row groups, total row) – children in key order. This matters for
16
+ * `first`/`last` only: a row total adds its rows in source order, a column group merges its keys in key order, so
17
+ * the two may differ. Keys cut off by `maxColumns` still count in subtotals and totals.
18
+ *
19
+ * @example
20
+ * const result = pivotRows(sales, { rowFields: ["region"], columnFields: ["monat"], values: ["umsatz"] });
21
+ * const nord = result.rowGroups[0]; // Nord
22
+ * const jan = result.columnLeaves.find(c => c.key === "Jan");
23
+ * result.getValue(nord, jan); // 150
24
+ * result.getValue(nord); // 270 – the row total
25
+ * result.getValue(undefined, jan); // 230 – the column total
26
+ * result.getValue(); // 450
27
+ *
28
+ * @typeParam T - the row type
29
+ * @since 1.1.94
30
+ * @category Pivot
31
+ */
32
+ export declare class PivotResult<T = any> {
33
+ /** @internal the source rows */
34
+ readonly source: ArrayLike<T>;
35
+ /** The row groups of the top level (with sub-groups); empty without row fields. */
36
+ readonly rowGroups: RowGroup<T>[];
37
+ /** The column groups of the top level (with sub-groups); empty without column fields. */
38
+ readonly columnGroups: RowGroup<T>[];
39
+ /** The shown column keys of the lowest level in display order – at most {@link PivotConfigIf.maxColumns}. */
40
+ readonly columnLeaves: RowGroup<T>[];
41
+ /** The values (name, label, aggregator, format). */
42
+ readonly values: readonly PivotValueInfoIf[];
43
+ /** True if there were more column keys than {@link PivotConfigIf.maxColumns} (the rest is not shown as columns). */
44
+ readonly truncated: boolean;
45
+ /** the lowest column key (index into allColumnLeaves) of every source row, -1: no column fields */
46
+ private readonly columnLeafOf;
47
+ /** all column keys of the lowest level, also the ones cut off by maxColumns (they count in subtotals) */
48
+ private readonly allColumnLeaves;
49
+ /** shown column groups (all levels) */
50
+ private readonly shownColumns;
51
+ /** non-leaf column groups (shown or not), deepest first */
52
+ private readonly columnParentsPostOrder;
53
+ /** non-leaf row groups, deepest first */
54
+ private readonly rowParentsPostOrder;
55
+ /** row leaves in display order */
56
+ private readonly rowLeaves;
57
+ private cells;
58
+ /** the values with their getters */
59
+ private readonly resolved;
60
+ private accept?;
61
+ /**
62
+ * Groups the rows by the row and column fields and aggregates the values. Use {@link pivotRows}.
63
+ *
64
+ * @param {ArrayLike<T>} source - the rows (not changed)
65
+ * @param {PivotConfigIf<T>} config - fields and values
66
+ * @param {(sourceIndex: number) => boolean} [accept] - a filter: only rows it accepts count
67
+ */
68
+ constructor(
69
+ /** @internal the source rows */
70
+ source: ArrayLike<T>, config: PivotConfigIf<T>, accept?: (sourceIndex: number) => boolean);
71
+ /**
72
+ * Computes all cells again (same keys) – after a filter change or changed values.
73
+ *
74
+ * @param {(sourceIndex: number) => boolean} [accept] - a filter: only rows it accepts count
75
+ *
76
+ * @example
77
+ * result.compute(i => sales[i].monat === "Jan");
78
+ * result.getValue(); // 230
79
+ */
80
+ compute(accept?: (sourceIndex: number) => boolean): void;
81
+ /**
82
+ * The aggregated value of a cell, a subtotal or a total.
83
+ *
84
+ * @param {RowGroupIf<T>} [row] - a row group (any level); undefined = all rows (column totals)
85
+ * @param {RowGroupIf<T>} [column] - a column key or column group (any level); undefined = all columns (row totals)
86
+ * @param {number | string} [value=0] - the index or name of the value
87
+ * @returns {unknown} the result, `undefined` if no row has this combination
88
+ *
89
+ * @example
90
+ * result.getValue(result.rowGroups[0], undefined, "sum(umsatz)"); // the total of the first row group
91
+ */
92
+ getValue(row?: RowGroupIf<T>, column?: RowGroupIf<T>, value?: number | string): unknown;
93
+ /**
94
+ * The number of rows of a cell, a subtotal or a total (after the filter).
95
+ *
96
+ * @param {RowGroupIf<T>} [row] - a row group; undefined = all rows
97
+ * @param {RowGroupIf<T>} [column] - a column key or group; undefined = all columns
98
+ * @returns {number} the row count, 0 for a combination without rows
99
+ *
100
+ * @example
101
+ * result.getCount(result.rowGroups[0]); // 3 – the rows of Nord
102
+ */
103
+ getCount(row?: RowGroupIf<T>, column?: RowGroupIf<T>): number;
104
+ /**
105
+ * The rows behind a cell (drill-down), after the filter, in source order.
106
+ *
107
+ * @param {RowGroupIf<T>} [row] - a row group; undefined = all rows
108
+ * @param {RowGroupIf<T>} [column] - a column key or group; undefined = all columns
109
+ * @returns {T[]} a new array
110
+ *
111
+ * @example
112
+ * result.getSourceRows(nord, jan).map(s => s.umsatz); // [100, 50]
113
+ */
114
+ getSourceRows(row?: RowGroupIf<T>, column?: RowGroupIf<T>): T[];
115
+ /**
116
+ * True if a column group is shown – false for groups whose keys were all cut off by `maxColumns`.
117
+ *
118
+ * @param {RowGroupIf<T>} column - a column group
119
+ * @returns {boolean} true if it has at least one shown column key
120
+ */
121
+ isColumnShown(column: RowGroupIf<T>): boolean;
122
+ /** @internal the index of a value (by index or name), -1 if unknown */
123
+ valueIndex(value: number | string): number;
124
+ private cell;
125
+ private newCell;
126
+ /** One pass over the rows of a row leaf: the cells per column key and the row total, then the column groups. */
127
+ private leafCells;
128
+ private mergeInto;
129
+ private mergeMap;
130
+ }
131
+ /**
132
+ * Pivots rows: groups them by the row fields and by the column fields and aggregates the values of every combination,
133
+ * with subtotals and totals – the engine behind {@link PivotFactory} (DOM-free, also usable without a table). One pass
134
+ * over the rows; empty combinations are `undefined`, averages are computed from sum and count.
135
+ *
136
+ * @param {ArrayLike<T>} rows - the rows (not changed)
137
+ * @param {PivotConfigIf<T>} config - row fields, column fields, values (see {@link PivotConfigIf})
138
+ * @param {(sourceIndex: number) => boolean} [accept] - a filter: only rows it accepts count (index into `rows`)
139
+ * @returns {PivotResult<T>} the hierarchies and the values
140
+ *
141
+ * @example
142
+ * // case 1: regions × months, sum of umsatz
143
+ * const result = pivotRows(sales, { rowFields: ["region"], columnFields: ["monat"], values: ["umsatz"] });
144
+ * result.rowGroups.map(r => `${r.label}: ${result.getValue(r)}`); // ["Nord: 270", "Süd: 180"]
145
+ * result.getValue(); // 450
146
+ *
147
+ * @example
148
+ * // case 3: the average of a column total is the average of its rows
149
+ * const avg = pivotRows(sales, { rowFields: ["region"], columnFields: ["monat"],
150
+ * values: [{ value: "umsatz", aggregator: "avg" }] });
151
+ * const jan = avg.columnLeaves.find(c => c.key === "Jan");
152
+ * avg.getValue(undefined, jan); // 76.666… (230 / 3) – not 77.5, the mean of 75 and 80
153
+ *
154
+ * @since 1.1.94
155
+ * @category Pivot
156
+ */
157
+ export declare function pivotRows<T = any>(rows: ArrayLike<T>, config: PivotConfigIf<T>, accept?: (sourceIndex: number) => boolean): PivotResult<T>;