• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

IgniteUI / igniteui-angular / 23353730325

20 Mar 2026 05:03PM UTC coverage: 9.784% (-79.5%) from 89.264%
23353730325

Pull #17069

github

web-flow
Merge cfa7e86d1 into a4dc50177
Pull Request #17069: fix(IgxGrid): Do not apply width constraint to groups.

921 of 16963 branches covered (5.43%)

Branch coverage included in aggregate %.

1 of 3 new or added lines in 1 file covered. (33.33%)

25213 existing lines in 340 files now uncovered.

3842 of 31721 relevant lines covered (12.11%)

6.13 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.4
/projects/igniteui-angular/grids/pivot-grid/src/pivot-grid.component.ts
1
import { AfterContentInit, AfterViewInit, ChangeDetectionStrategy, Component, EventEmitter, ElementRef, HostBinding, Input, OnInit, Output, QueryList, TemplateRef, ViewChild, ViewChildren, ContentChild, createComponent, CUSTOM_ELEMENTS_SCHEMA, booleanAttribute, OnChanges, SimpleChanges, inject } from '@angular/core';
2
import { NgTemplateOutlet, NgClass, NgStyle } from '@angular/common';
3

4
import { first, take, takeUntil } from 'rxjs/operators';
5
import { DEFAULT_PIVOT_KEYS, IDimensionsChange, IgxFilteringService, IgxGridNavigationService, IgxGridValidationService, IgxPivotDateDimension, IgxPivotGridValueTemplateContext, IPivotConfiguration, IPivotConfigurationChangedEventArgs, IPivotDimension, IPivotUISettings, IPivotValue, IValuesChange, PivotDimensionType, PivotRowLayoutType, PivotSummaryPosition, PivotUtil } from 'igniteui-angular/grids/core';
6
import { IgxGridSelectionService } from 'igniteui-angular/grids/core';
7
import { GridType, IGX_GRID_BASE, IGX_GRID_SERVICE_BASE, IgxColumnTemplateContext, PivotGridType, RowType } from 'igniteui-angular/grids/core';
8
import { IgxGridCRUDService } from 'igniteui-angular/grids/core';
9
import { IgxGridSummaryService } from 'igniteui-angular/grids/core';
10
import { IgxPivotHeaderRowComponent } from './pivot-header-row.component';
11
import { IgxColumnGroupComponent } from 'igniteui-angular/grids/core';
12
import { IgxColumnComponent } from 'igniteui-angular/grids/core';
13
import { FilterMode, GridPagingMode, GridSummaryPosition } from 'igniteui-angular/grids/core';
14
import { WatchChanges } from 'igniteui-angular/grids/core';
15
import { cloneArray, ColumnType, DataUtil, DefaultDataCloneStrategy, GridColumnDataType, GridSummaryCalculationMode, IDataCloneStrategy, IFilteringExpressionsTree, IFilteringOperation, IFilteringStrategy, ISortingExpression, OverlaySettings, resizeObservable, ɵSize, SortingDirection, IgxOverlayOutletDirective } from 'igniteui-angular/core';
16
import {
17
    IGridEditEventArgs,
18
    ICellPosition,
19
    IColumnMovingEndEventArgs, IColumnMovingEventArgs, IColumnMovingStartEventArgs,
20
    IColumnVisibilityChangedEventArgs,
21
    IGridEditDoneEventArgs,
22
    IGridToolbarExportEventArgs,
23
    IPinColumnCancellableEventArgs,
24
    IPinColumnEventArgs,
25
    IPinRowEventArgs,
26
    IRowDataCancelableEventArgs,
27
    IRowDataEventArgs,
28
    IRowDragEndEventArgs,
29
    IRowDragStartEventArgs
30
} from 'igniteui-angular/grids/core';
31
import { DropPosition } from 'igniteui-angular/grids/core';
32
import { DimensionValuesFilteringStrategy, NoopPivotDimensionsStrategy } from 'igniteui-angular/grids/core';
33
import { IgxGridExcelStyleFilteringComponent, IgxExcelStyleColumnOperationsTemplateDirective, IgxExcelStyleFilterOperationsTemplateDirective } from 'igniteui-angular/grids/core';
34
import { IgxPivotGridNavigationService } from './pivot-grid-navigation.service';
35
import { IgxPivotColumnResizingService } from 'igniteui-angular/grids/core';
36
import { State, Transaction, TransactionService, onResourceChangeHandle } from 'igniteui-angular/core';
37
import { IgxPivotFilteringService } from './pivot-filtering.service';
38
import { GridBaseAPIService } from 'igniteui-angular/grids/core';
39
import { IgxPivotRowDimensionContentComponent } from './pivot-row-dimension-content.component';
40
import { IgxPivotGridColumnResizerComponent } from 'igniteui-angular/grids/core';
41
import { PivotSortUtil } from './pivot-sort-util';
42
import { IgxPivotRowDimensionHeaderTemplateDirective, IgxPivotValueChipTemplateDirective } from './pivot-grid.directives';
43
import { IgxPivotRowPipe, IgxPivotRowExpansionPipe, IgxPivotAutoTransform, IgxPivotColumnPipe, IgxPivotGridFilterPipe, IgxPivotGridSortingPipe, IgxPivotGridColumnSortingPipe, IgxPivotCellMergingPipe, IgxPivotGridHorizontalRowGrouping } from './pivot-grid.pipes';
44
import { IgxGridRowClassesPipe, IgxGridRowStylesPipe } from 'igniteui-angular/grids/core';
45
import { IgxExcelStyleSearchComponent } from 'igniteui-angular/grids/core';
46
import { IgxPivotRowComponent } from './pivot-row.component';
47
import { IgxColumnMovingDropDirective } from 'igniteui-angular/grids/core';
48
import { IgxGridDragSelectDirective } from 'igniteui-angular/grids/core';
49
import { IgxGridBodyDirective } from 'igniteui-angular/grids/core';
50
import { IgxColumnResizingService } from 'igniteui-angular/grids/core';
51
import { IgxPivotRowHeaderGroupComponent } from './pivot-row-header-group.component';
52
import { IgxPivotRowDimensionMrlRowComponent } from './pivot-row-dimension-mrl-row.component';
53
import { IForOfDataChangingEventArgs, IgxForOfScrollSyncService, IgxForOfSyncService, IgxGridForOfDirective, IgxTemplateOutletDirective, IgxToggleDirective } from 'igniteui-angular/directives';
54
import { IgxCircularProgressBarComponent } from 'igniteui-angular/progressbar';
55
import { IgxSnackbarComponent } from 'igniteui-angular/snackbar';
56
import { IgxIconComponent } from 'igniteui-angular/icon';
57
import { IgxPivotGridRow } from './pivot-grid-row';
58
import { IgxGridBaseDirective, IgxGridRowComponent } from 'igniteui-angular/grids/grid';
59

60
let NEXT_ID = 0;
3✔
61
const MINIMUM_COLUMN_WIDTH = 200;
3✔
62
const MINIMUM_COLUMN_WIDTH_SUPER_COMPACT = 104;
3✔
63

64
/* blazorAdditionalDependency: Column */
65
/* blazorAdditionalDependency: ColumnGroup */
66
/* blazorAdditionalDependency: ColumnLayout */
67
/* blazorAdditionalDependency: GridToolbar */
68
/* blazorAdditionalDependency: GridToolbarActions */
69
/* blazorAdditionalDependency: GridToolbarTitle */
70
/* blazorAdditionalDependency: GridToolbarAdvancedFiltering */
71
/* blazorAdditionalDependency: GridToolbarExporter */
72
/* blazorAdditionalDependency: GridToolbarHiding */
73
/* blazorAdditionalDependency: GridToolbarPinning */
74
/* blazorAdditionalDependency: ActionStrip */
75
/* blazorAdditionalDependency: GridActionsBaseDirective */
76
/* blazorAdditionalDependency: GridEditingActions */
77
/* blazorAdditionalDependency: GridPinningActions */
78
/* blazorAdditionalDependency: PivotDateDimension */
79
/* blazorIndirectRender */
80
/**
81
 * Pivot Grid provides a way to present and manipulate data in a pivot table view.
82
 *
83
 * @igxModule IgxPivotGridModule
84
 * @igxGroup Grids & Lists
85
 * @igxKeywords pivot, grid, table
86
 * @igxTheme igx-grid-theme
87
 * @remarks
88
 * The Ignite UI Pivot Grid is used for grouping and aggregating simple flat data into a pivot table.  Once data
89
 * has been bound and the dimensions and values configured it can be manipulated via sorting and filtering.
90
 * @example
91
 * ```html
92
 * <igx-pivot-grid [data]="data" [pivotConfiguration]="configuration">
93
 * </igx-pivot-grid>
94
 * ```
95
 */
