@kanunilabs/pivotgrid-core 1.0.0
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/LICENSE +55 -0
- package/README.md +48 -0
- package/dist/export.worker.cjs +24 -0
- package/dist/export.worker.d.cts +2 -0
- package/dist/export.worker.d.ts +2 -0
- package/dist/export.worker.js +24 -0
- package/dist/import.worker.cjs +3 -0
- package/dist/import.worker.d.cts +2 -0
- package/dist/import.worker.d.ts +2 -0
- package/dist/import.worker.js +3 -0
- package/dist/index.cjs +60 -0
- package/dist/index.d.cts +787 -0
- package/dist/index.d.ts +787 -0
- package/dist/index.js +60 -0
- package/dist/pivot.worker-DQFl4fMu.d.cts +1001 -0
- package/dist/pivot.worker-DQFl4fMu.d.ts +1001 -0
- package/dist/pivot.worker.cjs +1 -0
- package/dist/pivot.worker.d.cts +1 -0
- package/dist/pivot.worker.d.ts +1 -0
- package/dist/pivot.worker.js +1 -0
- package/package.json +70 -0
|
@@ -0,0 +1,1001 @@
|
|
|
1
|
+
interface PivotPlugin {
|
|
2
|
+
id: string;
|
|
3
|
+
version?: string;
|
|
4
|
+
type: 'expression' | 'summary' | 'sort' | 'custom' | 'exporter' | 'cellRender' | 'aggregator' | 'headerRender' | 'toolbar';
|
|
5
|
+
execute?: Function;
|
|
6
|
+
workerCode?: string;
|
|
7
|
+
exportFunction?: (data: any[], options: any) => Promise<void>;
|
|
8
|
+
renderCell?: (value: any, displayValue: string, cellContext: any, field: any) => any;
|
|
9
|
+
renderHeader?: (field: any, defaultLabel: string) => any;
|
|
10
|
+
aggregate?: (values: number[]) => number;
|
|
11
|
+
}
|
|
12
|
+
declare class PivotEngineRegistry {
|
|
13
|
+
private plugins;
|
|
14
|
+
/**
|
|
15
|
+
* Registers a new plugin into this instance.
|
|
16
|
+
* If a plugin with the same ID exists, it issues a warning before overwriting.
|
|
17
|
+
*/
|
|
18
|
+
register(plugin: PivotPlugin): void;
|
|
19
|
+
/**
|
|
20
|
+
* Unregisters a plugin.
|
|
21
|
+
*/
|
|
22
|
+
unregister(id: string): void;
|
|
23
|
+
/**
|
|
24
|
+
* Retrieves a plugin by its ID.
|
|
25
|
+
*/
|
|
26
|
+
get(id: string): PivotPlugin | undefined;
|
|
27
|
+
/**
|
|
28
|
+
* Retrieves all plugins of a specific type.
|
|
29
|
+
*/
|
|
30
|
+
getPluginsByType(type: PivotPlugin['type']): PivotPlugin[];
|
|
31
|
+
/**
|
|
32
|
+
* Safe getter that logs a warning and returns a fallback mock if the plugin is missing.
|
|
33
|
+
* This guarantees that UI loops do not crash.
|
|
34
|
+
*/
|
|
35
|
+
resolveSafe(id: string, fallbackType: 'expression' | 'summary'): Function;
|
|
36
|
+
/**
|
|
37
|
+
* Returns a snapshot of plugins that have worker code, ready for Worker Bootstrap.
|
|
38
|
+
*/
|
|
39
|
+
getWorkerBootstrapPayload(): Pick<PivotPlugin, 'id' | 'type' | 'workerCode'>[];
|
|
40
|
+
/**
|
|
41
|
+
* Register a custom aggregator function (e.g., median, weighted average).
|
|
42
|
+
* Used by the engine when summaryType === 'custom' and field references this aggregator.
|
|
43
|
+
*/
|
|
44
|
+
registerAggregator(id: string, aggregateFn: (values: number[]) => number, version?: string): void;
|
|
45
|
+
/**
|
|
46
|
+
* Register a custom export format plugin.
|
|
47
|
+
* The exportFunction receives the data array and an options bag with fields, layout, etc.
|
|
48
|
+
*/
|
|
49
|
+
registerExporter(id: string, exportFn: (data: any[], options: any) => Promise<void>, version?: string): void;
|
|
50
|
+
/**
|
|
51
|
+
* Register a custom cell renderer plugin.
|
|
52
|
+
* Applied globally to cells matching the plugin criteria.
|
|
53
|
+
*/
|
|
54
|
+
registerCellRenderer(id: string, renderFn: (value: any, displayValue: string, cellContext: any, field: any) => any, version?: string): void;
|
|
55
|
+
/**
|
|
56
|
+
* Register a custom header renderer plugin.
|
|
57
|
+
*/
|
|
58
|
+
registerHeaderRenderer(id: string, renderFn: (field: any, defaultLabel: string) => any, version?: string): void;
|
|
59
|
+
/** Get all registered custom exporters. */
|
|
60
|
+
getExporters(): PivotPlugin[];
|
|
61
|
+
/** Get all registered cell renderers. */
|
|
62
|
+
getCellRenderers(): PivotPlugin[];
|
|
63
|
+
/** Get all registered aggregators. */
|
|
64
|
+
getAggregators(): PivotPlugin[];
|
|
65
|
+
/** Get all registered header renderers. */
|
|
66
|
+
getHeaderRenderers(): PivotPlugin[];
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** Message sent to the worker to initialize the engine with columnar data. */
|
|
70
|
+
interface WorkerInitRequest {
|
|
71
|
+
action: 'init';
|
|
72
|
+
id: string;
|
|
73
|
+
rowCount: number;
|
|
74
|
+
columnarData: Record<string, {
|
|
75
|
+
type: 'int32' | 'float64';
|
|
76
|
+
buffer: ArrayBuffer;
|
|
77
|
+
}>;
|
|
78
|
+
dictionary: string[];
|
|
79
|
+
rowFields: PivotField<any>[];
|
|
80
|
+
colFields: PivotField<any>[];
|
|
81
|
+
dataFields: PivotField<any>[];
|
|
82
|
+
workerBootstrap?: {
|
|
83
|
+
id: string;
|
|
84
|
+
type: string;
|
|
85
|
+
workerCode: string;
|
|
86
|
+
}[];
|
|
87
|
+
/**
|
|
88
|
+
* Skip the initial unfiltered build. Used by the worker pipeline, where a
|
|
89
|
+
* filter request (which rebuilds) always follows init — avoids building the
|
|
90
|
+
* tries twice. compute() self-heals if no build happened yet.
|
|
91
|
+
*/
|
|
92
|
+
deferBuild?: boolean;
|
|
93
|
+
}
|
|
94
|
+
interface WorkerFilterSpec {
|
|
95
|
+
fieldId: string;
|
|
96
|
+
filterType: 'include' | 'exclude';
|
|
97
|
+
dictIds: number[];
|
|
98
|
+
}
|
|
99
|
+
interface PrefilterConditionSpec {
|
|
100
|
+
fieldId: string;
|
|
101
|
+
operator: string;
|
|
102
|
+
value: string | number | boolean | null | undefined | (string | number | boolean | null | undefined)[];
|
|
103
|
+
}
|
|
104
|
+
interface PrefilterGroupSpec {
|
|
105
|
+
logicalOperator: 'and' | 'or';
|
|
106
|
+
conditions: (PrefilterConditionSpec | PrefilterGroupSpec)[];
|
|
107
|
+
}
|
|
108
|
+
interface WorkerFilterRequest {
|
|
109
|
+
action: 'filter';
|
|
110
|
+
id: string;
|
|
111
|
+
filters: WorkerFilterSpec[];
|
|
112
|
+
prefilter?: PrefilterGroupSpec;
|
|
113
|
+
}
|
|
114
|
+
interface WorkerComputeRequest {
|
|
115
|
+
action: 'compute';
|
|
116
|
+
id: string;
|
|
117
|
+
expandedPaths: string[];
|
|
118
|
+
expandedColPaths: string[];
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Include/exclude filter carried INTO the incremental init pipeline as raw
|
|
122
|
+
* value strings. The worker resolves them to dictionary ids incrementally as
|
|
123
|
+
* dictionary chunks arrive (a value string that is not yet in the dictionary
|
|
124
|
+
* cannot match any row of the chunks seen so far, so per-chunk resolution is
|
|
125
|
+
* exact).
|
|
126
|
+
*/
|
|
127
|
+
interface WorkerInitFilterSpec {
|
|
128
|
+
fieldId: string;
|
|
129
|
+
filterType: 'include' | 'exclude';
|
|
130
|
+
valueStrings: string[];
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Opens an incremental (chunked) init pipeline. Column buffers arrive via
|
|
134
|
+
* {@link WorkerInitChunkRequest} and are grouped/aggregated as they arrive,
|
|
135
|
+
* overlapping worker-side build with main-thread encoding. Filters are
|
|
136
|
+
* applied during the build (no separate rebuild needed afterwards). The final
|
|
137
|
+
* engine state is identical to a monolithic init + applyFilter.
|
|
138
|
+
*/
|
|
139
|
+
interface WorkerInitStartRequest {
|
|
140
|
+
action: 'initStart';
|
|
141
|
+
id: string;
|
|
142
|
+
rowCountTotal: number;
|
|
143
|
+
/** Column kind per field id — full-size arrays are preallocated up front. */
|
|
144
|
+
columnTypes: Record<string, 'int32' | 'float64'>;
|
|
145
|
+
/** Initial dictionary (index 0 = ''); the rest arrives via chunk appends. */
|
|
146
|
+
dictionary: string[];
|
|
147
|
+
rowFields: PivotField<any>[];
|
|
148
|
+
colFields: PivotField<any>[];
|
|
149
|
+
dataFields: PivotField<any>[];
|
|
150
|
+
filters?: WorkerInitFilterSpec[];
|
|
151
|
+
prefilter?: PrefilterGroupSpec;
|
|
152
|
+
workerBootstrap?: {
|
|
153
|
+
id: string;
|
|
154
|
+
type: string;
|
|
155
|
+
workerCode: string;
|
|
156
|
+
}[];
|
|
157
|
+
}
|
|
158
|
+
interface WorkerInitChunkRequest {
|
|
159
|
+
action: 'initChunk';
|
|
160
|
+
id: string;
|
|
161
|
+
start: number;
|
|
162
|
+
end: number;
|
|
163
|
+
columns: Record<string, ArrayBuffer>;
|
|
164
|
+
/** Dictionary entries appended (in order) since the previous message. */
|
|
165
|
+
dictionaryAppend?: string[];
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Reassigns field roles (row/column/data) over the columnar data already
|
|
169
|
+
* stored in the worker — the fast path for field drag & drop. The raw data is
|
|
170
|
+
* NOT re-encoded or re-transferred; only missing columns (fields entering an
|
|
171
|
+
* area for the first time, or whose encoding definition changed) are shipped
|
|
172
|
+
* via `newColumns` together with any dictionary entries appended while
|
|
173
|
+
* encoding them.
|
|
174
|
+
*/
|
|
175
|
+
interface WorkerReconfigureRequest {
|
|
176
|
+
action: 'reconfigure';
|
|
177
|
+
id: string;
|
|
178
|
+
rowFields: PivotField<any>[];
|
|
179
|
+
colFields: PivotField<any>[];
|
|
180
|
+
dataFields: PivotField<any>[];
|
|
181
|
+
/** Freshly encoded columns to merge into stored columnar data. */
|
|
182
|
+
newColumns?: Record<string, {
|
|
183
|
+
type: 'int32' | 'float64';
|
|
184
|
+
buffer: ArrayBuffer;
|
|
185
|
+
}>;
|
|
186
|
+
/** Dictionary entries appended (in order) since the worker's dictionary was last synced. */
|
|
187
|
+
dictionaryAppend?: string[];
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Flat cell matrix returned by the engine.
|
|
191
|
+
* `keys[i]` = `rowId * MAX_C + colId` hash; `sums[i * numDF + df]` = finalized aggregated value.
|
|
192
|
+
*/
|
|
193
|
+
interface FlatCellMatrix {
|
|
194
|
+
keys: Float64Array;
|
|
195
|
+
/** Finalized values per cell per data field (sum, avg, min, max, count, or distinct count). */
|
|
196
|
+
sums: Float64Array;
|
|
197
|
+
counts: Int32Array;
|
|
198
|
+
/** Post-processed display values after summary display modes are applied. */
|
|
199
|
+
displaySums?: Float64Array;
|
|
200
|
+
}
|
|
201
|
+
interface WorkerResponse {
|
|
202
|
+
id: string;
|
|
203
|
+
rowTree: PivotNode[];
|
|
204
|
+
colTree: PivotNode[];
|
|
205
|
+
cellMatrix: FlatCellMatrix;
|
|
206
|
+
rowIndexMap: Record<string, number>;
|
|
207
|
+
columnIndexMap: Record<string, number>;
|
|
208
|
+
cardinalityMap: Record<string, number>;
|
|
209
|
+
/** Monotonic version of the trie build that produced the index maps. */
|
|
210
|
+
indexMapsVersion?: number;
|
|
211
|
+
/**
|
|
212
|
+
* Wire-level flag: index/cardinality maps were omitted because they are
|
|
213
|
+
* unchanged since the previous compute response; the receiver must reuse
|
|
214
|
+
* its cached copies.
|
|
215
|
+
*/
|
|
216
|
+
indexMapsOmitted?: boolean;
|
|
217
|
+
error?: string;
|
|
218
|
+
isInitComplete?: boolean;
|
|
219
|
+
isFilterComplete?: boolean;
|
|
220
|
+
isReconfigureComplete?: boolean;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* TypedArray-based pivot computation engine designed to run inside a Web Worker.
|
|
224
|
+
*
|
|
225
|
+
* Pipelines: monolithic `init()` → `applyFilter()` → `compute()`, or the
|
|
226
|
+
* chunked `initStart()` → `initChunk()`× → `initEnd()` → `compute()` (filters
|
|
227
|
+
* applied during the chunked build; result state is identical).
|
|
228
|
+
* Uses {@link FastTrie} for hierarchical grouping and pre-aggregates leaf groups
|
|
229
|
+
* into flat TypedArrays supporting SUM, COUNT, AVG, MIN, MAX, and DISTINCT.
|
|
230
|
+
*/
|
|
231
|
+
declare class FlatPivotEngine {
|
|
232
|
+
private dictionary;
|
|
233
|
+
private rowFields;
|
|
234
|
+
private colFields;
|
|
235
|
+
private dataFields;
|
|
236
|
+
private storedColumns;
|
|
237
|
+
private storedRowCount;
|
|
238
|
+
private lastMask;
|
|
239
|
+
private isBuilt;
|
|
240
|
+
private buildState;
|
|
241
|
+
private incrementalFilters;
|
|
242
|
+
private incrementalPrefilter;
|
|
243
|
+
private rowTrie;
|
|
244
|
+
private colTrie;
|
|
245
|
+
private cardinalityMap;
|
|
246
|
+
private rowPathStrs;
|
|
247
|
+
private colPathStrs;
|
|
248
|
+
private rowIndexMapCache;
|
|
249
|
+
private columnIndexMapCache;
|
|
250
|
+
private buildVersion;
|
|
251
|
+
private groupCount;
|
|
252
|
+
private leafGroupRowIds;
|
|
253
|
+
private leafGroupColIds;
|
|
254
|
+
private leafGroupMeasures;
|
|
255
|
+
private leafGroupCounts;
|
|
256
|
+
private leafGroupMins;
|
|
257
|
+
private leafGroupMaxes;
|
|
258
|
+
private leafGroupDistinctSets;
|
|
259
|
+
init(req: WorkerInitRequest): void;
|
|
260
|
+
/**
|
|
261
|
+
* Swap field roles and regroup the already-stored columnar data under the
|
|
262
|
+
* current filter mask. Skips data encoding/transfer entirely — aggregation
|
|
263
|
+
* results are identical to a fresh init + filter with the same fields.
|
|
264
|
+
*/
|
|
265
|
+
reconfigure(req: WorkerReconfigureRequest): void;
|
|
266
|
+
/**
|
|
267
|
+
* Open a chunked init: preallocate full-size columns and the build state.
|
|
268
|
+
* Filters (as raw value strings) are applied DURING the chunked build, so
|
|
269
|
+
* no separate rebuild is needed afterwards — the final state is identical
|
|
270
|
+
* to a monolithic init + applyFilter with the same inputs.
|
|
271
|
+
*/
|
|
272
|
+
initStart(req: WorkerInitStartRequest): void;
|
|
273
|
+
/** Merge a column chunk, mask its rows under the init filters, and aggregate it. */
|
|
274
|
+
initChunk(req: WorkerInitChunkRequest): void;
|
|
275
|
+
/** Close the chunked init and commit the accumulated build. */
|
|
276
|
+
initEnd(): void;
|
|
277
|
+
/**
|
|
278
|
+
* Resolve pending filter value strings against dictionary entries from
|
|
279
|
+
* `fromIndex` on. A string that is not yet in the dictionary cannot match
|
|
280
|
+
* any already-processed row, so incremental resolution stays exact.
|
|
281
|
+
*/
|
|
282
|
+
private resolveIncrementalFilterStrings;
|
|
283
|
+
/** applyFilter semantics over a row range, writing into lastMask. */
|
|
284
|
+
private computeMaskRange;
|
|
285
|
+
applyFilter(req: WorkerFilterRequest): void;
|
|
286
|
+
private evaluatePrefilterGroup;
|
|
287
|
+
private evaluatePrefilterCondition;
|
|
288
|
+
private buildFromMask;
|
|
289
|
+
/** Allocate the state of a build pass (full rebuild or chunked init). */
|
|
290
|
+
private beginBuild;
|
|
291
|
+
/** Cardinality bitmaps must cover the (growing) dictionary id space. */
|
|
292
|
+
private ensureCardCapacity;
|
|
293
|
+
/**
|
|
294
|
+
* Single fused pass over rows [start, end): cardinality + trie grouping +
|
|
295
|
+
* leaf aggregation. `mask` (when present) is indexed by absolute row index.
|
|
296
|
+
*/
|
|
297
|
+
private processRange;
|
|
298
|
+
/** Commit the build state into the engine + rebuild per-build caches. */
|
|
299
|
+
private finalizeBuild;
|
|
300
|
+
private buildPathStrs;
|
|
301
|
+
private buildIndexMap;
|
|
302
|
+
compute(req: WorkerComputeRequest): WorkerResponse;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
interface PivotEngineResult {
|
|
306
|
+
rowTree: PivotNode[];
|
|
307
|
+
colTree: PivotNode[];
|
|
308
|
+
cellMatrix: FlatCellMatrix;
|
|
309
|
+
rowIndexMap: Record<string, number>;
|
|
310
|
+
columnIndexMap: Record<string, number>;
|
|
311
|
+
cardinalityMap: Record<string, number>;
|
|
312
|
+
}
|
|
313
|
+
interface FieldDistinctEntry {
|
|
314
|
+
rawStr: string;
|
|
315
|
+
rawVal: PivotValue;
|
|
316
|
+
}
|
|
317
|
+
/** Set the active grid context for subsequent init/compute calls. */
|
|
318
|
+
declare function setActiveEngineGrid(gridId: string): void;
|
|
319
|
+
/**
|
|
320
|
+
* Release a grid's worker when the grid unmounts. Termination is deferred by
|
|
321
|
+
* a short keep-alive window: a grid that remounts quickly (rebuilds, config
|
|
322
|
+
* driven remounts, React StrictMode double mount) re-claims the worker and —
|
|
323
|
+
* when the dataset identity is unchanged — skips the entire re-encode and
|
|
324
|
+
* re-transfer of its data.
|
|
325
|
+
*/
|
|
326
|
+
declare function destroyEngineWorker(gridId: string): void;
|
|
327
|
+
interface InitFilterState {
|
|
328
|
+
/** All fields — those carrying filterValues become include/exclude specs. */
|
|
329
|
+
fields: PivotField<any>[];
|
|
330
|
+
prefilter?: PivotPrefilter;
|
|
331
|
+
}
|
|
332
|
+
declare function initPivotEngineAsync<TRow>(data: TRow[], rowFields: PivotField<TRow>[], colFields: PivotField<TRow>[], dataFields: PivotField<TRow>[], registry?: PivotEngineRegistry, workerUrl?: string | URL, options?: {
|
|
333
|
+
/**
|
|
334
|
+
* Skip the same-dataset reuse fast path and re-encode unconditionally.
|
|
335
|
+
* Used by explicit refresh (refreshEngine): callers may have mutated the
|
|
336
|
+
* data array in place, so stored columns cannot be trusted.
|
|
337
|
+
*/
|
|
338
|
+
forceReencode?: boolean;
|
|
339
|
+
/**
|
|
340
|
+
* Current filter state; when provided, filters are applied DURING the
|
|
341
|
+
* chunked init build (single build instead of init-build + filter-build).
|
|
342
|
+
* `filtersApplied: true` in the result means the caller can skip its
|
|
343
|
+
* follow-up filter request.
|
|
344
|
+
*/
|
|
345
|
+
filterState?: InitFilterState;
|
|
346
|
+
}): Promise<{
|
|
347
|
+
filtersApplied: boolean;
|
|
348
|
+
}>;
|
|
349
|
+
/**
|
|
350
|
+
* Fast path for field drag & drop / reorder / settings changes: reassigns
|
|
351
|
+
* field roles over the columnar data already stored in the worker instead of
|
|
352
|
+
* re-encoding and re-transferring the whole dataset. Only fields that have no
|
|
353
|
+
* matching column worker-side (entering an area for the first time, or whose
|
|
354
|
+
* encode-relevant definition changed) are encoded and shipped individually.
|
|
355
|
+
*
|
|
356
|
+
* Returns `false` when the fast path is not applicable (no initialized
|
|
357
|
+
* worker context, or the dataset changed) — the caller must fall back to a
|
|
358
|
+
* full {@link initPivotEngineAsync}.
|
|
359
|
+
*/
|
|
360
|
+
declare function reconfigurePivotEngineAsync<TRow>(data: TRow[], rowFields: PivotField<TRow>[], colFields: PivotField<TRow>[], dataFields: PivotField<TRow>[], registry?: PivotEngineRegistry): Promise<boolean>;
|
|
361
|
+
/**
|
|
362
|
+
* Send filter specs to the worker. Converts field.filterValues to
|
|
363
|
+
* dictionary-encoded integer IDs so the worker can do fast integer
|
|
364
|
+
* set lookups on columnar data instead of string comparisons.
|
|
365
|
+
*/
|
|
366
|
+
declare function filterPivotEngineAsync(fields: PivotField<any>[], prefilter?: PivotPrefilter): Promise<void>;
|
|
367
|
+
declare function computePivotMatrixAsync(expandedPaths: string[], expandedColPaths: string[]): Promise<PivotEngineResult>;
|
|
368
|
+
declare function getFieldDistinctValues(fieldId: string): FieldDistinctEntry[] | null;
|
|
369
|
+
|
|
370
|
+
interface PivotReportState {
|
|
371
|
+
fields: PivotField<any>[];
|
|
372
|
+
layout: PivotLayoutState;
|
|
373
|
+
expandedPaths: string[];
|
|
374
|
+
expandedColPaths?: string[];
|
|
375
|
+
chartState?: Record<string, unknown>;
|
|
376
|
+
}
|
|
377
|
+
interface PivotReport {
|
|
378
|
+
id: string;
|
|
379
|
+
name: string;
|
|
380
|
+
createdAt: string;
|
|
381
|
+
updatedAt: string;
|
|
382
|
+
isDefault?: boolean;
|
|
383
|
+
schemaVersion?: number;
|
|
384
|
+
state: PivotReportState;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* Prune row/column tree nodes that have no data cells — the shared
|
|
389
|
+
* implementation of `layout.hideEmptySummaryCells`. Used by BOTH the on-screen
|
|
390
|
+
* grid and the export pipeline so a hidden-empty configuration produces
|
|
391
|
+
* identical structure in the UI and in exported files.
|
|
392
|
+
*
|
|
393
|
+
* A row node is kept if the cell matrix contains its grand-total intersection
|
|
394
|
+
* (rowId × MAX_C); a column node is kept if it contains the column's root-row
|
|
395
|
+
* intersection (colId). Nodes missing from the index maps are kept as-is
|
|
396
|
+
* (they cannot be safely evaluated).
|
|
397
|
+
*/
|
|
398
|
+
declare function filterEmptySummaryTree(engineResult: PivotEngineResult): [PivotNode[], PivotNode[]];
|
|
399
|
+
declare function getVisibleLeafCount(node: PivotNode, expandedColPaths: Set<string>, allExpanded?: boolean): number;
|
|
400
|
+
declare function getVisibleMaxDepth(nodes: PivotNode[], expandedColPaths: Set<string>, allExpanded?: boolean): number;
|
|
401
|
+
declare function getVisibleColLeaves(nodes: PivotNode[], expandedColPaths: Set<string>, allExpanded?: boolean): PivotNode[];
|
|
402
|
+
interface ColHeaderCell {
|
|
403
|
+
node: PivotNode | null;
|
|
404
|
+
caption: string;
|
|
405
|
+
colSpan: number;
|
|
406
|
+
rowSpan: number;
|
|
407
|
+
isTotal: boolean;
|
|
408
|
+
fieldId?: string;
|
|
409
|
+
colPath?: string;
|
|
410
|
+
hasChildren?: boolean;
|
|
411
|
+
isExpanded?: boolean;
|
|
412
|
+
}
|
|
413
|
+
declare function buildColumnHeaders(colTree: PivotNode[], dataFields: PivotField[], layout: PivotLayoutState, expandedColPaths: Set<string>, allExpanded?: boolean): ColHeaderCell[][];
|
|
414
|
+
/**
|
|
415
|
+
* A flattened row for rendering. Each row represents either:
|
|
416
|
+
* - A leaf data row (values at each depth level column)
|
|
417
|
+
* - A subtotal row (after a group's children end)
|
|
418
|
+
* - A grand total row
|
|
419
|
+
*/
|
|
420
|
+
interface FlatRow {
|
|
421
|
+
/** The node path segments (value at each depth) */
|
|
422
|
+
pathValues: (string | null)[];
|
|
423
|
+
/** Which depth level this row "belongs to" (for expand/collapse) */
|
|
424
|
+
depth: number;
|
|
425
|
+
/** The full key/path hash for this node */
|
|
426
|
+
key: string;
|
|
427
|
+
/** Whether this is a subtotal row */
|
|
428
|
+
isSubtotal: boolean;
|
|
429
|
+
/** Whether this row's group has children that can be expanded */
|
|
430
|
+
hasChildren: boolean;
|
|
431
|
+
/** Whether this row's group is currently expanded */
|
|
432
|
+
isExpanded: boolean;
|
|
433
|
+
/** The actual PivotNode reference (the deepest node for this row) */
|
|
434
|
+
node: PivotNode;
|
|
435
|
+
/** rowSpan hints: for tabular layout, parent cells that span multiple rows */
|
|
436
|
+
rowSpans: number[];
|
|
437
|
+
/** Whether this is the first row of its parent group (used for rowSpan rendering) */
|
|
438
|
+
isFirstInGroup: boolean[];
|
|
439
|
+
}
|
|
440
|
+
declare function flattenRowTree(nodes: PivotNode[], expandedPaths: Set<string>, allExpanded: boolean): PivotNode[];
|
|
441
|
+
/**
|
|
442
|
+
* Flatten the row tree for spreadsheet-style tabular rendering.
|
|
443
|
+
*
|
|
444
|
+
* In this layout:
|
|
445
|
+
* - Each row field gets its own column
|
|
446
|
+
* - Parent group values appear in their respective columns
|
|
447
|
+
* - When a group is expanded, children appear below with their values
|
|
448
|
+
* in the NEXT column to the right
|
|
449
|
+
* - Subtotal rows appear after each group's children (if showRowTotals is true)
|
|
450
|
+
* - Parent cells span multiple rows (rowSpan) to avoid repetition
|
|
451
|
+
*/
|
|
452
|
+
declare function flattenRowTreeTabular(nodes: PivotNode[], expandedPaths: Set<string>, allExpanded: boolean, maxDepth: number, showRowTotals: boolean, totalsPosition: 'top' | 'bottom'): FlatRow[];
|
|
453
|
+
/**
|
|
454
|
+
* Flatten the row tree for compact tree rendering.
|
|
455
|
+
* In this layout:
|
|
456
|
+
* - All row headers share a single column (spanning maxDepth).
|
|
457
|
+
* - Each node is its own row.
|
|
458
|
+
* - Indentation is used to show hierarchy.
|
|
459
|
+
*/
|
|
460
|
+
declare function flattenRowTreeTree(nodes: PivotNode[], expandedPaths: Set<string>, allExpanded: boolean, treeDepth: number, showRowTotals: boolean, totalsPosition: 'top' | 'bottom'): FlatRow[];
|
|
461
|
+
|
|
462
|
+
type ExportFormat = 'excel-list' | 'excel-pivot' | 'pdf' | 'json' | 'json-pivot' | 'json-snapshot' | 'xml' | 'csv' | 'print' | 'clipboard';
|
|
463
|
+
/** Options passed to the export pipeline — all fields optional for backward compat. */
|
|
464
|
+
interface ExportOptions {
|
|
465
|
+
/** Apply prefilter to raw data before export. */
|
|
466
|
+
applyFilters?: boolean;
|
|
467
|
+
/** Custom file name (without extension). */
|
|
468
|
+
fileName?: string;
|
|
469
|
+
/** Expand all nodes before export regardless of current state. */
|
|
470
|
+
expandAll?: boolean;
|
|
471
|
+
/** AbortSignal for cancellation support. */
|
|
472
|
+
signal?: AbortSignal;
|
|
473
|
+
/** Progress callback: 0–100. */
|
|
474
|
+
onProgress?: (percent: number) => void;
|
|
475
|
+
/** Include hidden/chooser fields in list export. */
|
|
476
|
+
includeHiddenFields?: boolean;
|
|
477
|
+
/** Locale for formatting. */
|
|
478
|
+
locale?: string;
|
|
479
|
+
}
|
|
480
|
+
declare function exportPivotData<TRow>(format: ExportFormat, data: TRow[], fields: PivotField<TRow>[], engineResult: PivotEngineResult, layout: PivotLayoutState, expandedPaths: Set<string>, expandedColPaths: Set<string>, fileName?: string, locale?: string, options?: ExportOptions): Promise<void>;
|
|
481
|
+
declare function escapeXmlText(value: string): string;
|
|
482
|
+
declare function getCellVal(engineResult: PivotEngineResult, rHash: string, cHash: string, dfId: string, dataFields: PivotField[], cellLookup: Map<number, number>, preferDisplay?: boolean): number | "";
|
|
483
|
+
/** Per-cell style resolved from a data field's conditional-formatting rules. */
|
|
484
|
+
interface ExportCellStyle {
|
|
485
|
+
fillColor?: string;
|
|
486
|
+
textColor?: string;
|
|
487
|
+
bold?: boolean;
|
|
488
|
+
}
|
|
489
|
+
/** Parse a CSS color (#rgb, #rrggbb, rgb(...)) into an [r,g,b] tuple, or null. */
|
|
490
|
+
declare function cssColorToRgb(color: string | undefined): [number, number, number] | null;
|
|
491
|
+
/** Build cellLookup Map from engine result — shared across export functions. */
|
|
492
|
+
declare function buildCellLookup(engineResult: PivotEngineResult): Map<number, number>;
|
|
493
|
+
/** Build column paths list from visible column leaves and data fields. */
|
|
494
|
+
declare function buildColPathsList(engineResult: PivotEngineResult, dataFields: PivotField[], layout: PivotLayoutState, expandedColPaths: Set<string>, allExpanded: boolean): string[][];
|
|
495
|
+
/**
|
|
496
|
+
* Format a date-typed row/column header value exactly as the on-screen grid
|
|
497
|
+
* does (`DateFormatter.format(value, 'grid', …)`), honoring the field's
|
|
498
|
+
* groupInterval. Non-date fields and total/blank cells pass through unchanged.
|
|
499
|
+
*/
|
|
500
|
+
declare function formatHeaderValue(value: any, field: PivotField | undefined, locale: string): any;
|
|
501
|
+
/**
|
|
502
|
+
* Flatten row nodes for export, honoring `rowHeaderLayout`. In `tree` mode all
|
|
503
|
+
* row fields collapse into a single indented column (matching the grid's tree
|
|
504
|
+
* renderer); otherwise each row field gets its own column (tabular). Returns
|
|
505
|
+
* the flat rows plus the effective row-header column count.
|
|
506
|
+
*/
|
|
507
|
+
declare function flattenExportRows(engineResult: PivotEngineResult, rowFields: PivotField[], layout: PivotLayoutState, expandedPaths: Set<string>, allExpanded: boolean): {
|
|
508
|
+
flatRows: FlatRow[];
|
|
509
|
+
treeMode: boolean;
|
|
510
|
+
rowLabelCols: number;
|
|
511
|
+
};
|
|
512
|
+
/**
|
|
513
|
+
* Produce the row-header label cell(s) for one flat row. Tree mode returns a
|
|
514
|
+
* single indented label (subtotals keep a "Total" marker so downstream
|
|
515
|
+
* heuristics still recognize them); tabular mode returns one cell per depth.
|
|
516
|
+
*/
|
|
517
|
+
declare function buildRowLabelCells(flatRow: FlatRow, rowFields: PivotField[], treeMode: boolean, rowLabelCols: number, locale: string): any[];
|
|
518
|
+
/** Find the data field for a given column path entry. */
|
|
519
|
+
declare function resolveColPath(cPathInfo: string[], dataFields: PivotField[]): {
|
|
520
|
+
cHash: string;
|
|
521
|
+
dfId: string;
|
|
522
|
+
};
|
|
523
|
+
/**
|
|
524
|
+
* Build the array-of-arrays used by the PDF/Print/Clipboard exporters.
|
|
525
|
+
*
|
|
526
|
+
* Async + cancellable: the (potentially large) data-row loop yields to the
|
|
527
|
+
* event loop every {@link AOA_CHUNK} rows, honors an AbortSignal, and reports
|
|
528
|
+
* incremental progress. Returns `null` when the export was aborted mid-build.
|
|
529
|
+
*/
|
|
530
|
+
declare function buildPivotAOA(engineResult: PivotEngineResult, rowFields: PivotField[], dataFields: PivotField[], layout: PivotLayoutState, expandedPaths: Set<string>, expandedColPaths: Set<string>, allExpanded?: boolean, locale?: string, applyFormatting?: boolean, colFields?: PivotField[], signal?: AbortSignal, onProgress?: (percent: number) => void): Promise<{
|
|
531
|
+
aoa: any[][];
|
|
532
|
+
styles: (ExportCellStyle | null)[][] | null;
|
|
533
|
+
} | null>;
|
|
534
|
+
|
|
535
|
+
/** Area where a {@link PivotField} can be placed. */
|
|
536
|
+
type PivotArea = 'row' | 'column' | 'data' | 'filter' | 'chooser';
|
|
537
|
+
/** Aggregation function applied to data fields in worker pre-aggregation. */
|
|
538
|
+
type PivotSummaryType = 'sum' | 'count' | 'avg' | 'min' | 'max' | 'distinct' | 'custom';
|
|
539
|
+
/** Post-aggregation display transformation applied after cell values are computed. */
|
|
540
|
+
type PivotSummaryDisplayMode = 'absolute' | 'percentOfTotal' | 'percentOfColumnTotal' | 'percentOfRowTotal' | 'runningTotal' | 'difference' | 'percentDifference';
|
|
541
|
+
/** Temporal or numeric grouping interval for date/number fields. */
|
|
542
|
+
type PivotGroupInterval = 'year' | 'quarter' | 'month' | 'day' | 'numeric' | 'custom';
|
|
543
|
+
/** Supported UI locale identifiers. */
|
|
544
|
+
type PivotLocale = 'tr' | 'en' | 'ar' | 'de' | 'fr' | 'es' | 'it' | 'pt' | 'ru' | 'zh-CN' | 'ja' | 'ko';
|
|
545
|
+
/** Union of all value types a pivot cell, node, or filter can hold. */
|
|
546
|
+
type PivotValue = string | number | boolean | Date | null | undefined;
|
|
547
|
+
/** Comparison operators for filter conditions. */
|
|
548
|
+
type FilterOperator = '=' | '<>' | '>' | '>=' | '<' | '<=' | 'contains' | 'notcontains' | 'startswith' | 'endswith' | 'in' | 'notin' | 'isnull' | 'isnotnull';
|
|
549
|
+
/** A single filter predicate targeting one field. */
|
|
550
|
+
interface FilterCondition {
|
|
551
|
+
fieldId: string;
|
|
552
|
+
operator: FilterOperator;
|
|
553
|
+
value?: PivotValue | PivotValue[];
|
|
554
|
+
}
|
|
555
|
+
/** Composable filter tree — conditions joined by AND/OR, nestable. */
|
|
556
|
+
interface FilterGroup {
|
|
557
|
+
logicalOperator: 'and' | 'or';
|
|
558
|
+
conditions: (FilterCondition | FilterGroup)[];
|
|
559
|
+
}
|
|
560
|
+
/** Top-level prefilter applied before pivot computation. */
|
|
561
|
+
type PivotPrefilter = FilterGroup;
|
|
562
|
+
interface PivotDictionary {
|
|
563
|
+
ok: string;
|
|
564
|
+
cancel: string;
|
|
565
|
+
apply: string;
|
|
566
|
+
close: string;
|
|
567
|
+
search: string;
|
|
568
|
+
selectAll: string;
|
|
569
|
+
clearAll: string;
|
|
570
|
+
show: string;
|
|
571
|
+
hide: string;
|
|
572
|
+
filterArea: string;
|
|
573
|
+
columnArea: string;
|
|
574
|
+
rowArea: string;
|
|
575
|
+
dataArea: string;
|
|
576
|
+
footerArea: string;
|
|
577
|
+
allFields: string;
|
|
578
|
+
dropHere: string;
|
|
579
|
+
actions: string;
|
|
580
|
+
saveNewView: string;
|
|
581
|
+
saveAsView: string;
|
|
582
|
+
saveChanges: string;
|
|
583
|
+
savedViews: string;
|
|
584
|
+
viewOptions: string;
|
|
585
|
+
viewsAndReports: string;
|
|
586
|
+
views: string;
|
|
587
|
+
saveChangesOverwrite: string;
|
|
588
|
+
saveAsCopy: string;
|
|
589
|
+
makeDefault: string;
|
|
590
|
+
deleteReport: string;
|
|
591
|
+
deleteReportConfirm: string;
|
|
592
|
+
export: string;
|
|
593
|
+
importFile: string;
|
|
594
|
+
excelExport: string;
|
|
595
|
+
pivotView: string;
|
|
596
|
+
listView: string;
|
|
597
|
+
preservesGridLayout: string;
|
|
598
|
+
rawFlatData: string;
|
|
599
|
+
document: string;
|
|
600
|
+
pdfDocument: string;
|
|
601
|
+
printReadyLayout: string;
|
|
602
|
+
fullSnapshot: string;
|
|
603
|
+
saveSessionState: string;
|
|
604
|
+
rawDataFormats: string;
|
|
605
|
+
customExports: string;
|
|
606
|
+
customPlugin: string;
|
|
607
|
+
importSuccess: string;
|
|
608
|
+
importWarning: string;
|
|
609
|
+
importError: string;
|
|
610
|
+
initializing: string;
|
|
611
|
+
emptyData: string;
|
|
612
|
+
noItems: string;
|
|
613
|
+
blanks: string;
|
|
614
|
+
loadingData: string;
|
|
615
|
+
processing: string;
|
|
616
|
+
fieldSettings: string;
|
|
617
|
+
caption: string;
|
|
618
|
+
summaryType: string;
|
|
619
|
+
displayMode: string;
|
|
620
|
+
groupInterval: string;
|
|
621
|
+
sum: string;
|
|
622
|
+
count: string;
|
|
623
|
+
avg: string;
|
|
624
|
+
min: string;
|
|
625
|
+
max: string;
|
|
626
|
+
grandTotal: string;
|
|
627
|
+
subTotal: string;
|
|
628
|
+
absoluteValue: string;
|
|
629
|
+
runningTotal: string;
|
|
630
|
+
difference: string;
|
|
631
|
+
percentOfTotal: string;
|
|
632
|
+
none: string;
|
|
633
|
+
year: string;
|
|
634
|
+
quarter: string;
|
|
635
|
+
month: string;
|
|
636
|
+
day: string;
|
|
637
|
+
and: string;
|
|
638
|
+
or: string;
|
|
639
|
+
noConditionsAdded: string;
|
|
640
|
+
calculatedMeasureDesigner: string;
|
|
641
|
+
createFormulasWithoutCode: string;
|
|
642
|
+
measureName: string;
|
|
643
|
+
format: string;
|
|
644
|
+
numericStandard: string;
|
|
645
|
+
numericDecimal: string;
|
|
646
|
+
currencyTRY: string;
|
|
647
|
+
currencyUSD: string;
|
|
648
|
+
percent: string;
|
|
649
|
+
expand: string;
|
|
650
|
+
collapse: string;
|
|
651
|
+
expandAll: string;
|
|
652
|
+
collapseAll: string;
|
|
653
|
+
sortByThisColumn: string;
|
|
654
|
+
sortFieldByThisColumn: string;
|
|
655
|
+
removeAllSorting: string;
|
|
656
|
+
sortAsc: string;
|
|
657
|
+
sortDesc: string;
|
|
658
|
+
clearSort: string;
|
|
659
|
+
order: string;
|
|
660
|
+
moveToStart: string;
|
|
661
|
+
moveToEnd: string;
|
|
662
|
+
moveToLeft: string;
|
|
663
|
+
moveToRight: string;
|
|
664
|
+
showFieldList: string;
|
|
665
|
+
editCalculation: string;
|
|
666
|
+
[key: string]: string;
|
|
667
|
+
}
|
|
668
|
+
/** CSS custom-property overrides for theming the pivot grid. */
|
|
669
|
+
interface PivotTheme {
|
|
670
|
+
id?: string;
|
|
671
|
+
name?: string;
|
|
672
|
+
background?: string;
|
|
673
|
+
surface?: string;
|
|
674
|
+
surfaceHover?: string;
|
|
675
|
+
surfaceHeader?: string;
|
|
676
|
+
border?: string;
|
|
677
|
+
text?: string;
|
|
678
|
+
textMuted?: string;
|
|
679
|
+
textHeader?: string;
|
|
680
|
+
primary?: string;
|
|
681
|
+
primaryForeground?: string;
|
|
682
|
+
success?: string;
|
|
683
|
+
danger?: string;
|
|
684
|
+
warning?: string;
|
|
685
|
+
info?: string;
|
|
686
|
+
totalBackground?: string;
|
|
687
|
+
stripeBackground?: string;
|
|
688
|
+
groupBorder?: string;
|
|
689
|
+
iconActive?: string;
|
|
690
|
+
}
|
|
691
|
+
interface CustomSummaryOptions {
|
|
692
|
+
summaryProcess: 'start' | 'calculate' | 'finalize';
|
|
693
|
+
value: number | null;
|
|
694
|
+
totalValue: number | null;
|
|
695
|
+
}
|
|
696
|
+
interface PivotConditionRule<TStyle = any> {
|
|
697
|
+
type: 'colorScale' | 'dataBar' | 'iconSet' | 'expression';
|
|
698
|
+
formula?: (value: number, cellContext: PivotCell) => boolean;
|
|
699
|
+
style: TStyle;
|
|
700
|
+
}
|
|
701
|
+
type PivotCellTemplate = (props: {
|
|
702
|
+
value: PivotValue;
|
|
703
|
+
displayValue: string;
|
|
704
|
+
cell?: PivotCell;
|
|
705
|
+
field: PivotField;
|
|
706
|
+
}) => any;
|
|
707
|
+
/**
|
|
708
|
+
* Describes a single field (dimension or measure) in the pivot grid.
|
|
709
|
+
*
|
|
710
|
+
* @typeParam TRow - Shape of source data rows.
|
|
711
|
+
* @typeParam TCellTemplate - Custom cell render function type.
|
|
712
|
+
* @typeParam TStyle - Style object type for conditional formatting rules.
|
|
713
|
+
*/
|
|
714
|
+
interface PivotField<TRow = any, TCellTemplate = PivotCellTemplate, TStyle = any> {
|
|
715
|
+
/** Unique identifier for this field. */
|
|
716
|
+
id: string;
|
|
717
|
+
/** Source property name in the data row. */
|
|
718
|
+
dataField?: Extract<keyof TRow, string> | string;
|
|
719
|
+
/** Display label shown in headers and field chooser. */
|
|
720
|
+
caption: string;
|
|
721
|
+
/** Data type used for encoding, formatting, and grouping. */
|
|
722
|
+
dataType: 'string' | 'number' | 'date' | 'boolean';
|
|
723
|
+
/** Which pivot area this field belongs to. */
|
|
724
|
+
area?: PivotArea;
|
|
725
|
+
/** Position index within the area. */
|
|
726
|
+
areaIndex?: number;
|
|
727
|
+
/** Whether the field is visible in the field chooser. */
|
|
728
|
+
visible?: boolean;
|
|
729
|
+
/** Aggregation type — computed in the Web Worker for all types. */
|
|
730
|
+
summaryType?: PivotSummaryType;
|
|
731
|
+
/** Post-aggregation display transformation (e.g. percent of total). */
|
|
732
|
+
summaryDisplayMode?: PivotSummaryDisplayMode;
|
|
733
|
+
calculateCustomSummary?: string | ((options: CustomSummaryOptions) => void);
|
|
734
|
+
/** True for calculated (virtual) fields that derive from other fields. */
|
|
735
|
+
isCalculated?: boolean;
|
|
736
|
+
formulaString?: string;
|
|
737
|
+
formulaType?: 'row' | 'summary';
|
|
738
|
+
/** Row-level expression evaluated via CSP-safe engine. */
|
|
739
|
+
calculateExpression?: string | ((row: TRow) => number | string);
|
|
740
|
+
/** Summary-level expression combining other data field values. */
|
|
741
|
+
calculateSummaryExpression?: string | ((cellValues: Record<string, number>) => number);
|
|
742
|
+
/** Intl format options or custom formatter for cell display values. */
|
|
743
|
+
format?: Intl.NumberFormatOptions | Intl.DateTimeFormatOptions | ((value: number) => string);
|
|
744
|
+
/** Conditional formatting rules evaluated per cell. */
|
|
745
|
+
conditionalFormatting?: PivotConditionRule<TStyle>[];
|
|
746
|
+
/** Custom cell render function. */
|
|
747
|
+
cellTemplate?: TCellTemplate;
|
|
748
|
+
/** Date/numeric grouping interval. */
|
|
749
|
+
groupInterval?: PivotGroupInterval | number;
|
|
750
|
+
/** Active filter values for header filter (include/exclude mode). */
|
|
751
|
+
filterValues?: Set<any>;
|
|
752
|
+
/** Whether filterValues is an include list or exclude list. */
|
|
753
|
+
filterType?: 'include' | 'exclude';
|
|
754
|
+
/** Sort direction for this field's header values. */
|
|
755
|
+
sortOrder?: 'asc' | 'desc';
|
|
756
|
+
/** Data field ID to sort rows by summary value. */
|
|
757
|
+
sortBySummaryField?: string;
|
|
758
|
+
/** Column path key for sort-by-summary targeting. */
|
|
759
|
+
sortBySummaryPath?: string;
|
|
760
|
+
/** Custom sort comparator for header values. */
|
|
761
|
+
calculateCustomSort?: (a: any, b: any, cellA?: PivotCell, cellB?: PivotCell) => number;
|
|
762
|
+
/** Show only top N values; requires sortBySummaryField. */
|
|
763
|
+
topN?: number;
|
|
764
|
+
/** Whether to aggregate remaining values into an "Others" row. */
|
|
765
|
+
topNShowOthers?: boolean;
|
|
766
|
+
/** Custom caption for the "Others" row when topN is active. */
|
|
767
|
+
topNOthersCaption?: string;
|
|
768
|
+
}
|
|
769
|
+
/** Controls pivot grid layout, totals visibility, and structural options. */
|
|
770
|
+
interface PivotLayoutState {
|
|
771
|
+
showColumnGrandTotals?: boolean;
|
|
772
|
+
showRowGrandTotals?: boolean;
|
|
773
|
+
showColumnTotals?: boolean;
|
|
774
|
+
showRowTotals?: boolean;
|
|
775
|
+
/** Whether subtotals appear above or below their groups. */
|
|
776
|
+
totalsPosition?: 'top' | 'bottom';
|
|
777
|
+
showGrandTotals?: 'rows' | 'columns' | 'both' | 'none';
|
|
778
|
+
showSubTotals?: 'rows' | 'columns' | 'both' | 'none';
|
|
779
|
+
totalsDisplayMode?: 'top' | 'bottom';
|
|
780
|
+
/** Row header style: 'tabular' gives one column per row field, 'tree' nests all into one column. */
|
|
781
|
+
rowHeaderLayout?: 'tabular' | 'tree';
|
|
782
|
+
/** Hide rows/columns that have no data. */
|
|
783
|
+
hideEmptySummaryCells?: boolean;
|
|
784
|
+
/** Place data field labels in row headers or column headers. */
|
|
785
|
+
dataFieldPosition?: 'rows' | 'columns';
|
|
786
|
+
/** Server-side or computed prefilter applied before aggregation. */
|
|
787
|
+
prefilter?: PivotPrefilter;
|
|
788
|
+
showFooter?: boolean;
|
|
789
|
+
showFilterArea?: boolean;
|
|
790
|
+
/** Chart integration type when rendering in chart mode. */
|
|
791
|
+
chartType?: string;
|
|
792
|
+
}
|
|
793
|
+
interface PivotLayoutProfile {
|
|
794
|
+
id: string;
|
|
795
|
+
name: string;
|
|
796
|
+
fields: PivotField[];
|
|
797
|
+
layout: PivotLayoutState;
|
|
798
|
+
isDefault: boolean;
|
|
799
|
+
}
|
|
800
|
+
interface PivotStateStoringConfig {
|
|
801
|
+
enabled: boolean;
|
|
802
|
+
type?: 'localStorage' | 'sessionStorage' | 'custom';
|
|
803
|
+
storageKey?: string;
|
|
804
|
+
onSave?: (state: any) => void;
|
|
805
|
+
onLoad?: () => any;
|
|
806
|
+
}
|
|
807
|
+
interface PivotToolbarConfig {
|
|
808
|
+
showSaveReport?: boolean;
|
|
809
|
+
showImportFile?: boolean;
|
|
810
|
+
showExportButton?: boolean;
|
|
811
|
+
showCalculatedFields?: boolean;
|
|
812
|
+
showFullscreenToggle?: boolean;
|
|
813
|
+
showFieldChooserToggle?: boolean;
|
|
814
|
+
showExpandCollapseAll?: boolean;
|
|
815
|
+
showRefreshButton?: boolean;
|
|
816
|
+
}
|
|
817
|
+
/** A node in the row or column tree hierarchy returned by the engine. */
|
|
818
|
+
interface PivotNode {
|
|
819
|
+
key: string;
|
|
820
|
+
value: PivotValue;
|
|
821
|
+
fieldId: string;
|
|
822
|
+
children: PivotNode[];
|
|
823
|
+
isExpanded: boolean;
|
|
824
|
+
isTotal: boolean;
|
|
825
|
+
depth: number;
|
|
826
|
+
hasChildren?: boolean;
|
|
827
|
+
}
|
|
828
|
+
/** Represents a single cell at the intersection of a row path and column path. */
|
|
829
|
+
interface PivotCell<TRow = any> {
|
|
830
|
+
rowPath: string[];
|
|
831
|
+
colPath: string[];
|
|
832
|
+
values: Record<string, number>;
|
|
833
|
+
displayValues: Record<string, string>;
|
|
834
|
+
records?: TRow[];
|
|
835
|
+
isTotalCell: boolean;
|
|
836
|
+
}
|
|
837
|
+
/** Minimal data source shape: field definitions + row array. */
|
|
838
|
+
interface PivotDataSource<TRow = any> {
|
|
839
|
+
fields: PivotField<TRow>[];
|
|
840
|
+
store: TRow[];
|
|
841
|
+
}
|
|
842
|
+
/** Fired when a user clicks a data cell, header, or total. */
|
|
843
|
+
interface CellClickEvent<TRow = any, TNativeEvent = unknown> {
|
|
844
|
+
event: TNativeEvent;
|
|
845
|
+
cellType: 'data' | 'rowHeader' | 'colHeader' | 'grandTotal';
|
|
846
|
+
value?: number;
|
|
847
|
+
rowPath: string[];
|
|
848
|
+
colPath: string[];
|
|
849
|
+
records?: TRow[];
|
|
850
|
+
}
|
|
851
|
+
interface FieldMoveEvent {
|
|
852
|
+
fieldId: string;
|
|
853
|
+
sourceArea: string;
|
|
854
|
+
targetArea: string;
|
|
855
|
+
newIndex: number;
|
|
856
|
+
cancel: () => void;
|
|
857
|
+
isCanceled: boolean;
|
|
858
|
+
}
|
|
859
|
+
/** Fired before each cell renders — mutate `cellConfig` to customize appearance. */
|
|
860
|
+
interface CellPreparedEvent<TRow = any, TNode = unknown, TStyle = unknown> {
|
|
861
|
+
area: 'row' | 'column' | 'data';
|
|
862
|
+
cell: PivotCell<TRow> | null;
|
|
863
|
+
rowIndex: number;
|
|
864
|
+
columnIndex: number;
|
|
865
|
+
cellConfig: {
|
|
866
|
+
text?: TNode;
|
|
867
|
+
style?: TStyle;
|
|
868
|
+
className?: string;
|
|
869
|
+
};
|
|
870
|
+
}
|
|
871
|
+
interface ExportingEvent {
|
|
872
|
+
format: string;
|
|
873
|
+
cancel: boolean;
|
|
874
|
+
}
|
|
875
|
+
interface PivotSelectionStats {
|
|
876
|
+
count: number;
|
|
877
|
+
sum: number;
|
|
878
|
+
avg: number;
|
|
879
|
+
min: number;
|
|
880
|
+
max: number;
|
|
881
|
+
}
|
|
882
|
+
type PivotSelectionMode = 'row' | 'data';
|
|
883
|
+
interface PivotSelectionRange {
|
|
884
|
+
startRow: number;
|
|
885
|
+
startColumn: number;
|
|
886
|
+
endRow: number;
|
|
887
|
+
endColumn: number;
|
|
888
|
+
}
|
|
889
|
+
interface PivotSelectionState {
|
|
890
|
+
range: PivotSelectionRange;
|
|
891
|
+
isSelecting: boolean;
|
|
892
|
+
mode: PivotSelectionMode;
|
|
893
|
+
}
|
|
894
|
+
type PivotCellValueAccessor = (row: number, column: number) => number | null | undefined;
|
|
895
|
+
type PivotCellTextAccessor = (row: number, column: number) => string;
|
|
896
|
+
interface PivotImportStatus {
|
|
897
|
+
isOpen: boolean;
|
|
898
|
+
status: 'loading' | 'success' | 'error' | 'warning';
|
|
899
|
+
title: string;
|
|
900
|
+
messages: string[];
|
|
901
|
+
/** Overall parse progress 0..100 (present only while streaming a large file). */
|
|
902
|
+
progress?: number;
|
|
903
|
+
/** Coarse pipeline stage label (reading | parsing | typing | finalizing). */
|
|
904
|
+
phase?: string;
|
|
905
|
+
/** Whether the in-flight import can be cancelled by the user. */
|
|
906
|
+
cancellable?: boolean;
|
|
907
|
+
}
|
|
908
|
+
/** One detected column in the import preview / column-mapping step. */
|
|
909
|
+
interface PivotImportField {
|
|
910
|
+
/** Source data key. */
|
|
911
|
+
dataField: string;
|
|
912
|
+
/** Display caption (editable in the mapping UI). */
|
|
913
|
+
caption: string;
|
|
914
|
+
/** Detected data type (editable in the mapping UI). */
|
|
915
|
+
dataType: 'string' | 'number' | 'date' | 'boolean';
|
|
916
|
+
}
|
|
917
|
+
/**
|
|
918
|
+
* Parsed-but-not-yet-committed import awaiting user review (preview + column
|
|
919
|
+
* mapping). Held in observable state; the full row set is kept privately by the
|
|
920
|
+
* controller and applied on commit.
|
|
921
|
+
*/
|
|
922
|
+
interface PivotImportPreviewState {
|
|
923
|
+
fields: PivotImportField[];
|
|
924
|
+
/** First-N rows for the preview table. */
|
|
925
|
+
sample: Record<string, unknown>[];
|
|
926
|
+
/** Total parsed row count. */
|
|
927
|
+
rowCount: number;
|
|
928
|
+
warnings: string[];
|
|
929
|
+
}
|
|
930
|
+
type DropIntent = 'before' | 'after' | 'append' | null;
|
|
931
|
+
interface PivotDragIntentState {
|
|
932
|
+
activeId: string | null;
|
|
933
|
+
targetId: string | null;
|
|
934
|
+
targetArea: string | null;
|
|
935
|
+
intent: DropIntent;
|
|
936
|
+
}
|
|
937
|
+
/** Full observable state of the pivot controller — consumed by UI frameworks. */
|
|
938
|
+
interface PivotControllerState<TRow = any> {
|
|
939
|
+
gridId: string;
|
|
940
|
+
fields: PivotField<TRow>[];
|
|
941
|
+
layout: PivotLayoutState;
|
|
942
|
+
expandedPaths: Set<string>;
|
|
943
|
+
expandedColPaths: Set<string>;
|
|
944
|
+
columnWidths: Record<string, number>;
|
|
945
|
+
engineResult: PivotEngineResult | null;
|
|
946
|
+
isBuilding: boolean;
|
|
947
|
+
/** Monotonic engine build progress shown by UI loaders. 0..100, simulated when exact worker progress is unavailable. */
|
|
948
|
+
buildProgress?: number;
|
|
949
|
+
engineError: Error | null;
|
|
950
|
+
selectionStats: PivotSelectionStats | null;
|
|
951
|
+
reports: PivotReport[];
|
|
952
|
+
activeReportId: string | null;
|
|
953
|
+
importStatus: PivotImportStatus;
|
|
954
|
+
/** Pending import awaiting preview/column-mapping review (null when none). */
|
|
955
|
+
importPreview: PivotImportPreviewState | null;
|
|
956
|
+
drag: PivotDragIntentState;
|
|
957
|
+
}
|
|
958
|
+
interface PivotControllerCallbacks<TRow = any> {
|
|
959
|
+
onRefresh?: () => void;
|
|
960
|
+
onImportData?: (data: TRow[]) => void;
|
|
961
|
+
onFieldsChange?: (fields: PivotField<TRow>[]) => void;
|
|
962
|
+
onLayoutChange?: (layout: PivotLayoutState) => void;
|
|
963
|
+
onFieldMove?: (e: FieldMoveEvent) => void | Promise<void>;
|
|
964
|
+
onBeforePivotCalculate?: () => void;
|
|
965
|
+
onAfterPivotCalculate?: (result: PivotEngineResult) => void;
|
|
966
|
+
onExporting?: (e: ExportingEvent) => void;
|
|
967
|
+
onError?: (error: Error) => void;
|
|
968
|
+
onChartStateLoaded?: (chartState: any) => void;
|
|
969
|
+
}
|
|
970
|
+
/** Options for initializing a {@link PivotController}. */
|
|
971
|
+
interface PivotControllerOptions<TRow = any> extends PivotControllerCallbacks<TRow> {
|
|
972
|
+
gridId: string;
|
|
973
|
+
data: TRow[];
|
|
974
|
+
initialFields: PivotField<TRow>[];
|
|
975
|
+
controlledFields?: PivotField<TRow>[];
|
|
976
|
+
controlledLayout?: PivotLayoutState;
|
|
977
|
+
chartIntegrationOptions?: Record<string, any>;
|
|
978
|
+
registry?: PivotEngineRegistry;
|
|
979
|
+
locale?: string;
|
|
980
|
+
workerUrl?: string | URL;
|
|
981
|
+
/**
|
|
982
|
+
* When true, file/URL/paste imports first open a preview + column-mapping
|
|
983
|
+
* step instead of applying immediately. Defaults to false (apply directly).
|
|
984
|
+
*/
|
|
985
|
+
previewImport?: boolean;
|
|
986
|
+
}
|
|
987
|
+
/** Imperative API handle exposed via React ref or Angular adapter. */
|
|
988
|
+
interface PivotGridRef {
|
|
989
|
+
exportData: (format: ExportFormat | string, options?: ExportOptions) => void;
|
|
990
|
+
expandAll: () => void;
|
|
991
|
+
collapseAll: () => void;
|
|
992
|
+
getState: () => PivotControllerState;
|
|
993
|
+
setFields: (fields: PivotField[]) => void;
|
|
994
|
+
refreshEngine: () => void;
|
|
995
|
+
getRawData: () => unknown[];
|
|
996
|
+
getEngineResult: () => PivotEngineResult | null;
|
|
997
|
+
getCell: (rowPath: string[], colPath: string[]) => PivotCell | null;
|
|
998
|
+
}
|
|
999
|
+
declare const defaultPivotLayout: PivotLayoutState;
|
|
1000
|
+
|
|
1001
|
+
export { type PrefilterConditionSpec as $, type FieldDistinctEntry as A, type FilterCondition as B, type CellClickEvent as C, type DropIntent as D, type ExportingEvent as E, type FieldMoveEvent as F, type FilterGroup as G, type FilterOperator as H, type FlatCellMatrix as I, FlatPivotEngine as J, type FlatRow as K, type PivotCellTemplate as L, type PivotControllerCallbacks as M, type PivotDataSource as N, type PivotGridRef as O, type PivotField as P, type PivotGroupInterval as Q, type PivotImportPreviewState as R, type PivotLayoutProfile as S, type PivotLocale as T, type PivotPlugin as U, type PivotSelectionRange as V, type PivotStateStoringConfig as W, type PivotSummaryDisplayMode as X, type PivotSummaryType as Y, type PivotTheme as Z, type PivotToolbarConfig as _, type PivotControllerState as a, type PrefilterGroupSpec as a0, type WorkerComputeRequest as a1, type WorkerFilterRequest as a2, type WorkerFilterSpec as a3, type WorkerInitRequest as a4, type WorkerResponse as a5, buildCellLookup as a6, buildColPathsList as a7, buildColumnHeaders as a8, buildPivotAOA as a9, buildRowLabelCells as aa, computePivotMatrixAsync as ab, cssColorToRgb as ac, defaultPivotLayout as ad, destroyEngineWorker as ae, escapeXmlText as af, exportPivotData as ag, filterEmptySummaryTree as ah, filterPivotEngineAsync as ai, flattenExportRows as aj, flattenRowTree as ak, flattenRowTreeTabular as al, flattenRowTreeTree as am, formatHeaderValue as an, getCellVal as ao, getFieldDistinctValues as ap, getVisibleColLeaves as aq, getVisibleLeafCount as ar, getVisibleMaxDepth as as, initPivotEngineAsync as at, reconfigurePivotEngineAsync as au, resolveColPath as av, setActiveEngineGrid as aw, type WorkerReconfigureRequest as ax, type PivotLayoutState as b, type PivotSelectionStats as c, type PivotImportStatus as d, type PivotControllerOptions as e, type PivotEngineResult as f, type PivotArea as g, type PivotImportField as h, type ExportFormat as i, type ExportOptions as j, type PivotCell as k, type PivotDragIntentState as l, type PivotReport as m, type PivotReportState as n, type PivotSelectionMode as o, type PivotSelectionState as p, type PivotCellValueAccessor as q, type PivotCellTextAccessor as r, type PivotPrefilter as s, type PivotNode as t, PivotEngineRegistry as u, type PivotValue as v, type PivotConditionRule as w, type PivotDictionary as x, type CellPreparedEvent as y, type CustomSummaryOptions as z };
|