96
@Component({
97
    changeDetection: ChangeDetectionStrategy.OnPush,
98
    preserveWhitespaces: false,
99
    selector: 'igx-pivot-grid',
100
    templateUrl: 'pivot-grid.component.html',
101
    providers: [
102
        IgxGridCRUDService,
103
        IgxGridValidationService,
104
        IgxGridSummaryService,
105
        IgxGridSelectionService,
106
        IgxColumnResizingService,
107
        GridBaseAPIService,
108
        { provide: IGX_GRID_SERVICE_BASE, useClass: GridBaseAPIService },
109
        { provide: IGX_GRID_BASE, useExisting: IgxPivotGridComponent },
110
        { provide: IgxFilteringService, useClass: IgxPivotFilteringService },
111
        IgxGridNavigationService,
112
        IgxPivotGridNavigationService,
113
        IgxPivotColumnResizingService,
114
        IgxForOfSyncService,
115
        IgxForOfScrollSyncService
116
    ],
117
    imports: [
118
        NgClass,
119
        NgStyle,
120
        NgTemplateOutlet,
121
        IgxPivotHeaderRowComponent,
122
        IgxGridBodyDirective,
123
        IgxGridDragSelectDirective,
124
        IgxColumnMovingDropDirective,
125
        IgxGridForOfDirective,
126
        IgxTemplateOutletDirective,
127
        IgxPivotRowComponent,
128
        IgxToggleDirective,
129
        IgxCircularProgressBarComponent,
130
        IgxSnackbarComponent,
131
        IgxOverlayOutletDirective,
132
        IgxPivotGridColumnResizerComponent,
133
        IgxIconComponent,
134
        IgxPivotRowDimensionContentComponent,
135
        IgxGridExcelStyleFilteringComponent,
136
        IgxExcelStyleColumnOperationsTemplateDirective,
137
        IgxExcelStyleFilterOperationsTemplateDirective,
138
        IgxExcelStyleSearchComponent,
139
        IgxGridRowClassesPipe,
140
        IgxGridRowStylesPipe,
141
        IgxPivotRowPipe,
142
        IgxPivotRowExpansionPipe,
143
        IgxPivotAutoTransform,
144
        IgxPivotColumnPipe,
145
        IgxPivotGridFilterPipe,
146
        IgxPivotGridSortingPipe,
147
        IgxPivotGridColumnSortingPipe,
148
        IgxPivotCellMergingPipe,
149
        IgxPivotGridHorizontalRowGrouping,
150
        IgxPivotRowDimensionMrlRowComponent
151
    ],
152
    schemas: [CUSTOM_ELEMENTS_SCHEMA]
153
})
154
export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnInit, AfterContentInit,
3✔
155
    PivotGridType, AfterViewInit, OnChanges {
156
    /* blazorSuppress */
UNCOV
157
    public override readonly gridAPI = inject<GridBaseAPIService<IgxGridBaseDirective & GridType>>(GridBaseAPIService);
×
158
    /* blazorSuppress */
UNCOV
159
    public override navigation = inject(IgxPivotGridNavigationService);
×
UNCOV
160
    protected override colResizingService = inject(IgxPivotColumnResizingService);
×
161

162
    /**
163
     * Emitted when the dimension collection is changed via the grid chip area.
164
     *
165
     * @remarks
166
     * Returns the new dimension collection and its type:
167
     * @example
168
     * ```html
169
     * <igx-pivot-grid #grid [data]="localData" [height]="'305px'"
170
     *              (dimensionsChange)="dimensionsChange($event)"></igx-grid>
171
     * ```
172
     */
173
    @Output()
UNCOV
174
    public dimensionsChange = new EventEmitter<IDimensionsChange>();
×
175

176
    /**
177
     * Emitted when any of the pivotConfiguration properties is changed via the grid chip area.
178
     *
179
     * @example
180
     * ```html
181
     * <igx-pivot-grid #grid [data]="localData" [height]="'305px'"
182
     *              (pivotConfigurationChanged)="configurationChanged($event)"></igx-grid>
183
     * ```
184
     */
185
    @Output()
UNCOV
186
    public pivotConfigurationChange = new EventEmitter<IPivotConfigurationChangedEventArgs>();
×
187

188

189
    /**
190
     * Emitted when the dimension is initialized.
191
     * @remarks
192
     * Emits the dimension that is about to be initialized.
193
     * @example
194
     * ```html
195
     * <igx-pivot-grid #grid [data]="localData" [height]="'305px'"
196
     *              (dimensionInit)="dimensionInit($event)"></igx-pivot-grid>
197
     * ```
198
     */
199
    @Output()
UNCOV
200
    public dimensionInit = new EventEmitter<IPivotDimension>();
×
201

202
    /**
203
     * Emitted when the value is initialized.
204
     * @remarks
205
     * Emits the value that is about to be initialized.
206
     * @example
207
     * ```html
208
     * <igx-pivot-grid #grid [data]="localData" [height]="'305px'"
209
     *              (valueInit)="valueInit($event)"></igx-pivot-grid>
210
     * ```
211
     */
212
    @Output()
UNCOV
213
    public valueInit = new EventEmitter<IPivotValue>();
×
214

215

216
    /**
217
     * Emitted when a dimension is sorted.
218
     *
219
     * @example
220
     * ```html
221
     * <igx-pivot-grid #grid [data]="localData" [height]="'305px'"
222
     *              (dimensionsSortingExpressionsChange)="dimensionsSortingExpressionsChange($event)"></igx-pivot-grid>
223
     * ```
224
     */
225
    @Output()
UNCOV
226
    public dimensionsSortingExpressionsChange = new EventEmitter<ISortingExpression[]>();
×
227

228
    /**
229
     * Emitted when the values collection is changed via the grid chip area.
230
     *
231
     * @remarks
232
     * Returns the new dimension
233
     * @example
234
     * ```html
235
     * <igx-pivot-grid #grid [data]="localData" [height]="'305px'"
236
     *              (valuesChange)="valuesChange($event)"></igx-grid>
237
     * ```
238
    */
239
    @Output()
UNCOV
240
    public valuesChange = new EventEmitter<IValuesChange>();
×
241

242

243
    /**
244
     * Gets the sorting expressions generated for the dimensions.
245
     *
246
     * @example
247
     * ```typescript
248
     * const expressions = this.grid.dimensionsSortingExpressions;
249
     * ```
250
     */
251
    public get dimensionsSortingExpressions() {
UNCOV
252
        const allEnabledDimensions = this.rowDimensions.concat(this.columnDimensions);
×
UNCOV
253
        const dimensionsSortingExpressions = PivotSortUtil.generateDimensionSortingExpressions(allEnabledDimensions);
×
UNCOV
254
        return dimensionsSortingExpressions;
×
255
    }
256

257
    /** @hidden @internal */
258
    @ViewChild(IgxPivotHeaderRowComponent, { static: true })
259
    public override theadRow: IgxPivotHeaderRowComponent;
260

261
    /**
262
    * @hidden @internal
263
    */
264
    @ContentChild(IgxPivotValueChipTemplateDirective, { read: IgxPivotValueChipTemplateDirective })
265
    protected valueChipTemplateDirective: IgxPivotValueChipTemplateDirective;
266

267
    /**
268
     * @hidden @internal
269
     */
270
    @ContentChild(IgxPivotRowDimensionHeaderTemplateDirective, { read: IgxPivotRowDimensionHeaderTemplateDirective })
271
    protected rowDimensionHeaderDirective: IgxPivotRowDimensionHeaderTemplateDirective;
272

273
    /**
274
     * Gets/Sets a custom template for the value chips.
275
     *
276
     * @example
277
     * ```html
278
     * <igx-pivot-grid [valueChipTemplate]="myTemplate"><igx-pivot-grid>
279
     * ```
280
     */
281
    @Input()
282
    public valueChipTemplate: TemplateRef<IgxPivotGridValueTemplateContext>;
283

284
    @Input()
285
    public rowDimensionHeaderTemplate: TemplateRef<IgxColumnTemplateContext>;
286

287
    /* mustSetInCodePlatforms: WebComponents;Blazor;React */
288
    /* @tsTwoWayProperty (true, "PivotConfigurationChange", "Detail.PivotConfiguration", false) */
289
    /**
290
     * Gets/Sets the pivot configuration with all related dimensions and values.
291
     *
292
     * @example
293
     * ```html
294
     * <igx-pivot-grid [pivotConfiguration]="config"></igx-pivot-grid>
295
     * ```
296
     */
297
    @Input()
298
    public set pivotConfiguration(value: IPivotConfiguration) {
UNCOV
299
        this._pivotConfiguration = value;
×
UNCOV
300
        this.emitInitEvents(this._pivotConfiguration);
×
UNCOV
301
        this.filteringExpressionsTree = PivotUtil.buildExpressionTree(value);
×
UNCOV
302
        if (!this._init) {
×
UNCOV
303
            this.setupColumns();
×
304
        }
UNCOV
305
        this.notifyChanges(true);
×
306
    }
307

308
    /* mustSetInCodePlatforms: WebComponents;Blazor */
309
    public get pivotConfiguration() {
UNCOV
310
        return this._pivotConfiguration || { rows: null, columns: null, values: null, filters: null };
×
311
    }
312

313
    /**
314
     * Gets/Sets whether to auto-generate the pivot configuration based on the provided data.
315
     *
316
     * @remarks
317
     * The default value is false. When set to true, it will override all dimensions and values in the pivotConfiguration.
318
     * @example
319
     * ```html
320
     * <igx-pivot-grid [data]="Data" [autoGenerateConfig]="true"></igx-pivot-grid>
321
     * ```
322
     */
323
    @Input({ transform: booleanAttribute })
UNCOV
324
    public autoGenerateConfig = false;
×
325

326
    @Input()
327
    /**
328
     * Gets/Sets the pivot ui settings for the pivot grid - chips and their
329
     * corresponding containers for row, filter, column dimensions and values
330
     * as well as headers for the row dimensions values.
331
     * @example
332
     * ```html
333
     * <igx-pivot-grid [pivotUI]="{ showRowHeaders: true }"></igx-pivot-grid>
334
     * ```
335
     */
336
    public set pivotUI(value: IPivotUISettings) {
UNCOV
337
        this._pivotUI = Object.assign(this._pivotUI, value || {});
×
UNCOV
338
        this.pipeTrigger++;
×
UNCOV
339
        this.notifyChanges(true);
×
340
    }
341

342
    public get pivotUI() {
UNCOV
343
        return this._pivotUI;
×
344
    }
345

346
    /**
347
     * @hidden @internal
348
     */
349
    @HostBinding('attr.role')
UNCOV
350
    public role = 'grid';
×
351

352
    /**
353
     * Enables a super compact theme for the component.
354
     * @remarks
355
     * Overrides the grid size option if one is set.
356
     * @example
357
     * ```html
358
     * <igx-pivot-grid [superCompactMode]="true"></igx-pivot-grid>
359
     * ```
360
     */
361
    @HostBinding('class.igx-grid__pivot--super-compact')
362
    @Input()
363
    public get superCompactMode() {
UNCOV
364
        return this._superCompactMode;
×
365
    }
366

367
    public set superCompactMode(value) {
UNCOV
368
        this._superCompactMode = value;
×
369
    }
370

371
    /** @hidden @internal */
372
    public override get gridSize() {
UNCOV
373
        if (this.superCompactMode) {
×
UNCOV
374
            return ɵSize.Small;
×
375
        }
UNCOV
376
        return super.gridSize;
×
377
    }
378

379

380
    /**
381
     * Gets/Sets the values clone strategy of the pivot grid when assigning them to different dimensions.
382
     *
383
     * @example
384
     * ```html
385
     *  <igx-pivot-grid #grid [data]="localData" [pivotValueCloneStrategy]="customCloneStrategy"></igx-pivot-grid>
386
     * ```
387
     * @hidden @internal
388
     */
389
    @Input()
390
    public get pivotValueCloneStrategy(): IDataCloneStrategy {
UNCOV
391
        return this._pivotValueCloneStrategy;
×
392
    }
393

394
    public set pivotValueCloneStrategy(strategy: IDataCloneStrategy) {
395
        if (strategy) {
×
396
            this._pivotValueCloneStrategy = strategy;
×
397
        }
398
    }
399

400
    /**
401
     * @hidden @internal
402
     */
403
    @ViewChild('record_template', { read: TemplateRef, static: true })
404
    public recordTemplate: TemplateRef<any>;
405

406
    /**
407
     * @hidden @internal
408
     */
409
    @ViewChild(IgxPivotRowDimensionMrlRowComponent, { read: IgxPivotRowDimensionMrlRowComponent })
410
    public rowDimensionMrlComponent: IgxPivotRowDimensionMrlRowComponent;
411

412
    /**
413
     * @hidden @internal
414
     */
415
    @ViewChild('headerTemplate', { read: TemplateRef, static: true })
416
    public headerTemplate: TemplateRef<any>;
417

418
    /**
419
     * @hidden @internal
420
     */
421
    @ViewChildren('rowDimensionContainer', { read: ElementRef })
422
    public rowDimensionContainer: QueryList<ElementRef<any>>;
423

424
    /**
425
     * @hidden @internal
426
     */
427
    @ViewChild(IgxPivotGridColumnResizerComponent)
428
    public override resizeLine: IgxPivotGridColumnResizerComponent;
429

430
    /**
431
     * @hidden @internal
432
     */
433
    @ViewChildren(IgxGridExcelStyleFilteringComponent, { read: IgxGridExcelStyleFilteringComponent })
434
    public override excelStyleFilteringComponents: QueryList<IgxGridExcelStyleFilteringComponent>;
435

436
    /**
437
     * @hidden @internal
438
     */
439
    @ViewChildren(IgxPivotRowDimensionContentComponent)
440
    protected rowDimensionContentCollection: QueryList<IgxPivotRowDimensionContentComponent>;
441

442
    /**
443
     * @hidden @internal
444
     */
445
    public override get minColumnWidth() {
UNCOV
446
        if (this.superCompactMode) {
×
UNCOV
447
            return MINIMUM_COLUMN_WIDTH_SUPER_COMPACT;
×
448
        } else {
UNCOV
449
            return MINIMUM_COLUMN_WIDTH;
×
450
        }
451
    }
452

453
    /**
454
     * @hidden @internal
455
     */
456
    @ViewChildren('verticalRowDimScrollContainer', { read: IgxGridForOfDirective })
457
    public verticalRowDimScrollContainers: QueryList<IgxGridForOfDirective<any, any[]>>;
458

459
    /**
460
     * @hidden @internal
461
     */
462
    @ViewChildren(IgxPivotRowDimensionMrlRowComponent)
463
    public rowDimensionMrlRowsCollection: QueryList<IgxPivotRowDimensionMrlRowComponent>;
464

465
    /**
466
     * @hidden @internal
467
     */
468
    @Input()
469
    public override addRowEmptyTemplate: TemplateRef<void>;
470

471
    /**
472
     * @hidden @internal
473
     */
474
    @Input()
UNCOV
475
    public override autoGenerateExclude: string[] = [];
×
476

477
    /**
478
     * @hidden @internal
479
     */
480
    @Input()
UNCOV
481
    public override snackbarDisplayTime = 6000;
×
482

483
    /**
484
     * @hidden @internal
485
     */
486
    @Output()
UNCOV
487
    public override cellEdit = new EventEmitter<IGridEditEventArgs>();
×
488

489
    /**
490
     * @hidden @internal
491
     */
492
    @Output()
UNCOV
493
    public override cellEditDone = new EventEmitter<IGridEditDoneEventArgs>();
×
494

495
    /**
496
     * @hidden @internal
497
     */
498
    @Output()
UNCOV
499
    public override cellEditEnter = new EventEmitter<IGridEditEventArgs>();
×
500

501
    /**
502
     * @hidden @internal
503
     */
504
    @Output()
UNCOV
505
    public override cellEditExit = new EventEmitter<IGridEditDoneEventArgs>();
×
506

507
    /**
508
     * @hidden @internal
509
     */
510
    @Output()
UNCOV
511
    public override columnMovingStart = new EventEmitter<IColumnMovingStartEventArgs>();
×
512

513
    /**
514
     * @hidden @internal
515
     */
516
    @Output()
UNCOV
517
    public override columnMoving = new EventEmitter<IColumnMovingEventArgs>();
×
518

519
    /**
520
     * @hidden @internal
521
     */
522
    @Output()
UNCOV
523
    public override columnMovingEnd = new EventEmitter<IColumnMovingEndEventArgs>();
×
524

525
    /**
526
     * @hidden @internal
527
     */
528
    @Output()
UNCOV
529
    public override columnPin = new EventEmitter<IPinColumnCancellableEventArgs>();
×
530

531
    /**
532
     * @hidden @internal
533
     */
534
    @Output()
UNCOV
535
    public override columnPinned = new EventEmitter<IPinColumnEventArgs>();
×
536

537
    /**
538
     * @hidden @internal
539
     */
540
    @Output()
UNCOV
541
    public override rowAdd = new EventEmitter<IRowDataCancelableEventArgs>();
×
542

543
    /**
544
     * @hidden @internal
545
     */
546
    @Output()
UNCOV
547
    public override rowAdded = new EventEmitter<IRowDataEventArgs>();
×
548

549
    /**
550
     * @hidden @internal
551
     */
552
    @Output()
UNCOV
553
    public override rowDeleted = new EventEmitter<IRowDataEventArgs>();
×
554

555
    /**
556
     * @hidden @internal
557
     */
558
    @Output()
UNCOV
559
    public override rowDelete = new EventEmitter<IRowDataCancelableEventArgs>();
×
560

561
    /**
562
     * @hidden @internal
563
     */
564
    @Output()
UNCOV
565
    public override rowDragStart = new EventEmitter<IRowDragStartEventArgs>();
×
566

567
    /**
568
     * @hidden @internal
569
     */
570
    @Output()
UNCOV
571
    public override rowDragEnd = new EventEmitter<IRowDragEndEventArgs>();
×
572

573
    /**
574
     * @hidden @internal
575
     */
576
    @Output()
UNCOV
577
    public override rowEditEnter = new EventEmitter<IGridEditEventArgs>();
×
578

579
    /**
580
     * @hidden @internal
581
     */
582
    @Output()
UNCOV
583
    public override rowEdit = new EventEmitter<IGridEditEventArgs>();
×
584

585
    /**
586
     * @hidden @internal
587
     */
588
    @Output()
UNCOV
589
    public override rowEditDone = new EventEmitter<IGridEditDoneEventArgs>();
×
590

591
    /**
592
     * @hidden @internal
593
     */
594
    @Output()
UNCOV
595
    public override rowEditExit = new EventEmitter<IGridEditDoneEventArgs>();
×
596

597
    /**
598
     * @hidden @internal
599
     */
600
    @Output()
UNCOV
601
    public override rowPinning = new EventEmitter<IPinRowEventArgs>();
×
602

603
    /**
604
     * @hidden @internal
605
     */
606
    @Output()
UNCOV
607
    public override rowPinned = new EventEmitter<IPinRowEventArgs>();
×
608

609
    /** @hidden @internal */
UNCOV
610
    public columnGroupStates = new Map<string, boolean>();
×
611
    /** @hidden @internal */
612
    public dimensionDataColumns: any[];
613
    /** @hidden @internal */
614
    public get pivotKeys() {
UNCOV
615
        return this.pivotConfiguration.pivotKeys || DEFAULT_PIVOT_KEYS;
×
616
    }
617
    /** @hidden @internal */
618
    public override get type(): GridType["type"] {
UNCOV
619
        return 'pivot';
×
620
    }
621

622
    /**
623
     * @hidden @internal
624
     */
UNCOV
625
    public override dragRowID = null;
×
626

627
    /**
628
    * @hidden @internal
629
    */
630
    public override get rootSummariesEnabled(): boolean {
UNCOV
631
        return false;
×
632
    }
633

634
    /**
635
     * @hidden @internal
636
     */
UNCOV
637
    public rowDimensionResizing = true;
×
638

UNCOV
639
    private _emptyRowDimension: IPivotDimension = { memberName: '', enabled: true, level: 0 };
×
640
    /**
641
     * @hidden @internal
642
     */
643
    public get emptyRowDimension(): IPivotDimension {
UNCOV
644
        return this._emptyRowDimension;
×
645
    }
646

UNCOV
647
    protected _pivotValueCloneStrategy: IDataCloneStrategy = new DefaultDataCloneStrategy();
×
UNCOV
648
    protected override _defaultExpandState = false;
×
UNCOV
649
    protected override _filterStrategy: IFilteringStrategy = new DimensionValuesFilteringStrategy();
×
UNCOV
650
    protected regroupTrigger = 0;
×
651
    private _data;
UNCOV
652
    private _pivotConfiguration: IPivotConfiguration = { rows: null, columns: null, values: null, filters: null };
×
UNCOV
653
    private p_id = `igx-pivot-grid-${NEXT_ID++}`;
×
UNCOV
654
    private _superCompactMode = false;
×
UNCOV
655
    private _pivotUI: IPivotUISettings = {
×
656
        showConfiguration: true,
657
        showRowHeaders: false,
658
        rowLayout: PivotRowLayoutType.Vertical,
659
        horizontalSummariesPosition: PivotSummaryPosition.Bottom
660
    };
UNCOV
661
    private _sortableColumns = true;
×
UNCOV
662
    private _visibleRowDimensions: IPivotDimension[] = [];
×
UNCOV
663
    private _shouldUpdateSizes = false;
×
664

665
    /**
666
    * Gets/Sets the default expand state for all rows.
667
    */
668
    @Input({ transform: booleanAttribute })
669
    public get defaultExpandState() {
UNCOV
670
        return this._defaultExpandState;
×
671
    }
672

673
    public set defaultExpandState(val: boolean) {
UNCOV
674
        this._defaultExpandState = val;
×
675
    }
676

677
    /**
678
     * @hidden @internal
679
     */
680
    @Input()
681
    public override get pagingMode(): GridPagingMode {
682
        return 'local';
×
683
    }
684

685
    public override set pagingMode(_val: GridPagingMode) {
686
    }
687

688
    /**
689
     * @hidden @internal
690
     */
691
    @WatchChanges()
692
    @Input({ transform: booleanAttribute })
693
    public override get hideRowSelectors(): boolean {
694
        return false;
×
695
    }
696

697
    public override set hideRowSelectors(_value: boolean) {
698
    }
699

700
    /**
701
     * @hidden @internal
702
     */
UNCOV
703
    public override autoGenerate = true;
×
704

705
    /**
706
     * @hidden @internal
707
     */
708
    public override get actionStrip() {
UNCOV
709
        return undefined as any;
×
710
    }
711

712
    /**
713
     * @hidden @internal
714
     * @deprecated in version 18.2.0. This property is no longer supported.
715
     */
716
    public override get shouldGenerate(): boolean {
717
        return false;
×
718
    }
719

720
    public override set shouldGenerate(value: boolean) {
721
    }
722

723
    /**
724
     * @hidden @internal
725
     */
UNCOV
726
    public override moving = false;
×
727

728
    /**
729
     * @hidden @internal
730
     */
UNCOV
731
    public override toolbarExporting = new EventEmitter<IGridToolbarExportEventArgs>();
×
732

733
    /**
734
     * @hidden @internal
735
     */
736
    @Input({ transform: booleanAttribute })
737
    public override get rowDraggable(): boolean {
738
        return false;
×
739
    }
740

741

742
    public override set rowDraggable(_val: boolean) {
743
    }
744

745
    /**
746
     * @hidden @internal
747
     */
748
    @Input({ transform: booleanAttribute })
749
    public override get allowAdvancedFiltering() {
750
        return false;
×
751
    }
752

753
    public override set allowAdvancedFiltering(_value) {
754
    }
755

756
    /**
757
     * @hidden @internal
758
     */
759
    @Input()
760
    public override get filterMode() {
761
        return FilterMode.quickFilter;
×
762
    }
763

764
    public override set filterMode(_value: FilterMode) {
765
    }
766

767
    /**
768
     * @hidden @internal
769
     */
770
    @Input({ transform: booleanAttribute })
771
    public override get allowFiltering() {
UNCOV
772
        return false;
×
773
    }
774

775
    public override set allowFiltering(_value) {
776
    }
777

778
    /**
779
     * @hidden @internal
780
     */
781
    @Input()
782
    public override get page(): number {
783
        return 0;
×
784
    }
785

786
    public override set page(_val: number) {
787
    }
788

789
    /**
790
     * @hidden @internal
791
     */
792
    @Input()
793
    public override get perPage(): number {
794
        return 0;
×
795
    }
796

797
    public override set perPage(_val: number) {
798
    }
799

800
    /**
801
     * @hidden @internal
802
     */
803
    public override get pinnedColumns(): IgxColumnComponent[] {
UNCOV
804
        return [];
×
805
    }
806

807
    /**
808
    * @hidden @internal
809
    */
810
    public override get unpinnedColumns(): IgxColumnComponent[] {
UNCOV
811
        return super.unpinnedColumns;
×
812
    }
813

814
    /**
815
    * @hidden @internal
816
    */
817
    public override get unpinnedDataView(): any[] {
818
        return super.unpinnedDataView;
×
819
    }
820

821
    /**
822
    * @hidden @internal
823
    */
824
    public override get unpinnedWidth() {
UNCOV
825
        return super.unpinnedWidth;
×
826
    }
827

828
    /**
829
     * @hidden @internal
830
     */
831
    public override get pinnedStartWidth() {
UNCOV
832
        return super.pinnedStartWidth;
×
833
    }
834

835
    /**
836
     * @hidden @internal
837
     */
838
    @Input()
839
    public override set summaryRowHeight(_value: number) {
840
    }
841

842
    public override get summaryRowHeight(): number {
UNCOV
843
        return 0;
×
844
    }
845

846
    /**
847
     * @hidden @internal
848
     */
849
    public override get transactions(): TransactionService<Transaction, State> {
UNCOV
850
        return this._transactions;
×
851
    }
852

853

854

855
    /**
856
     * @hidden @internal
857
     */
858
    public override get dragIndicatorIconTemplate(): TemplateRef<any> {
859
        return;
×
860
    }
861

862
    public override set dragIndicatorIconTemplate(_val: TemplateRef<any>) {
863
    }
864

865
    /**
866
     * @hidden @internal
867
     */
868
    @WatchChanges()
869
    @Input({ transform: booleanAttribute })
870
    public override get rowEditable(): boolean {
UNCOV
871
        return;
×
872
    }
873

874
    public override set rowEditable(_val: boolean) {
875
    }
876

877
    /**
878
     * @hidden @internal
879
     */
880
    @Input()
881
    public override get pinning() {
UNCOV
882
        return {};
×
883
    }
884
    public override set pinning(_value) {
885
    }
886

887
    /**
888
     * @hidden @internal
889
     */
890
    @Input()
891
    public override get summaryPosition() {
892
        return;
×
893
    }
894

895
    public override set summaryPosition(_value: GridSummaryPosition) {
896
    }
897

898
    /**
899
     * @hidden @internal
900
     */
901
    @Input()
902
    public override get summaryCalculationMode() {
903
        return;
×
904
    }
905

906
    public override set summaryCalculationMode(_value: GridSummaryCalculationMode) {
907
    }
908

909
    /**
910
     * @hidden @internal
911
     */
912
    @Input({ transform: booleanAttribute })
913
    public override get showSummaryOnCollapse() {
914
        return;
×
915
    }
916

917
    public override set showSummaryOnCollapse(_value: boolean) {
918
    }
919

920
    /**
921
     * @hidden @internal
922
     */
923
    public override get hiddenColumnsCount(): number {
924
        return 0;
×
925
    }
926

927
    /**
928
     * @hidden @internal
929
     */
930
    public override get pinnedColumnsCount(): number {
931
        return 0;
×
932
    }
933

934
    /**
935
     * @hidden @internal
936
     */
937
    @Input({ transform: booleanAttribute })
938
    public override get batchEditing(): boolean {
939
        return false;
×
940
    }
941

942
    public override set batchEditing(_val: boolean) {
943
    }
944

945
    /* csSuppress */
946
    public override get selectedRows(): any[] {
UNCOV
947
        if (this.selectionService.getSelectedRows().length === 0) {
×
UNCOV
948
            return [];
×
949
        }
UNCOV
950
        const selectedRowIds = [];
×
UNCOV
951
        this.dataView.forEach(record => {
×
UNCOV
952
            const prev = [];
×
UNCOV
953
            for (const dim of this.rowDimensions) {
×
UNCOV
954
                let currDim = dim;
×
UNCOV
955
                let shouldBreak = false;
×
UNCOV
956
                do {
×
UNCOV
957
                    const key = PivotUtil.getRecordKey(record, currDim);
×
UNCOV
958
                    if (this.selectionService.isPivotRowSelected(key) && !selectedRowIds.find(x => x === record)) {
×
UNCOV
959
                        selectedRowIds.push(record);
×
UNCOV
960
                        shouldBreak = true;
×
UNCOV
961
                        break;
×
962
                    }
UNCOV
963
                    currDim = currDim.childLevel;
×
964
                } while (currDim);
UNCOV
965
                prev.push(dim);
×
UNCOV
966
                if (shouldBreak) {
×
UNCOV
967
                    break;
×
968
                }
969
            }
970

971
        });
972

UNCOV
973
        return selectedRowIds;
×
974
    }
975

976
    /**
977
     * @hidden
978
     */
979
    public override ngOnInit() {
980
        // pivot grid always generates columns automatically.
UNCOV
981
        this.autoGenerate = true;
×
UNCOV
982
        super.ngOnInit();
×
983
    }
984

985
    /**
986
     * @hidden
987
     */
988
    public override ngAfterContentInit() {
989
        // ignore any user defined columns and auto-generate based on pivot config.
UNCOV
990
        this.updateColumns([]);
×
UNCOV
991
        Promise.resolve().then(() => {
×
UNCOV
992
            if (this.autoGenerateConfig) {
×
993
                this.generateConfig();
×
994
            }
UNCOV
995
            this.setupColumns();
×
996
            // Bind to onResourceChange after the columns have initialized the first time to avoid premature initialization.
UNCOV
997
            onResourceChangeHandle(this.destroy$, () => {
×
998
                // Since the columns are kinda static, due to assigning DisplayName on init, they need to be regenerated.
999
                this.setupColumns();
×
1000
            }, this);
1001
        });
UNCOV
1002
        if (this.valueChipTemplateDirective) {
×
1003
            this.valueChipTemplate = this.valueChipTemplateDirective.template;
×
1004
        }
UNCOV
1005
        if (this.rowDimensionHeaderDirective) {
×
1006
            this.rowDimensionHeaderTemplate = this.rowDimensionHeaderDirective.template;
×
1007
        }
1008
    }
1009

1010
    /**
1011
     * @hidden @internal
1012
     */
1013
    public override ngAfterViewInit() {
UNCOV
1014
        Promise.resolve().then(() => {
×
UNCOV
1015
            super.ngAfterViewInit();
×
1016
        });
1017

1018
    }
1019

1020
    /**
1021
     * @hidden @internal
1022
     */
1023
    public ngOnChanges(changes: SimpleChanges) {
UNCOV
1024
        if (changes.superCompactMode && !changes.superCompactMode.isFirstChange()) {
×
1025
            this._shouldUpdateSizes = true;
×
1026
            resizeObservable(this.verticalScrollContainer.displayContainer).pipe(take(1), takeUntil(this.destroy$)).subscribe(() => this.resizeNotify.next());
×
1027
        }
1028
    }
1029

1030
    /**
1031
     * Notifies for dimension change.
1032
     */
1033
    public notifyDimensionChange(regenerateColumns = false) {
×
UNCOV
1034
        if (regenerateColumns) {
×
UNCOV
1035
            this.setupColumns();
×
1036
        }
UNCOV
1037
        this.pipeTrigger++;
×
UNCOV
1038
        this.cdr.detectChanges();
×
1039
    }
1040

1041
    /**
1042
     * Gets the full list of dimensions.
1043
     *
1044
     * @example
1045
     * ```typescript
1046
     * const dimensions = this.grid.allDimensions;
1047
     * ```
1048
     */
1049
    public get allDimensions() {
UNCOV
1050
        const config = this._pivotConfiguration;
×
UNCOV
1051
        if (!config) return [];
×
UNCOV
1052
        return (config.rows || []).concat((config.columns || [])).concat(config.filters || []).filter(x => x !== null && x !== undefined);
×
1053
    }
1054

1055
    protected get allVisibleDimensions() {
UNCOV
1056
        const config = this._pivotConfiguration;
×
UNCOV
1057
        if (!config) return [];
×
UNCOV
1058
        const uniqueVisibleRowDims = this.visibleRowDimensions.filter(dim => !config.rows.find(configRow => configRow.memberName === dim.memberName));
×
UNCOV
1059
        const rows = (config.rows || []).concat(...uniqueVisibleRowDims);
×
UNCOV
1060
        return rows.concat((config.columns || [])).concat(config.filters || []).filter(x => x !== null && x !== undefined);
×
1061
    }
1062

1063
    protected override get shouldResize(): boolean {
UNCOV
1064
        if (!this.dataRowList.first?.cells || this.dataRowList.first.cells.length === 0) {
×
1065
            return false;
×
1066
        }
UNCOV
1067
        const isSizePropChanged = super.shouldResize;
×
UNCOV
1068
        if (isSizePropChanged || this._shouldUpdateSizes) {
×
UNCOV
1069
            this._shouldUpdateSizes = false;
×
UNCOV
1070
            return true;
×
1071
        }
UNCOV
1072
        return false;
×
1073
    }
1074

1075
    protected get emptyBottomSize() {
UNCOV
1076
        return this.totalHeight - (<any>this.verticalScroll).scrollComponent.size;
×
1077
    }
1078

1079
    /** @hidden @internal */
1080
    public createFilterESF(dropdown: any, column: ColumnType, options: OverlaySettings, shouldReatach: boolean) {
UNCOV
1081
        options.outlet = this.outlet;
×
UNCOV
1082
        if (dropdown) {
×
UNCOV
1083
            dropdown.initialize(column, this.overlayService);
×
UNCOV
1084
            dropdown.populateData();
×
UNCOV
1085
            if (shouldReatach) {
×
UNCOV
1086
                const id = this.overlayService.attach(dropdown.element, options);
×
UNCOV
1087
                dropdown.overlayComponentId = id;
×
UNCOV
1088
                return { id, ref: undefined };
×
1089
            }
UNCOV
1090
            return { id: dropdown.overlayComponentId, ref: undefined };
×
1091
        }
1092
    }
1093

1094
    /** @hidden */
1095
    public override featureColumnsWidth() {
UNCOV
1096
        return this.pivotRowWidths || 0;
×
1097
    }
1098

1099
    /* blazorSuppress */
1100
    /**
1101
     * Gets/Sets the value of the `id` attribute.
1102
     *
1103
     * @remarks
1104
     * If not provided it will be automatically generated.
1105
     * @example
1106
     * ```html
1107
     * <igx-pivot-grid [id]="'igx-pivot-1'" [data]="Data"></igx-pivot-grid>
1108
     * ```
1109
     */
1110
    @HostBinding('attr.id')
1111
    @Input()
1112
    public get id(): string {
UNCOV
1113
        return this.p_id;
×
1114
    }
1115
    /* blazorSuppress */
1116
    public set id(value: string) {
1117
        this.p_id = value;
×
1118
    }
1119

1120
    /* treatAsRef */
1121
    /* blazorAlternateType: object */
1122
    /**
1123
     * Gets/Sets the array of data that populates the component.
1124
     * ```html
1125
     * <igx-pivot-grid [data]="Data"></igx-pivot-grid>
1126
     * ```
1127
     */
1128
    @Input()
1129
    public set data(value: any[] | null) {
UNCOV
1130
        this._data = value || [];
×
UNCOV
1131
        if (!this._init) {
×
UNCOV
1132
            if (this.autoGenerateConfig) {
×
UNCOV
1133
                this.generateConfig();
×
1134
            }
UNCOV
1135
            this.setupColumns();
×
UNCOV
1136
            this.reflow();
×
1137
        }
UNCOV
1138
        this.cdr.markForCheck();
×
UNCOV
1139
        if (this.height === null || this.height.indexOf('%') !== -1) {
×
1140
            // If the height will change based on how much data there is, recalculate sizes in igxForOf.
UNCOV
1141
            this.notifyChanges(true);
×
1142
        }
1143
    }
1144

1145
    /* treatAsRef */
1146
    /* blazorAlternateType: object */
1147
    /**
1148
     * Returns an array of data set to the component.
1149
     * ```typescript
1150
     * let data = this.grid.data;
1151
     * ```
1152
     */
1153
    public get data(): any[] | null {
UNCOV
1154
        return this._data;
×
1155
    }
1156

1157
    /**
1158
     * @hidden
1159
     */
1160
    public getContext(rowData, rowIndex): any {
UNCOV
1161
        return {
×
1162
            $implicit: rowData,
1163
            templateID: {
1164
                type: 'dataRow',
1165
                id: null
1166
            },
1167
            index: this.getDataViewIndex(rowIndex, false)
1168
        };
1169
    }
1170

1171
    /**
1172
     * @hidden @internal
1173
     */
1174
    public get pivotRowWidths() {
UNCOV
1175
        return this.visibleRowDimensions.length ? this.visibleRowDimensions.reduce((accumulator, dim) => accumulator + this.rowDimensionWidthToPixels(dim), 0) :
×
1176
            this.rowDimensionWidthToPixels(this.emptyRowDimension);
1177
    }
1178

1179
    /**
1180
     * @hidden @internal
1181
     */
1182
    public rowDimensionWidth(dim): string {
UNCOV
1183
        const isAuto = dim.width && dim.width.indexOf('auto') !== -1;
×
UNCOV
1184
        if (isAuto) {
×
UNCOV
1185
            return dim.autoWidth ? dim.autoWidth + 'px' : 'fit-content';
×
1186
        } else {
UNCOV
1187
            return this.rowDimensionWidthToPixels(dim) + 'px';
×
1188
        }
1189
    }
1190

1191
    /**
1192
     * @hidden @internal
1193
     */
1194
    public rowDimensionWidthToPixels(dim: IPivotDimension): number {
UNCOV
1195
        if (!dim?.width) {
×
UNCOV
1196
            return MINIMUM_COLUMN_WIDTH;
×
1197
        }
UNCOV
1198
        const isPercent = dim.width && dim.width.indexOf('%') !== -1;
×
UNCOV
1199
        const isAuto = dim.width && dim.width.indexOf('auto') !== -1;
×
UNCOV
1200
        if (isPercent) {
×
UNCOV
1201
            return Math.round(parseFloat(dim.width) / 100 * this.calcWidth);
×
UNCOV
1202
        } else if (isAuto) {
×
UNCOV
1203
            return dim.autoWidth;
×
1204
        } else {
UNCOV
1205
            return parseInt(dim.width, 10);
×
1206
        }
1207
    }
1208

1209
    /**
1210
     * @hidden @internal
1211
     */
1212
    public reverseDimensionWidthToPercent(width: number): number {
UNCOV
1213
        return (width * 100 / this.calcWidth);
×
1214
    }
1215

1216
    /** @hidden @internal */
1217
    public get pivotContentCalcWidth() {
UNCOV
1218
        if (!this.platform.isBrowser) {
×
1219
            return undefined;
×
1220
        }
UNCOV
1221
        if (!this.visibleRowDimensions.length) {
×
UNCOV
1222
            return Math.max(0, this.calcWidth - this.pivotRowWidths);
×
1223
        }
1224

UNCOV
1225
        const totalDimWidth = this.visibleRowDimensions.length > 0 ?
×
UNCOV
1226
            this.visibleRowDimensions.map((dim) => this.rowDimensionWidthToPixels(dim)).reduce((prev, cur) => prev + cur) :
×
1227
            0;
UNCOV
1228
        return this.calcWidth - totalDimWidth;
×
1229
    }
1230

1231
    /** @hidden @internal */
1232
    public get pivotPinnedStartWidth() {
UNCOV
1233
        return !this._init ? this.pinnedStartWidth : 0;
×
1234
    }
1235

1236
    /** @hidden @internal */
1237
    public get pivotPinnedEndWidth() {
UNCOV
1238
        return !this._init ? this.pinnedEndWidth : 0;
×
1239
    }
1240

1241
    /** @hidden @internal */
1242
    public get pivotUnpinnedWidth() {
UNCOV
1243
        return this.unpinnedWidth || 0;
×
1244
    }
1245

1246
    /** @hidden @internal */
1247
    public get rowDimensions() {
UNCOV
1248
        return this.pivotConfiguration.rows?.filter(x => x.enabled) || [];
×
1249
    }
1250

1251
    /** @hidden @internal */
1252
    public set visibleRowDimensions(value: IPivotDimension[]) {
UNCOV
1253
        this._visibleRowDimensions = value;
×
1254
    }
1255

1256
    public get visibleRowDimensions() {
UNCOV
1257
        return this._visibleRowDimensions || this.rowDimensions;
×
1258
    }
1259

1260
    /** @hidden @internal */
1261
    public get columnDimensions() {
UNCOV
1262
        return this.pivotConfiguration.columns?.filter(x => x.enabled) || [];
×
1263
    }
1264

1265
    /** @hidden @internal */
1266
    public get filterDimensions() {
UNCOV
1267
        return this.pivotConfiguration.filters?.filter(x => x.enabled) || [];
×
1268
    }
1269

1270
    /** @hidden @internal */
1271
    public get values() {
UNCOV
1272
        return this.pivotConfiguration.values?.filter(x => x.enabled) || [];
×
1273
    }
1274

1275
    public toggleColumn(col: IgxColumnComponent) {
UNCOV
1276
        const state = this.columnGroupStates.get(col.field);
×
UNCOV
1277
        const newState = !state;
×
UNCOV
1278
        this.columnGroupStates.set(col.field, newState);
×
UNCOV
1279
        this.toggleRowGroup(col, newState);
×
UNCOV
1280
        this.reflow();
×
1281
    }
1282

1283
    /**
1284
     * @hidden @internal
1285
     */
1286
    public override isRecordPinnedByIndex(_rowIndex: number) {
1287
        return false;
×
1288
    }
1289

1290
    /**
1291
     * @hidden @internal
1292
     */
1293
    public override toggleColumnVisibility(_args: IColumnVisibilityChangedEventArgs) {
1294
        return;
×
1295
    }
1296

1297
    /**
1298
     * @hidden @internal
1299
     */
1300
    public override expandAll() {
1301
    }
1302

1303
    /**
1304
     * @hidden @internal
1305
     */
1306
    public override collapseAll() {
1307
    }
1308

1309
    /**
1310
     * @hidden @internal
1311
     */
1312
    public override expandRow(_rowID: any) {
1313
    }
1314

1315
    /**
1316
     * @hidden @internal
1317
     */
1318
    public override collapseRow(_rowID: any) {
1319
    }
1320

1321
    /**
1322
     * @hidden @internal
1323
     */
1324
    public override get pinnedRows(): IgxGridRowComponent[] {
UNCOV
1325
        return;
×
1326
    }
1327

1328
    /**
1329
     * @hidden @internal
1330
     */
1331
    @Input()
1332
    public override get totalRecords(): number {
1333
        return;
×
1334
    }
1335

1336
    public override set totalRecords(_total: number) {
1337
    }
1338

1339
    /**
1340
     * @hidden @internal
1341
     */
1342
    public override moveColumn(_column: IgxColumnComponent, _target: IgxColumnComponent, _pos: DropPosition = DropPosition.AfterDropTarget) {
×
1343
    }
1344

1345
    /**
1346
     * @hidden @internal
1347
     */
1348
    public override addRow(_data: any): void {
1349
    }
1350

1351
    /**
1352
     * @hidden @internal
1353
     */
1354
    public override deleteRow(_rowSelector: any): any {
1355
    }
1356

1357
    /**
1358
     * @hidden @internal
1359
     */
1360
    public override updateCell(_value: any, _rowSelector: any, _column: string): void {
1361
    }
1362

1363
    /**
1364
     * @hidden @internal
1365
     */
1366
    public override updateRow(_value: any, _rowSelector: any): void {
1367
    }
1368

1369
    /**
1370
     * @hidden @internal
1371
     */
1372
    public override enableSummaries(..._rest) {
1373
    }
1374

1375
    /**
1376
     * @hidden @internal
1377
     */
1378
    public override disableSummaries(..._rest) {
1379
    }
1380

1381
    /**
1382
     * @hidden @internal
1383
     */
1384
    public override pinColumn(_columnName: string | IgxColumnComponent, _index?): boolean {
1385
        return;
×
1386
    }
1387

1388
    /**
1389
     * @hidden @internal
1390
     */
1391
    public override unpinColumn(_columnName: string | IgxColumnComponent, _index?): boolean {
1392
        return;
×
1393
    }
1394

1395
    /**
1396
     * @hidden @internal
1397
     */
1398
    public override pinRow(_rowID: any, _index?: number, _row?: RowType): boolean {
1399
        return;
×
1400
    }
1401

1402
    /**
1403
     * @hidden @internal
1404
     */
1405
    public override unpinRow(_rowID: any, _row?: RowType): boolean {
1406
        return;
×
1407
    }
1408

1409
    /**
1410
     * @hidden @internal
1411
     */
1412
    public override get pinnedRowHeight() {
UNCOV
1413
        return;
×
1414
    }
1415

1416
    /**
1417
     * @hidden @internal
1418
     */
1419
    public override get hasEditableColumns(): boolean {
1420
        return;
×
1421
    }
1422

1423
    /**
1424
     * @hidden @internal
1425
     */
1426
    public override get hasSummarizedColumns(): boolean {
UNCOV
1427
        return;
×
1428
    }
1429

1430
    /**
1431
     * @hidden @internal
1432
     */
1433
    public override get hasMovableColumns(): boolean {
UNCOV
1434
        return;
×
1435
    }
1436

1437
    /**
1438
     * @hidden @internal
1439
     */
1440
    public override get pinnedDataView(): any[] {
UNCOV
1441
        return [];
×
1442
    }
1443

1444
    /**
1445
     * @hidden @internal
1446
     */
1447
    public override openAdvancedFilteringDialog(_overlaySettings?: OverlaySettings) {
1448
    }
1449

1450
    /**
1451
     * @hidden @internal
1452
     */
1453
    public override closeAdvancedFilteringDialog(_applyChanges: boolean) {
1454
    }
1455

1456
    /**
1457
     * @hidden @internal
1458
     */
1459
    public override endEdit(_commit = true, _event?: Event): boolean {
×
1460
        return;
×
1461
    }
1462

1463
    /**
1464
     * @hidden @internal
1465
     */
1466
    public override beginAddRowById(_rowID: any, _asChild?: boolean): void {
1467
    }
1468

1469
    /**
1470
     * @hidden @internal
1471
     */
1472
    public override beginAddRowByIndex(_index: number): void {
1473
    }
1474

1475
    /**
1476
     * @hidden @internal
1477
     */
1478
    public override clearSearch() { }
1479

1480
    /**
1481
    * @hidden @internal
1482
    */
1483
    public override refreshSearch(_updateActiveInfo?: boolean, _endEdit = true): number {
×
UNCOV
1484
        return 0;
×
1485
    }
1486

1487
    /**
1488
    * @hidden @internal
1489
    */
1490
    public override findNext(_text: string, _caseSensitive?: boolean, _exactMatch?: boolean): number {
1491
        return 0;
×
1492
    }
1493

1494
    /**
1495
    * @hidden @internal
1496
    */
1497
    public override findPrev(_text: string, _caseSensitive?: boolean, _exactMatch?: boolean): number {
1498
        return 0;
×
1499
    }
1500

1501
    /**
1502
    * @hidden @internal
1503
    */
1504
    public override getNextCell(currRowIndex: number, curVisibleColIndex: number,
1505
        callback: (IgxColumnComponent) => boolean = null): ICellPosition {
×
1506
        return super.getNextCell(currRowIndex, curVisibleColIndex, callback);
×
1507
    }
1508

1509
    /**
1510
    * @hidden @internal
1511
    */
1512
    public override getPreviousCell(currRowIndex: number, curVisibleColIndex: number,
1513
        callback: (IgxColumnComponent) => boolean = null): ICellPosition {
×
1514
        return super.getPreviousCell(currRowIndex, curVisibleColIndex, callback);
×
1515
    }
1516

1517
    /**
1518
    * @hidden @internal
1519
    */
1520
    public override getPinnedStartWidth(takeHidden = false) {
×
UNCOV
1521
        return super.getPinnedStartWidth(takeHidden);
×
1522
    }
1523

1524
    /**
1525
     * @hidden @internal
1526
     */
1527
    public override get totalHeight() {
UNCOV
1528
        return this.calcHeight;
×
1529
    }
1530

1531
    public getColumnGroupExpandState(col: IgxColumnComponent) {
UNCOV
1532
        const state = this.columnGroupStates.get(col.field);
×
1533
        // columns are expanded by default?
UNCOV
1534
        return state !== undefined && state !== null ? state : false;
×
1535
    }
1536

1537
    public toggleRowGroup(col: IgxColumnComponent, newState: boolean) {
UNCOV
1538
        if (!col) return;
×
UNCOV
1539
        if (this.hasMultipleValues) {
×
UNCOV
1540
            const parentCols = col.parent ? col.parent.children.toArray() : this._autoGeneratedCols.filter(x => x.level === 0);
×
UNCOV
1541
            const siblingCol = parentCols.filter(x => x.header === col.header && x !== col)[0];
×
UNCOV
1542
            const currIndex = parentCols.indexOf(col);
×
UNCOV
1543
            const siblingIndex = parentCols.indexOf(siblingCol);
×
UNCOV
1544
            if (currIndex < siblingIndex) {
×
1545
                // clicked on the full hierarchy header
UNCOV
1546
                this.resolveToggle(col, newState);
×
UNCOV
1547
                siblingCol.headerTemplate = this.headerTemplate;
×
1548
            } else {
1549
                // clicked on summary parent column that contains just the measures
UNCOV
1550
                col.headerTemplate = undefined;
×
UNCOV
1551
                this.resolveToggle(siblingCol, newState);
×
1552
            }
1553
        } else {
UNCOV
1554
            const parentCols = col.parent ? col.parent.children : this._autoGeneratedCols.filter(x => x.level === 0);
×
UNCOV
1555
            const fieldColumn = parentCols.filter(x => x.header === col.header && !x.columnGroup)[0];
×
UNCOV
1556
            const groupColumn = parentCols.filter(x => x.header === col.header && x.columnGroup)[0];
×
UNCOV
1557
            this.resolveToggle(groupColumn, newState);
×
UNCOV
1558
            if (newState) {
×
UNCOV
1559
                fieldColumn.headerTemplate = this.headerTemplate;
×
1560
            } else {
1561
                fieldColumn.headerTemplate = undefined;
×
1562
            }
1563
        }
1564
    }
1565

1566
    /**
1567
    * @hidden @internal
1568
    */
1569
    public override setupColumns() {
UNCOV
1570
        super.setupColumns();
×
1571
    }
1572

1573
    /**
1574
    * @hidden @internal
1575
    */
1576
    public override dataRebinding(event: IForOfDataChangingEventArgs) {
UNCOV
1577
        if (this.hasHorizontalLayout) {
×
UNCOV
1578
            this.dimensionDataColumns = this.generateDimensionColumns();
×
1579
        }
1580

UNCOV
1581
        super.dataRebinding(event);
×
1582
    }
1583

1584
    /**
1585
     * Auto-sizes row dimension cells.
1586
     *
1587
     * @remarks
1588
     * Only sizes based on the dimension cells in view.
1589
     * @example
1590
     * ```typescript
1591
     * this.grid.autoSizeRowDimension(dimension);
1592
     * ```
1593
     * @param dimension The row dimension to size.
1594
     */
1595
    public autoSizeRowDimension(dimension: IPivotDimension) {
UNCOV
1596
        if (this.getDimensionType(dimension) === PivotDimensionType.Row) {
×
UNCOV
1597
            const relatedDims: string[] = PivotUtil.flatten([dimension]).map((x: IPivotDimension) => x.memberName);
×
UNCOV
1598
            const contentCollection = this.getContentCollection(dimension);
×
UNCOV
1599
            const content = contentCollection.filter(x => relatedDims.indexOf(x.dimension.memberName) !== -1);
×
UNCOV
1600
            const headers = content.map(x => x.headerGroups.toArray()).flat().map(x => x.header && x.header.refInstance);
×
UNCOV
1601
            if (this.pivotUI.showRowHeaders) {
×
1602
                const dimensionHeader = this.theadRow.rowDimensionHeaders.find(x => x.column.field === dimension.memberName);
×
1603
                headers.push(dimensionHeader);
×
1604
            }
UNCOV
1605
            const autoWidth = this.getLargesContentWidth(headers);
×
UNCOV
1606
            if (dimension.width === "auto") {
×
1607
                dimension.autoWidth = parseFloat(autoWidth);
×
1608
            } else {
UNCOV
1609
                dimension.width = autoWidth;
×
1610
            }
UNCOV
1611
            this.pipeTrigger++;
×
UNCOV
1612
            this.cdr.detectChanges();
×
1613
        }
1614
    }
1615

1616
    /**
1617
     * Inserts dimension in target collection by type at specified index or at the collection's end.
1618
     *
1619
     * @example
1620
     * ```typescript
1621
     * this.grid.insertDimensionAt(dimension, PivotDimensionType.Row, 1);
1622
     * ```
1623
     * @param dimension The dimension that will be added.
1624
     * @param targetCollectionType The target collection type to add to. Can be Row, Column or Filter.
1625
     * @param index The index in the collection at which to add.
1626
     * This parameter is optional. If not set it will add it to the end of the collection.
1627
     */
1628
    public insertDimensionAt(dimension: IPivotDimension, targetCollectionType: PivotDimensionType, index?: number) {
UNCOV
1629
        const targetCollection = this.getDimensionsByType(targetCollectionType);
×
UNCOV
1630
        if (index !== undefined) {
×
UNCOV
1631
            targetCollection.splice(index, 0, dimension);
×
1632
        } else {
UNCOV
1633
            targetCollection.push(dimension);
×
1634
        }
UNCOV
1635
        if (targetCollectionType === PivotDimensionType.Column) {
×
UNCOV
1636
            this.setupColumns();
×
1637
        }
UNCOV
1638
        this.pipeTrigger++;
×
UNCOV
1639
        this.dimensionsChange.emit({ dimensions: targetCollection, dimensionCollectionType: targetCollectionType });
×
UNCOV
1640
        if (targetCollectionType === PivotDimensionType.Filter) {
×
UNCOV
1641
            this.dimensionDataColumns = this.generateDimensionColumns();
×
UNCOV
1642
            this.reflow();
×
1643
        }
UNCOV
1644
        this.pivotConfigurationChange.emit({ pivotConfiguration: this.pivotConfiguration });
×
1645
    }
1646

1647
    /**
1648
     * Move dimension from its currently collection to the specified target collection by type at specified index or at the collection's end.
1649
     *
1650
     * @example
1651
     * ```typescript
1652
     * this.grid.moveDimension(dimension, PivotDimensionType.Row, 1);
1653
     * ```
1654
     * @param dimension The dimension that will be moved.
1655
     * @param targetCollectionType The target collection type to move it to. Can be Row, Column or Filter.
1656
     * @param index The index in the collection at which to add.
1657
     * This parameter is optional. If not set it will add it to the end of the collection.
1658
     */
1659
    public moveDimension(dimension: IPivotDimension, targetCollectionType: PivotDimensionType, index?: number) {
UNCOV
1660
        const prevCollectionType = this.getDimensionType(dimension);
×
UNCOV
1661
        if (prevCollectionType === null) return;
×
1662
        // remove from old collection
UNCOV
1663
        this._removeDimensionInternal(dimension);
×
1664
        // add to target
UNCOV
1665
        this.insertDimensionAt(dimension, targetCollectionType, index);
×
1666

UNCOV
1667
        if (prevCollectionType === PivotDimensionType.Column) {
×
UNCOV
1668
            this.setupColumns();
×
1669
        }
1670
    }
1671

1672
    /**
1673
     * Removes dimension from its currently collection.
1674
     * @remarks
1675
     * This is different than toggleDimension that enabled/disables the dimension.
1676
     * This completely removes the specified dimension from the collection.
1677
     * @example
1678
     * ```typescript
1679
     * this.grid.removeDimension(dimension);
1680
     * ```
1681
     * @param dimension The dimension to be removed.
1682
     */
1683
    public removeDimension(dimension: IPivotDimension) {
UNCOV
1684
        const prevCollectionType = this.getDimensionType(dimension);
×
UNCOV
1685
        this._removeDimensionInternal(dimension);
×
UNCOV
1686
        if (prevCollectionType === PivotDimensionType.Column) {
×
UNCOV
1687
            this.setupColumns();
×
1688
        }
UNCOV
1689
        if (prevCollectionType === PivotDimensionType.Filter) {
×
UNCOV
1690
            this.reflow();
×
1691
        }
UNCOV
1692
        this.pipeTrigger++;
×
UNCOV
1693
        this.cdr.detectChanges();
×
1694
    }
1695

1696
    /**
1697
     * Toggles the dimension's enabled state on or off.
1698
     * @remarks
1699
     * The dimension remains in its current collection. This just changes its enabled state.
1700
     * @example
1701
     * ```typescript
1702
     * this.grid.toggleDimension(dimension);
1703
     * ```
1704
     * @param dimension The dimension to be toggled.
1705
     */
1706
    public toggleDimension(dimension: IPivotDimension) {
UNCOV
1707
        const dimType = this.getDimensionType(dimension);
×
UNCOV
1708
        if (dimType === null) return;
×
UNCOV
1709
        const collection = this.getDimensionsByType(dimType);
×
UNCOV
1710
        dimension.enabled = !dimension.enabled;
×
UNCOV
1711
        if (dimType === PivotDimensionType.Column) {
×
UNCOV
1712
            this.setupColumns();
×
1713
        }
UNCOV
1714
        if (!dimension.enabled && dimension.filter) {
×
UNCOV
1715
            this.filteringService.clearFilter(dimension.memberName);
×
1716
        }
UNCOV
1717
        this.pipeTrigger++;
×
UNCOV
1718
        this.dimensionsChange.emit({ dimensions: collection, dimensionCollectionType: dimType });
×
UNCOV
1719
        this.cdr.detectChanges();
×
UNCOV
1720
        if (dimType === PivotDimensionType.Filter) {
×
UNCOV
1721
            this.reflow();
×
1722
        }
UNCOV
1723
        this.pivotConfigurationChange.emit({ pivotConfiguration: this.pivotConfiguration });
×
1724
    }
1725

1726
    /**
1727
     * Inserts value at specified index or at the end.
1728
     *
1729
     * @example
1730
     * ```typescript
1731
     * this.grid.insertValueAt(value, 1);
1732
     * ```
1733
     * @param value The value definition that will be added.
1734
     * @param index The index in the collection at which to add.
1735
     * This parameter is optional. If not set it will add it to the end of the collection.
1736
     */
1737
    public insertValueAt(value: IPivotValue, index?: number) {
UNCOV
1738
        if (!this.pivotConfiguration.values) {
×
UNCOV
1739
            this.pivotConfiguration.values = [];
×
1740
        }
UNCOV
1741
        const values = this.pivotConfiguration.values;
×
UNCOV
1742
        if (index !== undefined) {
×
UNCOV
1743
            values.splice(index, 0, value);
×
1744
        } else {
UNCOV
1745
            values.push(value);
×
1746
        }
UNCOV
1747
        this.setupColumns();
×
UNCOV
1748
        this.pipeTrigger++;
×
UNCOV
1749
        this.cdr.detectChanges();
×
UNCOV
1750
        this.valuesChange.emit({ values });
×
UNCOV
1751
        this.pivotConfigurationChange.emit({ pivotConfiguration: this.pivotConfiguration });
×
1752
    }
1753

1754
    /**
1755
     * Move value from its currently at specified index or at the end.
1756
     *
1757
     * @example
1758
     * ```typescript
1759
     * this.grid.moveValue(value, 1);
1760
     * ```
1761
     * @param value The value that will be moved.
1762
     * @param index The index in the collection at which to add.
1763
     * This parameter is optional. If not set it will add it to the end of the collection.
1764
     */
1765
    public moveValue(value: IPivotValue, index?: number) {
UNCOV
1766
        if (this.pivotConfiguration.values.indexOf(value) === -1) return;
×
1767
        // remove from old index
UNCOV
1768
        this.removeValue(value);
×
1769
        // add to new
UNCOV
1770
        this.insertValueAt(value, index);
×
1771
    }
1772

1773
    /**
1774
     * Removes value from collection.
1775
     * @remarks
1776
     * This is different than toggleValue that enabled/disables the value.
1777
     * This completely removes the specified value from the collection.
1778
     * @example
1779
     * ```typescript
1780
     * this.grid.removeValue(dimension);
1781
     * ```
1782
     * @param value The value to be removed.
1783
     */
1784
    public removeValue(value: IPivotValue,) {
UNCOV
1785
        const values = this.pivotConfiguration.values;
×
UNCOV
1786
        const currentIndex = values.indexOf(value);
×
UNCOV
1787
        if (currentIndex !== -1) {
×
UNCOV
1788
            values.splice(currentIndex, 1);
×
UNCOV
1789
            this.setupColumns();
×
UNCOV
1790
            this.pipeTrigger++;
×
UNCOV
1791
            this.valuesChange.emit({ values });
×
UNCOV
1792
            this.pivotConfigurationChange.emit({ pivotConfiguration: this.pivotConfiguration });
×
1793
        }
1794
    }
1795

1796
    /**
1797
     * Toggles the value's enabled state on or off.
1798
     * @remarks
1799
     * The value remains in its current collection. This just changes its enabled state.
1800
     * @example
1801
     * ```typescript
1802
     * this.grid.toggleValue(value);
1803
     * ```
1804
     * @param value The value to be toggled.
1805
     */
1806
    public toggleValue(value: IPivotValue) {
UNCOV
1807
        if (this.pivotConfiguration.values.indexOf(value) === -1) return;
×
UNCOV
1808
        value.enabled = !value.enabled;
×
UNCOV
1809
        this.setupColumns();
×
UNCOV
1810
        this.pipeTrigger++;
×
UNCOV
1811
        this.valuesChange.emit({ values: this.pivotConfiguration.values });
×
UNCOV
1812
        this.reflow();
×
UNCOV
1813
        this.pivotConfigurationChange.emit({ pivotConfiguration: this.pivotConfiguration });
×
1814
    }
1815

1816
    /**
1817
     * Sort the dimension and its children in the provided direction.
1818
     * @example
1819
     * ```typescript
1820
     * this.grid.sortDimension(dimension, SortingDirection.Asc);
1821
     * ```
1822
     * @param value The value to be toggled.
1823
     */
1824
    public sortDimension(dimension: IPivotDimension, sortDirection: SortingDirection) {
UNCOV
1825
        const dimensionType = this.getDimensionType(dimension);
×
UNCOV
1826
        dimension.sortDirection = sortDirection;
×
1827
        // apply same sort direction to children.
UNCOV
1828
        let dim = dimension;
×
UNCOV
1829
        if (this.pivotUI.rowLayout === PivotRowLayoutType.Vertical) {
×
UNCOV
1830
            while (dim.childLevel) {
×
UNCOV
1831
                dim.childLevel.sortDirection = dimension.sortDirection;
×
UNCOV
1832
                dim = dim.childLevel;
×
1833
            }
1834
        }
1835

UNCOV
1836
        this.pipeTrigger++;
×
UNCOV
1837
        this.dimensionsSortingExpressionsChange.emit(this.dimensionsSortingExpressions);
×
UNCOV
1838
        if (dimensionType === PivotDimensionType.Column) {
×
UNCOV
1839
            this.setupColumns();
×
1840
        }
UNCOV
1841
        this.cdr.detectChanges();
×
UNCOV
1842
        this.pivotConfigurationChange.emit({ pivotConfiguration: this.pivotConfiguration });
×
1843
    }
1844

1845
    /**
1846
     * Filters a single `IPivotDimension`.
1847
     *
1848
     * @example
1849
     * ```typescript
1850
     * public filter() {
1851
     *      const set = new Set();
1852
     *      set.add('Value 1');
1853
     *      set.add('Value 2');
1854
     *      this.grid1.filterDimension(this.pivotConfigHierarchy.rows[0], set, IgxStringFilteringOperand.instance().condition('in'));
1855
     * }
1856
     * ```
1857
     */
1858
    public filterDimension(dimension: IPivotDimension, value: any, conditionOrExpressionTree?: IFilteringOperation | IFilteringExpressionsTree) {
UNCOV
1859
        this.filteringService.filter(dimension.memberName, value, conditionOrExpressionTree);
×
UNCOV
1860
        const dimensionType = this.getDimensionType(dimension);
×
UNCOV
1861
        if (dimensionType === PivotDimensionType.Column) {
×
UNCOV
1862
            this.setupColumns();
×
1863
        }
UNCOV
1864
        this.cdr.detectChanges();
×
1865
    }
1866

1867
    /**
1868
     * @hidden @internal
1869
     */
1870
    public getRowDimensionByName(memberName: string) {
UNCOV
1871
        const visibleRows = this.pivotUI.rowLayout === PivotRowLayoutType.Vertical ?
×
1872
            this.pivotConfiguration.rows :
1873
            PivotUtil.flatten(this.pivotConfiguration.rows);
UNCOV
1874
        const dimIndex = visibleRows.findIndex((target) => target.memberName === memberName);
×
UNCOV
1875
        const dim = visibleRows[dimIndex];
×
UNCOV
1876
        return dim;
×
1877
    }
1878

1879
    /**
1880
     * @hidden @internal
1881
     */
1882
    public getDimensionsByType(dimension: PivotDimensionType) {
UNCOV
1883
        switch (dimension) {
×
1884
            case PivotDimensionType.Row:
UNCOV
1885
                if (!this.pivotConfiguration.rows) {
×
1886
                    this.pivotConfiguration.rows = [];
×
1887
                }
UNCOV
1888
                return this.pivotConfiguration.rows;
×
1889
            case PivotDimensionType.Column:
UNCOV
1890
                if (!this.pivotConfiguration.columns) {
×
1891
                    this.pivotConfiguration.columns = [];
×
1892
                }
UNCOV
1893
                return this.pivotConfiguration.columns;
×
1894
            case PivotDimensionType.Filter:
UNCOV
1895
                if (!this.pivotConfiguration.filters) {
×
UNCOV
1896
                    this.pivotConfiguration.filters = [];
×
1897
                }
UNCOV
1898
                return this.pivotConfiguration.filters;
×
1899
            default:
UNCOV
1900
                return null;
×
1901
        }
1902
    }
1903

1904
    /**
1905
     * @hidden @internal
1906
     */
1907
    public resizeRowDimensionPixels(dimension: IPivotDimension, newWidth: number) {
UNCOV
1908
        const isPercentageWidth = dimension.width && typeof dimension.width === 'string' && dimension.width.indexOf('%') !== -1;
×
UNCOV
1909
        if (isPercentageWidth) {
×
UNCOV
1910
            dimension.width = this.reverseDimensionWidthToPercent(newWidth).toFixed(2) + '%';
×
1911
        } else {
UNCOV
1912
            dimension.width = newWidth + 'px';
×
1913
        }
1914

1915
        // Notify the grid to reflow, to update if horizontal scrollbar needs to be rendered/removed.
UNCOV
1916
        this.pipeTrigger++;
×
UNCOV
1917
        this.cdr.detectChanges();
×
1918
    }
1919

1920
    /*
1921
    * @hidden
1922
    * @internal
1923
    */
1924
    protected _removeDimensionInternal(dimension) {
UNCOV
1925
        const prevCollectionType = this.getDimensionType(dimension);
×
UNCOV
1926
        if (prevCollectionType === null) return;
×
UNCOV
1927
        const prevCollection = this.getDimensionsByType(prevCollectionType);
×
UNCOV
1928
        const currentIndex = prevCollection.indexOf(dimension);
×
UNCOV
1929
        prevCollection.splice(currentIndex, 1);
×
UNCOV
1930
        this.pipeTrigger++;
×
UNCOV
1931
        this.cdr.detectChanges();
×
1932
    }
1933

1934
    protected getDimensionType(dimension: IPivotDimension): PivotDimensionType {
UNCOV
1935
        return PivotUtil.flatten(this.pivotConfiguration.rows).indexOf(dimension) !== -1 ? PivotDimensionType.Row :
×
1936
            PivotUtil.flatten(this.pivotConfiguration.columns).indexOf(dimension) !== -1 ? PivotDimensionType.Column :
×
1937
                (!!this.pivotConfiguration.filters && PivotUtil.flatten(this.pivotConfiguration.filters).indexOf(dimension) !== -1) ?
×
1938
                    PivotDimensionType.Filter : null;
1939
    }
1940

1941
    protected getPivotRowHeaderContentWidth(headerGroup: IgxPivotRowHeaderGroupComponent) {
1942
        const headerSizes = this.getHeaderCellWidth(headerGroup.nativeElement);
×
1943
        return headerSizes.width + headerSizes.padding;
×
1944
    }
1945

1946
    protected getLargesContentWidth(contents: ElementRef[]): string {
UNCOV
1947
        const largest = new Map<number, number>();
×
UNCOV
1948
        if (contents.length > 0) {
×
UNCOV
1949
            const cellsContentWidths = [];
×
UNCOV
1950
            contents.forEach((elem) => {
×
UNCOV
1951
                elem instanceof IgxPivotRowHeaderGroupComponent ?
×
1952
                    cellsContentWidths.push(this.getPivotRowHeaderContentWidth(elem)) :
1953
                    cellsContentWidths.push(this.getHeaderCellWidth(elem.nativeElement).width);
1954
            });
UNCOV
1955
            const index = cellsContentWidths.indexOf(Math.max(...cellsContentWidths));
×
UNCOV
1956
            const cellStyle = this.document.defaultView.getComputedStyle(contents[index].nativeElement);
×
UNCOV
1957
            const cellPadding = parseFloat(cellStyle.paddingLeft) + parseFloat(cellStyle.paddingRight) +
×
1958
                parseFloat(cellStyle.borderLeftWidth) + parseFloat(cellStyle.borderRightWidth);
UNCOV
1959
            largest.set(Math.max(...cellsContentWidths), cellPadding);
×
1960
        }
UNCOV
1961
        const largestCell = Math.max(...Array.from(largest.keys()));
×
UNCOV
1962
        const width = Math.ceil(largestCell + largest.get(largestCell));
×
1963

UNCOV
1964
        if (Number.isNaN(width)) {
×
1965
            return null;
×
1966
        } else {
UNCOV
1967
            return width + 'px';
×
1968
        }
1969
    }
1970

1971
    /** @hidden @internal */
1972
    public get hasHorizontalLayout() {
UNCOV
1973
        return this.pivotUI.rowLayout === PivotRowLayoutType.Horizontal;
×
1974
    }
1975

1976
    /**
1977
    * @hidden
1978
    */
1979
    public get hasMultipleValues() {
UNCOV
1980
        return this.values.length > 1;
×
1981
    }
1982

1983
    /**
1984
    * @hidden
1985
    */
1986
    public get excelStyleFilterMaxHeight() {
1987
        // max 10 rows, row size depends on grid size
UNCOV
1988
        const maxHeight = this.renderedRowHeight * 10;
×
UNCOV
1989
        return `${maxHeight}px`;
×
1990
    }
1991

1992
    /**
1993
    * @hidden
1994
    */
1995
    public get excelStyleFilterMinHeight(): string {
1996
        // min 5 rows, row size depends on grid size
UNCOV
1997
        const minHeight = this.renderedRowHeight * 5;
×
UNCOV
1998
        return `${minHeight}px`;
×
1999
    }
2000

2001
    /** @hidden @internal */
2002
    public override get activeDescendant(): string | undefined {
UNCOV
2003
        if (this.navigation.isRowHeaderActive || this.navigation.isRowDimensionHeaderActive) {
×
UNCOV
2004
            return;
×
2005
        }
UNCOV
2006
        return super.activeDescendant;
×
2007
    }
2008

2009
    /** @hidden @internal */
2010
    public get headerRowActiveDescendant() {
UNCOV
2011
        const activeElem = this.navigation.activeNode;
×
UNCOV
2012
        if (!activeElem || !Object.keys(activeElem).length || !this.navigation.isRowHeaderActive) {
×
UNCOV
2013
            return null;
×
2014
        }
2015

UNCOV
2016
        const rowDimensions = this.rowDimensionContentCollection.length > 0 ?
×
2017
            this.rowDimensionContentCollection.toArray() :
2018
            this.rowDimensionMrlComponent.rowDimensionContentCollection.toArray();
2019

UNCOV
2020
        const rowDimensionContentActive = rowDimensions.find(rd => rd && rd.headerGroups?.some(hg => hg.active));
×
UNCOV
2021
        const activeHeader = rowDimensionContentActive?.headerGroups.toArray().find(hg => hg.active);
×
2022

UNCOV
2023
        return activeHeader ? `${this.id}_${activeHeader.title}` : null;
×
2024
    }
2025

2026
    protected resolveToggle(groupColumn: ColumnType, state: boolean) {
UNCOV
2027
        if (!groupColumn) return;
×
UNCOV
2028
        groupColumn.hidden = state;
×
UNCOV
2029
        this.columnGroupStates.set(groupColumn.field, state);
×
UNCOV
2030
        const childrenTotal = this.hasMultipleValues ?
×
UNCOV
2031
            groupColumn.children.filter(x => x.columnGroup && x.children.filter(y => !y.columnGroup).length === this.values.length) :
×
UNCOV
2032
            groupColumn.children.filter(x => !x.columnGroup);
×
UNCOV
2033
        const childrenSubgroups = this.hasMultipleValues ?
×
UNCOV
2034
            groupColumn.children.filter(x => x.columnGroup && x.children.filter(y => !y.columnGroup).length === 0) :
×
UNCOV
2035
            groupColumn.children.filter(x => x.columnGroup);
×
UNCOV
2036
        childrenTotal.forEach(group => {
×
UNCOV
2037
            const newState = this.columnGroupStates.get(group.field) || state;
×
UNCOV
2038
            if (newState) {
×
UNCOV
2039
                group.headerTemplate = this.headerTemplate;
×
2040
            } else {
UNCOV
2041
                group.headerTemplate = undefined;
×
2042
            }
2043
        });
UNCOV
2044
        if (!groupColumn.hidden && childrenSubgroups.length > 0) {
×
UNCOV
2045
            childrenSubgroups.forEach(group => {
×
UNCOV
2046
                const newState = this.columnGroupStates.get(group.field) || state;
×
UNCOV
2047
                this.resolveToggle(group, newState);
×
2048
            });
2049
        }
2050
    }
2051

2052
    protected override buildDataView(data: any[]) {
UNCOV
2053
        this._dataView = data;
×
2054
    }
2055

2056
    /**
2057
     * @hidden @internal
2058
     */
2059
    protected override getDataBasedBodyHeight(): number {
UNCOV
2060
        const dvl = this.dataView?.length || 0;
×
UNCOV
2061
        return dvl < this._defaultTargetRecordNumber ? 0 : this.defaultTargetBodyHeight;
×
2062
    }
2063

2064
    protected override horizontalScrollHandler(event) {
UNCOV
2065
        const scrollLeft = event.target.scrollLeft;
×
UNCOV
2066
        this.theadRow.headerContainers.forEach(headerForOf => {
×
UNCOV
2067
            headerForOf.onHScroll(scrollLeft);
×
2068
        });
UNCOV
2069
        super.horizontalScrollHandler(event);
×
2070
    }
2071

2072
    protected override verticalScrollHandler(event) {
2073
        this.verticalRowDimScrollContainers.forEach(x => {
×
2074
            x.onScroll(event);
×
2075
        });
2076
        super.verticalScrollHandler(event);
×
2077
    }
2078

2079
    /**
2080
     * @hidden
2081
     */
2082
    protected override autogenerateColumns() {
UNCOV
2083
        let columns = [];
×
UNCOV
2084
        const data = this.gridAPI.filterDataByExpressions(this.filteringExpressionsTree);
×
UNCOV
2085
        this.dimensionDataColumns = this.generateDimensionColumns();
×
UNCOV
2086
        const flattenedColumnsWithSorting = PivotUtil.flatten(this.columnDimensions).filter(dim => dim.sortDirection);
×
UNCOV
2087
        const expressions = flattenedColumnsWithSorting.length > 0 ? PivotSortUtil.generateDimensionSortingExpressions(flattenedColumnsWithSorting) : [];
×
UNCOV
2088
        let sortedData = data;
×
UNCOV
2089
        if (expressions.length > 0) {
×
UNCOV
2090
            sortedData = DataUtil.sort(cloneArray(data), expressions, this.sortStrategy, this);
×
2091
        }
2092
        let fieldsMap;
UNCOV
2093
        if (this.pivotConfiguration.columnStrategy && this.pivotConfiguration.columnStrategy instanceof NoopPivotDimensionsStrategy) {
×
UNCOV
2094
            const fields = this.generateDataFields(sortedData);
×
UNCOV
2095
            if (fields.length === 0) return;
×
UNCOV
2096
            const rowFields = PivotUtil.flatten(this.pivotConfiguration.rows).map(x => x.memberName);
×
UNCOV
2097
            const keyFields = Object.values(this.pivotKeys);
×
UNCOV
2098
            const filteredFields = fields.filter(x => rowFields.indexOf(x) === -1 && keyFields.indexOf(x) === -1 &&
×
2099
                x.indexOf(this.pivotKeys.rowDimensionSeparator + this.pivotKeys.level) === -1 &&
2100
                x.indexOf(this.pivotKeys.rowDimensionSeparator + this.pivotKeys.records) === -1);
UNCOV
2101
            fieldsMap = this.generateFromData(filteredFields);
×
2102
        } else {
UNCOV
2103
            fieldsMap = PivotUtil.getFieldsHierarchy(
×
2104
                sortedData,
2105
                this.columnDimensions,
2106
                PivotDimensionType.Column,
2107
                this.pivotKeys,
2108
                this.pivotValueCloneStrategy
2109
            );
2110
        }
UNCOV
2111
        columns = this.generateColumnHierarchy(fieldsMap, sortedData);
×
UNCOV
2112
        this._autoGeneratedCols = columns;
×
2113
        // reset expansion states if any are stored.
UNCOV
2114
        this.columnGroupStates.forEach((value, key) => {
×
UNCOV
2115
            if (value) {
×
UNCOV
2116
                const primaryColumn = columns.find(x => x.field === key && x.headerTemplate === this.headerTemplate);
×
UNCOV
2117
                const groupSummaryColumn = columns.find(x => x.field === key && x.headerTemplate !== this.headerTemplate);
×
UNCOV
2118
                this.toggleRowGroup(primaryColumn, value);
×
UNCOV
2119
                if (groupSummaryColumn) {
×
UNCOV
2120
                    groupSummaryColumn.headerTemplate = this.headerTemplate;
×
2121
                }
2122
            }
2123
        });
2124

UNCOV
2125
        this.updateColumns(columns);
×
UNCOV
2126
        this.pipeTrigger++;
×
UNCOV
2127
        this.reflow();
×
2128
    }
2129

2130
    protected generateDimensionColumns(): IgxColumnComponent[] {
UNCOV
2131
        const columns = [];
×
UNCOV
2132
        this.allVisibleDimensions.forEach((dim) => {
×
UNCOV
2133
            const ref = createComponent(IgxColumnComponent, { environmentInjector: this.envInjector, elementInjector: this.injector });
×
UNCOV
2134
            ref.instance.field = dim.memberName;
×
UNCOV
2135
            ref.instance.header = dim.displayName || dim.memberName;
×
UNCOV
2136
            ref.instance.headerTemplate = this.rowDimensionHeaderTemplate;
×
UNCOV
2137
            ref.instance.resizable = this.rowDimensionResizing;
×
UNCOV
2138
            ref.instance.sortable = dim.sortable === undefined ? true : dim.sortable;
×
UNCOV
2139
            ref.instance.width = this.rowDimensionWidth(dim);
×
UNCOV
2140
            ref.instance.filteringIgnoreCase = false;
×
UNCOV
2141
            ref.changeDetectorRef.detectChanges();
×
UNCOV
2142
            columns.push(ref.instance);
×
2143
        });
UNCOV
2144
        return columns;
×
2145
    }
2146

2147
    protected override calculateGridSizes(recalcFeatureWidth = true) {
×
UNCOV
2148
        super.calculateGridSizes(recalcFeatureWidth);
×
UNCOV
2149
        if (this.hasDimensionsToAutosize) {
×
UNCOV
2150
            this.cdr.detectChanges();
×
UNCOV
2151
            this.zone.onStable.pipe(first()).subscribe(() => {
×
UNCOV
2152
                requestAnimationFrame(() => {
×
UNCOV
2153
                    this.autoSizeDimensionsInView();
×
2154
                });
2155
            });
2156
        }
2157
    }
2158

2159
    protected getContentCollection(dimenstion: IPivotDimension) {
2160
        let contentCollection;
UNCOV
2161
        if (this.hasHorizontalLayout) {
×
2162
            const allMrlContents = this.rowDimensionMrlRowsCollection.map(mrlRow => mrlRow.contentCells.toArray()).flat();
×
2163
            contentCollection = allMrlContents.filter(cell => cell.rootDimension === dimenstion);
×
2164
        } else {
UNCOV
2165
            contentCollection = this.rowDimensionContentCollection.toArray();
×
2166
        }
UNCOV
2167
        return contentCollection;
×
2168
    }
2169

2170
    protected autoSizeDimensionsInView() {
UNCOV
2171
        if (!this.hasDimensionsToAutosize) return;
×
UNCOV
2172
        for (const dim of this.visibleRowDimensions) {
×
UNCOV
2173
            if (dim.width === 'auto') {
×
UNCOV
2174
                const contentWidths = [];
×
UNCOV
2175
                const relatedDims = PivotUtil.flatten([dim]).map(x => x.memberName);
×
UNCOV
2176
                const contentCollection = this.getContentCollection(dim);
×
UNCOV
2177
                const content = contentCollection.filter(x => relatedDims.indexOf(x.dimension.memberName) !== -1);
×
UNCOV
2178
                const headers = content.map(x => x.headerGroups.toArray()).flat().map(x => x.header && x.header.refInstance);
×
UNCOV
2179
                headers.forEach((header) => contentWidths.push(header?.nativeElement?.offsetWidth || 0));
×
UNCOV
2180
                if (this.pivotUI.showRowHeaders) {
×
2181
                    const dimensionHeader = this.theadRow.rowDimensionHeaders.find(x => x.column.field === dim.memberName);
×
2182
                    contentWidths.push(parseFloat(this.getLargesContentWidth([dimensionHeader])));
×
2183
                }
UNCOV
2184
                const max = Math.max(...contentWidths);
×
UNCOV
2185
                if (max === 0) {
×
2186
                    // cells not in DOM yet...
2187
                    continue;
×
2188
                }
UNCOV
2189
                const maxSize = Math.ceil(Math.max(...contentWidths));
×
UNCOV
2190
                dim.autoWidth = maxSize;
×
2191
            }
2192
        }
2193

UNCOV
2194
        if (this.isColumnWidthSum) {
×
2195
            this.calcWidth = this.getColumnWidthSum();
×
2196
        }
2197
    }
2198

2199
    /** @hidden @internal */
2200
    public get hasDimensionsToAutosize() {
UNCOV
2201
        return this.rowDimensions.some(x => x.width === 'auto' && !x.autoWidth);
×
2202
    }
2203

2204
    protected generateFromData(fields: string[]) {
UNCOV
2205
        const separator = this.pivotKeys.columnDimensionSeparator;
×
UNCOV
2206
        const dataArr = fields.map(x => x.split(separator)).sort(x => x.length);
×
UNCOV
2207
        const hierarchy = new Map<string, any>();
×
UNCOV
2208
        const columnDimensions = PivotUtil.flatten(this.columnDimensions);
×
UNCOV
2209
        dataArr.forEach(arr => {
×
UNCOV
2210
            let currentHierarchy = hierarchy;
×
UNCOV
2211
            const path = [];
×
UNCOV
2212
            let index = 0;
×
UNCOV
2213
            for (const val of arr) {
×
UNCOV
2214
                path.push(val);
×
UNCOV
2215
                const newPath = path.join(separator);
×
UNCOV
2216
                let targetHierarchy = currentHierarchy.get(newPath);
×
UNCOV
2217
                if (!targetHierarchy) {
×
UNCOV
2218
                    const currentColumnDimension = columnDimensions[index];
×
UNCOV
2219
                    currentHierarchy.set(newPath, { value: newPath, expandable: !!currentColumnDimension.childLevel, children: new Map<string, any>(), dimension: currentColumnDimension });
×
UNCOV
2220
                    targetHierarchy = currentHierarchy.get(newPath);
×
2221
                }
UNCOV
2222
                currentHierarchy = targetHierarchy.children;
×
UNCOV
2223
                index++;
×
2224
            }
2225
        });
UNCOV
2226
        return hierarchy;
×
2227
    }
2228
    protected generateColumnHierarchy(fields: Map<string, any>, data, parent = null): IgxColumnComponent[] {
×
UNCOV
2229
        let columns = [];
×
UNCOV
2230
        if (fields.size === 0) {
×
UNCOV
2231
            this.values.forEach((value) => {
×
UNCOV
2232
                const ref = createComponent(IgxColumnComponent, { environmentInjector: this.envInjector, elementInjector: this.injector });
×
UNCOV
2233
                let columnDataType = value.dataType || this.resolveDataTypes(data.length ? data[0][value.member] : null);
×
2234

UNCOV
2235
                if (value.aggregate?.key?.toLowerCase() === 'count' && (columnDataType === GridColumnDataType.Currency || columnDataType == GridColumnDataType.Percent)) {
×
2236
                    columnDataType = GridColumnDataType.Number;
×
2237
                }
2238

UNCOV
2239
                ref.instance.header = value.displayName;
×
UNCOV
2240
                ref.instance.field = value.member;
×
UNCOV
2241
                ref.instance.parent = parent;
×
UNCOV
2242
                ref.instance.sortable = true;
×
UNCOV
2243
                ref.instance.dataType = columnDataType;
×
UNCOV
2244
                ref.instance.formatter = value.formatter;
×
UNCOV
2245
                columns.push(ref.instance);
×
2246
            });
UNCOV
2247
            return columns;
×
2248
        }
UNCOV
2249
        const currentFields = fields;
×
UNCOV
2250
        currentFields.forEach((value) => {
×
UNCOV
2251
            let shouldGenerate = true;
×
UNCOV
2252
            if (data.length === 0) {
×
2253
                shouldGenerate = false;
×
2254
            }
UNCOV
2255
            if (shouldGenerate && (value.children == null || value.children.length === 0 || value.children.size === 0)) {
×
UNCOV
2256
                const col = this.createColumnForDimension(value, data, parent, this.hasMultipleValues);
×
2257

UNCOV
2258
                if (!this.hasMultipleValues && this.values.length > 0) {
×
UNCOV
2259
                    PivotUtil.updateColumnTypeByAggregator([col], this.values[0], true);
×
2260
                }
2261

UNCOV
2262
                columns.push(col);
×
UNCOV
2263
                if (this.hasMultipleValues) {
×
UNCOV
2264
                    const measureChildren = this.getMeasureChildren(data, col, false, value.dimension.width);
×
2265

UNCOV
2266
                    measureChildren.forEach((child, index) => {
×
UNCOV
2267
                        const pivotValue = this.values[index];
×
UNCOV
2268
                        PivotUtil.updateColumnTypeByAggregator([child], pivotValue, this.values.length === 1);
×
2269
                    });
2270

UNCOV
2271
                    col.children.reset(measureChildren);
×
UNCOV
2272
                    columns = columns.concat(measureChildren);
×
2273
                }
2274

UNCOV
2275
            } else if (shouldGenerate) {
×
UNCOV
2276
                const col = this.createColumnForDimension(value, data, parent, true);
×
UNCOV
2277
                if (value.expandable) {
×
UNCOV
2278
                    col.headerTemplate = this.headerTemplate;
×
2279
                }
UNCOV
2280
                const children = this.generateColumnHierarchy(value.children, data, col);
×
UNCOV
2281
                const filteredChildren = children.filter(x => x.level === col.level + 1);
×
UNCOV
2282
                columns.push(col);
×
UNCOV
2283
                if (this.hasMultipleValues) {
×
UNCOV
2284
                    let measureChildren = this.getMeasureChildren(data, col, true, value.dimension.width);
×
UNCOV
2285
                    const nestedChildren = filteredChildren;
×
2286
                    //const allChildren = children.concat(measureChildren);
UNCOV
2287
                    col.children.reset(nestedChildren);
×
UNCOV
2288
                    columns = columns.concat(children);
×
UNCOV
2289
                    if (value.dimension.childLevel) {
×
UNCOV
2290
                        const sibling = this.createColumnForDimension(value, data, parent, true);
×
UNCOV
2291
                        columns.push(sibling);
×
2292

UNCOV
2293
                        measureChildren = this.getMeasureChildren(data, sibling, false, value.dimension?.width);
×
UNCOV
2294
                        sibling.children.reset(measureChildren);
×
UNCOV
2295
                        columns = columns.concat(measureChildren);
×
2296
                    }
2297

2298
                } else {
UNCOV
2299
                    col.children.reset(filteredChildren);
×
UNCOV
2300
                    columns = columns.concat(children);
×
UNCOV
2301
                    if (value.dimension.childLevel) {
×
UNCOV
2302
                        const sibling = this.createColumnForDimension(value, data, parent, false);
×
UNCOV
2303
                        columns.push(sibling);
×
2304
                    }
2305
                }
2306
            }
2307
        });
2308

UNCOV
2309
        return columns;
×
2310
    }
2311

2312

2313
    protected generateConfig() {
UNCOV
2314
        if (!this.data) return;
×
2315

UNCOV
2316
        const data = this.data;
×
UNCOV
2317
        const fields = this.generateDataFields(data);
×
UNCOV
2318
        const columnDimensions: IPivotDimension[] = [];
×
UNCOV
2319
        const rowDimensions: IPivotDimension[] = [];
×
UNCOV
2320
        const values: IPivotValue[] = [];
×
UNCOV
2321
        let isFirstDate = true;
×
UNCOV
2322
        fields.forEach((field) => {
×
UNCOV
2323
            const dataType = this.resolveDataTypes(data[0][field]);
×
UNCOV
2324
            switch (dataType) {
×
2325
                case "number":
2326
                    {
UNCOV
2327
                        const value: IPivotValue = {
×
2328
                            member: field,
2329
                            displayName: field,
2330
                            dataType: dataType,
2331
                            aggregate: {
2332
                                key: 'sum',
2333
                                label: 'Sum',
2334
                                aggregatorName: "SUM"
2335
                            },
2336
                            enabled: true
2337
                        };
UNCOV
2338
                        values.push(value);
×
UNCOV
2339
                        break;
×
2340
                    }
2341
                case "date":
2342
                    {
UNCOV
2343
                        const dimension: IPivotDimension = new IgxPivotDateDimension(
×
2344
                            {
2345
                                memberName: field,
2346
                                enabled: isFirstDate,
2347
                                dataType: dataType
2348
                            }
2349
                        )
UNCOV
2350
                        rowDimensions.push(dimension);
×
UNCOV
2351
                        isFirstDate = false;
×
UNCOV
2352
                        break;
×
2353
                    }
2354
                default: {
UNCOV
2355
                    const dimension: IPivotDimension = {
×
2356
                        memberName: field,
2357
                        enabled: false,
2358
                        dataType: dataType
2359
                    };
UNCOV
2360
                    columnDimensions.push(dimension);
×
UNCOV
2361
                    break;
×
2362
                }
2363
            }
2364
        });
UNCOV
2365
        const config: IPivotConfiguration = {
×
2366
            columns: columnDimensions,
2367
            rows: rowDimensions,
2368
            values: values
2369
        };
UNCOV
2370
        this.pivotConfiguration = config;
×
2371
    }
2372

2373
    protected createColumnForDimension(value: any, data: any, parent: ColumnType, isGroup: boolean) {
UNCOV
2374
        const key = value.value;
×
UNCOV
2375
        const ref = isGroup ?
×
2376
            createComponent(IgxColumnGroupComponent, { environmentInjector: this.envInjector, elementInjector: this.injector }) :
2377
            createComponent(IgxColumnComponent, { environmentInjector: this.envInjector, elementInjector: this.injector });
UNCOV
2378
        ref.instance.header = parent != null ? key.split(parent.header + this.pivotKeys.columnDimensionSeparator)[1] : key;
×
UNCOV
2379
        ref.instance.field = key;
×
UNCOV
2380
        ref.instance.parent = parent;
×
UNCOV
2381
        if (value.dimension.width) {
×
2382
            ref.instance.width = value.dimension.width;
×
2383
        }
UNCOV
2384
        const valueDefinition = this.values[0];
×
UNCOV
2385
        ref.instance.dataType = valueDefinition?.dataType || this.resolveDataTypes(data[0][valueDefinition?.member]);
×
UNCOV
2386
        ref.instance.formatter = valueDefinition?.formatter;
×
UNCOV
2387
        ref.instance.sortable = true;
×
UNCOV
2388
        ref.changeDetectorRef.detectChanges();
×
UNCOV
2389
        return ref.instance;
×
2390
    }
2391

2392
    protected resolveColumnDimensionWidth(dim: IPivotDimension) {
2393
        if (dim.width) {
×
2394
            return dim.width;
×
2395
        }
2396
        return this.minColumnWidth + 'px';
×
2397
    }
2398

2399
    protected getMeasureChildren(data, parent, hidden, parentWidth) {
UNCOV
2400
        const cols = [];
×
UNCOV
2401
        const count = this.values.length;
×
UNCOV
2402
        const childWidth = parseInt(parentWidth, 10) / count;
×
UNCOV
2403
        const isPercent = parentWidth && parentWidth.indexOf('%') !== -1;
×
UNCOV
2404
        const isAuto = parentWidth && parentWidth.indexOf('auto') !== -1;
×
UNCOV
2405
        this.values.forEach(val => {
×
UNCOV
2406
            const ref = createComponent(IgxColumnComponent, { environmentInjector: this.envInjector, elementInjector: this.injector });
×
UNCOV
2407
            ref.instance.header = val.displayName || val.member;
×
UNCOV
2408
            ref.instance.field = parent.field + this.pivotKeys.columnDimensionSeparator + val.member;
×
UNCOV
2409
            ref.instance.parent = parent;
×
UNCOV
2410
            if (parentWidth) {
×
2411
                ref.instance.width = isAuto ? 'auto' : isPercent ? childWidth + '%' : childWidth + 'px';
×
2412
            }
UNCOV
2413
            ref.instance.hidden = hidden;
×
UNCOV
2414
            ref.instance.sortable = this._sortableColumns;
×
UNCOV
2415
            ref.instance.dataType = val.dataType || this.resolveDataTypes(data[0][val.member]);
×
UNCOV
2416
            ref.instance.formatter = val.formatter;
×
UNCOV
2417
            ref.changeDetectorRef.detectChanges();
×
UNCOV
2418
            cols.push(ref.instance);
×
2419
        });
UNCOV
2420
        return cols;
×
2421
    }
2422

2423
    /**
2424
    * @hidden @internal
2425
    */
2426
    @ViewChild('emptyPivotGridTemplate', { read: TemplateRef, static: true })
2427
    public defaultEmptyPivotGridTemplate: TemplateRef<any>;
2428

2429
    /**
2430
     * Gets/Sets a custom template when pivot grid is empty.
2431
     *
2432
     * @example
2433
     * ```html
2434
     * <igx-pivot-grid [emptyPivotGridTemplate]="myTemplate"><igx-pivot-grid>
2435
     * ```
2436
     */
2437
    @Input()
2438
    public emptyPivotGridTemplate: TemplateRef<void>;
2439

2440
    /**
2441
    * @hidden @internal
2442
    */
2443
    public override get template(): TemplateRef<any> {
UNCOV
2444
        const allEnabledDimensions = this.rowDimensions.concat(this.columnDimensions);
×
UNCOV
2445
        if (allEnabledDimensions.length === 0 && this.values.length === 0) {
×
2446
            // no enabled values and dimensions
UNCOV
2447
            return this.emptyPivotGridTemplate || this.defaultEmptyPivotGridTemplate;
×
2448
        }
UNCOV
2449
        return super.template;
×
2450
    }
2451

2452
    private emitInitEvents(pivotConfig: IPivotConfiguration) {
UNCOV
2453
        const dimensions = PivotUtil.flatten(this.allDimensions);
×
UNCOV
2454
        dimensions.forEach(dim => {
×
UNCOV
2455
            this.dimensionInit.emit(dim);
×
2456
        });
UNCOV
2457
        const values = pivotConfig?.values;
×
UNCOV
2458
        values?.forEach(val => {
×
UNCOV
2459
            this.valueInit.emit(val);
×
2460
        });
2461
    }
2462

2463
    protected rowDimensionByName(memberName: string) {
2464
        return this.visibleRowDimensions.find((rowDim) => rowDim.memberName === memberName);
×
2465
    }
2466

2467
    protected calculateResizerTop() {
UNCOV
2468
        return this.pivotUI.showRowHeaders ?
×
2469
            (this.theadRow.pivotFilterContainer?.nativeElement.offsetHeight || 0) + (this.theadRow.pivotRowContainer?.nativeElement.offsetHeight || 0) :
×
2470
            this.theadRow.nativeElement.offsetHeight;
2471
    }
2472

2473
    protected override updateDefaultRowHeight() {
UNCOV
2474
        super.updateDefaultRowHeight();
×
UNCOV
2475
        if (this.hasHorizontalLayout) {
×
2476
            // Trigger pipes to recalc heights for the horizontal layout mrl rows.
UNCOV
2477
            this.regroupTrigger++;
×
2478
        }
2479
    }
2480

2481
    /**
2482
     * @hidden @internal
2483
     */
2484
    public createRow(index: number, data?: any): RowType {
2485
        let row: RowType;
2486

2487
        const dataIndex = this._getDataViewIndex(index);
×
2488
        const rec = data ?? this.dataView[dataIndex];
×
2489

2490

2491
        if (!row && rec) {
×
2492
            row = new IgxPivotGridRow(this, index, rec);
×
2493
        }
2494
        return row;
×
2495
    }
2496
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc