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

IgniteUI / igniteui-angular / 13013818259

28 Jan 2025 03:27PM CUT coverage: 91.561% (-0.04%) from 91.599%
13013818259

Pull #15223

github

web-flow
Merge 2c7faa429 into 0e6186987
Pull Request #15223: Ttonev/fix 14970 19.0

12990 of 15240 branches covered (85.24%)

0 of 14 new or added lines in 2 files covered. (0.0%)

86 existing lines in 17 files now uncovered.

26342 of 28770 relevant lines covered (91.56%)

34016.46 hits per line

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

89.46
/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-grid.component.ts
1
import {
2
    AfterContentInit,
3
    AfterViewInit,
4
    ChangeDetectionStrategy,
5
    ChangeDetectorRef,
6
    Component,
7
    EventEmitter,
8
    ElementRef,
9
    HostBinding,
10
    Inject,
11
    Input,
12
    IterableDiffers,
13
    LOCALE_ID,
14
    NgZone,
15
    OnInit,
16
    Output,
17
    Optional,
18
    QueryList,
19
    TemplateRef,
20
    ViewChild,
21
    ViewChildren,
22
    ViewContainerRef,
23
    Injector,
24
    ContentChild,
25
    createComponent,
26
    EnvironmentInjector,
27
    CUSTOM_ELEMENTS_SCHEMA,
28
    booleanAttribute,
29
    OnChanges,
30
    SimpleChanges
31
} from '@angular/core';
32
import { DOCUMENT, NgTemplateOutlet, NgIf, NgClass, NgStyle, NgFor } from '@angular/common';
33

34
import { first, take, takeUntil} from 'rxjs/operators';
35
import { IgxGridBaseDirective } from '../grid-base.directive';
36
import { IgxFilteringService } from '../filtering/grid-filtering.service';
37
import { IgxGridSelectionService } from '../selection/selection.service';
38
import { IgxForOfSyncService, IgxForOfScrollSyncService } from '../../directives/for-of/for_of.sync.service';
39
import { ColumnType, GridType, IGX_GRID_BASE, IgxColumnTemplateContext, RowType } from '../common/grid.interface';
40
import { IgxGridCRUDService } from '../common/crud.service';
41
import { IgxGridSummaryService } from '../summaries/grid-summary.service';
42
import { DEFAULT_PIVOT_KEYS, IDimensionsChange, IgxPivotGridValueTemplateContext, IPivotConfiguration, IPivotConfigurationChangedEventArgs, IPivotDimension, IPivotValue, IValuesChange, PivotDimensionType, IPivotUISettings, PivotRowLayoutType, PivotSummaryPosition } from './pivot-grid.interface';
43
import { IgxPivotHeaderRowComponent } from './pivot-header-row.component';
44
import { IgxColumnGroupComponent } from '../columns/column-group.component';
45
import { IgxColumnComponent } from '../columns/column.component';
46
import { PivotUtil } from './pivot-util';
47
import { FilterMode, GridPagingMode, GridSummaryCalculationMode, GridSummaryPosition, Size } from '../common/enums';
48
import { WatchChanges } from '../watch-changes';
49
import { OverlaySettings } from '../../services/public_api';
50
import {
51
    IGridEditEventArgs,
52
    ICellPosition,
53
    IColumnMovingEndEventArgs, IColumnMovingEventArgs, IColumnMovingStartEventArgs,
54
    IColumnVisibilityChangedEventArgs,
55
    IGridEditDoneEventArgs,
56
    IGridToolbarExportEventArgs,
57
    IPinColumnCancellableEventArgs,
58
    IPinColumnEventArgs,
59
    IPinRowEventArgs,
60
    IRowDataCancelableEventArgs,
61
    IRowDataEventArgs,
62
    IRowDragEndEventArgs,
63
    IRowDragStartEventArgs
64
} from '../common/events';
65
import { IgxGridRowComponent } from '../grid/grid-row.component';
66
import { DropPosition } from '../moving/moving.service';
67
import { DimensionValuesFilteringStrategy, NoopPivotDimensionsStrategy } from '../../data-operations/pivot-strategy';
68
import { IgxGridExcelStyleFilteringComponent, IgxExcelStyleColumnOperationsTemplateDirective, IgxExcelStyleFilterOperationsTemplateDirective } from '../filtering/excel-style/excel-style-filtering.component';
69
import { IgxPivotGridNavigationService } from './pivot-grid-navigation.service';
70
import { IgxPivotColumnResizingService } from '../resizing/pivot-grid/pivot-resizing.service';
71
import { IgxFlatTransactionFactory, IgxOverlayService, State, Transaction, TransactionService } from '../../services/public_api';
72
import { cloneArray, PlatformUtil, resizeObservable } from '../../core/utils';
73
import { IgxPivotFilteringService } from './pivot-filtering.service';
74
import { DataUtil } from '../../data-operations/data-util';
75
import { IFilteringExpressionsTree } from '../../data-operations/filtering-expressions-tree';
76
import { IgxGridTransaction } from '../common/types';
77
import { GridBaseAPIService } from '../api.service';
78
import { IForOfDataChangingEventArgs, IgxGridForOfDirective } from '../../directives/for-of/for_of.directive';
79
import { IgxPivotRowDimensionContentComponent } from './pivot-row-dimension-content.component';
80
import { IgxPivotGridColumnResizerComponent } from '../resizing/pivot-grid/pivot-resizer.component';
81
import { ISortingExpression, SortingDirection } from '../../data-operations/sorting-strategy';
82
import { PivotSortUtil } from './pivot-sort-util';
83
import { IFilteringStrategy } from '../../data-operations/filtering-strategy';
84
import { IgxPivotRowDimensionHeaderTemplateDirective, IgxPivotValueChipTemplateDirective } from './pivot-grid.directives';
85
import { IFilteringOperation } from '../../data-operations/filtering-condition';
86
import { IgxGridValidationService } from '../grid/grid-validation.service';
87
import { IgxPivotRowPipe, IgxPivotRowExpansionPipe, IgxPivotAutoTransform, IgxPivotColumnPipe, IgxPivotGridFilterPipe, IgxPivotGridSortingPipe, IgxPivotGridColumnSortingPipe, IgxPivotCellMergingPipe, IgxPivotGridHorizontalRowGrouping } from './pivot-grid.pipes';
88
import { IgxGridRowClassesPipe, IgxGridRowStylesPipe } from '../common/pipes';
89
import { IgxExcelStyleSearchComponent } from '../filtering/excel-style/excel-style-search.component';
90
import { IgxIconComponent } from '../../icon/icon.component';
91
import { IgxSnackbarComponent } from '../../snackbar/snackbar.component';
92
import { IgxCircularProgressBarComponent } from '../../progressbar/progressbar.component';
93
import { IgxToggleDirective, IgxOverlayOutletDirective } from '../../directives/toggle/toggle.directive';
94
import { IgxPivotRowComponent } from './pivot-row.component';
95
import { IgxTemplateOutletDirective } from '../../directives/template-outlet/template_outlet.directive';
96
import { IgxColumnMovingDropDirective } from '../moving/moving.drop.directive';
97
import { IgxGridDragSelectDirective } from '../selection/drag-select.directive';
98
import { IgxGridBodyDirective } from '../grid.common';
99
import { IgxColumnResizingService } from '../resizing/resizing.service';
100
import { DefaultDataCloneStrategy, IDataCloneStrategy } from '../../data-operations/data-clone-strategy';
101
import { IgxTextHighlightService } from '../../directives/text-highlight/text-highlight.service';
102
import { IgxPivotRowHeaderGroupComponent } from './pivot-row-header-group.component';
103
import { IgxPivotDateDimension } from './pivot-grid-dimensions';
104
import { IgxPivotRowDimensionMrlRowComponent } from './pivot-row-dimension-mrl-row.component';
105
import { IgxPivotGridRow } from '../grid-public-row';
106

107
let NEXT_ID = 0;
2✔
108
const MINIMUM_COLUMN_WIDTH = 200;
2✔
109
const MINIMUM_COLUMN_WIDTH_SUPER_COMPACT = 104;
2✔
110

111
/* blazorAdditionalDependency: Column */
112
/* blazorAdditionalDependency: ColumnGroup */
113
/* blazorAdditionalDependency: ColumnLayout */
114
/* blazorAdditionalDependency: GridToolbar */
115
/* blazorAdditionalDependency: GridToolbarActions */
116
/* blazorAdditionalDependency: GridToolbarTitle */
117
/* blazorAdditionalDependency: GridToolbarAdvancedFiltering */
118
/* blazorAdditionalDependency: GridToolbarExporter */
119
/* blazorAdditionalDependency: GridToolbarHiding */
120
/* blazorAdditionalDependency: GridToolbarPinning */
121
/* blazorAdditionalDependency: ActionStrip */
122
/* blazorAdditionalDependency: GridActionsBaseDirective */
123
/* blazorAdditionalDependency: GridEditingActions */
124
/* blazorAdditionalDependency: GridPinningActions */
125
/* blazorAdditionalDependency: PivotDateDimension */
126
/* blazorIndirectRender */
127
/**
128
 * Pivot Grid provides a way to present and manipulate data in a pivot table view.
129
 *
130
 * @igxModule IgxPivotGridModule
131
 * @igxGroup Grids & Lists
132
 * @igxKeywords pivot, grid, table
133
 * @igxTheme igx-grid-theme
134
 * @remarks
135
 * The Ignite UI Pivot Grid is used for grouping and aggregating simple flat data into a pivot table.  Once data
136
 * has been bound and the dimensions and values configured it can be manipulated via sorting and filtering.
137
 * @example
138
 * ```html
139
 * <igx-pivot-grid [data]="data" [pivotConfiguration]="configuration">
140
 * </igx-pivot-grid>
141
 * ```
142
 */
143
@Component({
144
    changeDetection: ChangeDetectionStrategy.OnPush,
145
    preserveWhitespaces: false,
146
    selector: 'igx-pivot-grid',
147
    templateUrl: 'pivot-grid.component.html',
148
    providers: [
149
        IgxGridCRUDService,
150
        IgxGridValidationService,
151
        IgxGridSummaryService,
152
        IgxGridSelectionService,
153
        IgxColumnResizingService,
154
        GridBaseAPIService,
155
        { provide: IGX_GRID_BASE, useExisting: IgxPivotGridComponent },
156
        { provide: IgxFilteringService, useClass: IgxPivotFilteringService },
157
        IgxPivotGridNavigationService,
158
        IgxPivotColumnResizingService,
159
        IgxForOfSyncService,
160
        IgxForOfScrollSyncService
161
    ],
162
    imports: [
163
        NgIf,
164
        NgFor,
165
        NgClass,
166
        NgStyle,
167
        NgTemplateOutlet,
168
        IgxPivotHeaderRowComponent,
169
        IgxGridBodyDirective,
170
        IgxGridDragSelectDirective,
171
        IgxColumnMovingDropDirective,
172
        IgxGridForOfDirective,
173
        IgxTemplateOutletDirective,
174
        IgxPivotRowComponent,
175
        IgxToggleDirective,
176
        IgxCircularProgressBarComponent,
177
        IgxSnackbarComponent,
178
        IgxOverlayOutletDirective,
179
        IgxPivotGridColumnResizerComponent,
180
        IgxIconComponent,
181
        IgxPivotRowDimensionContentComponent,
182
        IgxGridExcelStyleFilteringComponent,
183
        IgxExcelStyleColumnOperationsTemplateDirective,
184
        IgxExcelStyleFilterOperationsTemplateDirective,
185
        IgxExcelStyleSearchComponent,
186
        IgxGridRowClassesPipe,
187
        IgxGridRowStylesPipe,
188
        IgxPivotRowPipe,
189
        IgxPivotRowExpansionPipe,
190
        IgxPivotAutoTransform,
191
        IgxPivotColumnPipe,
192
        IgxPivotGridFilterPipe,
193
        IgxPivotGridSortingPipe,
194
        IgxPivotGridColumnSortingPipe,
195
        IgxPivotCellMergingPipe,
196
        IgxPivotGridHorizontalRowGrouping,
197
        IgxPivotRowDimensionMrlRowComponent
198
    ],
199
    schemas: [CUSTOM_ELEMENTS_SCHEMA]
200
})
201
export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnInit, AfterContentInit,
2✔
202
    GridType, AfterViewInit, OnChanges {
203

204
    /**
205
     * Emitted when the dimension collection is changed via the grid chip area.
206
     *
207
     * @remarks
208
     * Returns the new dimension collection and its type:
209
     * @example
210
     * ```html
211
     * <igx-pivot-grid #grid [data]="localData" [height]="'305px'"
212
     *              (dimensionsChange)="dimensionsChange($event)"></igx-grid>
213
     * ```
214
     */
215
    @Output()
216
    public dimensionsChange = new EventEmitter<IDimensionsChange>();
130✔
217

218
    /**
219
     * Emitted when any of the pivotConfiguration properties is changed via the grid chip area.
220
     *
221
     * @example
222
     * ```html
223
     * <igx-pivot-grid #grid [data]="localData" [height]="'305px'"
224
     *              (pivotConfigurationChanged)="configurationChanged($event)"></igx-grid>
225
     * ```
226
     */
227
    @Output()
228
    public pivotConfigurationChange = new EventEmitter<IPivotConfigurationChangedEventArgs>();
130✔
229

230

231
    /**
232
     * Emitted when the dimension is initialized.
233
     * @remarks
234
     * Emits the dimension that is about to be initialized.
235
     * @example
236
     * ```html
237
     * <igx-pivot-grid #grid [data]="localData" [height]="'305px'"
238
     *              (dimensionInit)="dimensionInit($event)"></igx-pivot-grid>
239
     * ```
240
     */
241
    @Output()
242
    public dimensionInit = new EventEmitter<IPivotDimension>();
130✔
243

244
    /**
245
     * Emitted when the value is initialized.
246
     * @remarks
247
     * Emits the value that is about to be initialized.
248
     * @example
249
     * ```html
250
     * <igx-pivot-grid #grid [data]="localData" [height]="'305px'"
251
     *              (valueInit)="valueInit($event)"></igx-pivot-grid>
252
     * ```
253
     */
254
    @Output()
255
    public valueInit = new EventEmitter<IPivotValue>();
130✔
256

257

258
    /**
259
     * Emitted when a dimension is sorted.
260
     *
261
     * @example
262
     * ```html
263
     * <igx-pivot-grid #grid [data]="localData" [height]="'305px'"
264
     *              (dimensionsSortingExpressionsChange)="dimensionsSortingExpressionsChange($event)"></igx-pivot-grid>
265
     * ```
266
     */
267
    @Output()
268
    public dimensionsSortingExpressionsChange = new EventEmitter<ISortingExpression[]>();
130✔
269

270
    /**
271
     * Emitted when the values collection is changed via the grid chip area.
272
     *
273
     * @remarks
274
     * Returns the new dimension
275
     * @example
276
     * ```html
277
     * <igx-pivot-grid #grid [data]="localData" [height]="'305px'"
278
     *              (valuesChange)="valuesChange($event)"></igx-grid>
279
     * ```
280
    */
281
    @Output()
282
    public valuesChange = new EventEmitter<IValuesChange>();
130✔
283

284

285
    /**
286
     * Gets the sorting expressions generated for the dimensions.
287
     *
288
     * @example
289
     * ```typescript
290
     * const expressions = this.grid.dimensionsSortingExpressions;
291
     * ```
292
     */
293
    public get dimensionsSortingExpressions() {
294
        const allEnabledDimensions = this.rowDimensions.concat(this.columnDimensions);
22✔
295
        const dimensionsSortingExpressions = PivotSortUtil.generateDimensionSortingExpressions(allEnabledDimensions);
22✔
296
        return dimensionsSortingExpressions;
22✔
297
    }
298

299
    /** @hidden @internal */
300
    @ViewChild(IgxPivotHeaderRowComponent, { static: true })
301
    public override theadRow: IgxPivotHeaderRowComponent;
302

303
    /**
304
    * @hidden @internal
305
    */
306
    @ContentChild(IgxPivotValueChipTemplateDirective, { read: IgxPivotValueChipTemplateDirective })
307
    protected valueChipTemplateDirective: IgxPivotValueChipTemplateDirective;
308

309
    /**
310
     * @hidden @internal
311
     */
312
    @ContentChild(IgxPivotRowDimensionHeaderTemplateDirective, { read: IgxPivotRowDimensionHeaderTemplateDirective })
313
    protected rowDimensionHeaderDirective: IgxPivotRowDimensionHeaderTemplateDirective;
314

315
    /**
316
     * Gets/Sets a custom template for the value chips.
317
     *
318
     * @example
319
     * ```html
320
     * <igx-pivot-grid [valueChipTemplate]="myTemplate"><igx-pivot-grid>
321
     * ```
322
     */
323
    @Input()
324
    public valueChipTemplate: TemplateRef<IgxPivotGridValueTemplateContext>;
325

326
    @Input()
327
    public rowDimensionHeaderTemplate: TemplateRef<IgxColumnTemplateContext>;
328

329
    /* mustSetInCodePlatforms: WebComponents;Blazor;React */
330
    /* @tsTwoWayProperty (true, "PivotConfigurationChange", "Detail.PivotConfiguration", false) */
331
    /**
332
     * Gets/Sets the pivot configuration with all related dimensions and values.
333
     *
334
     * @example
335
     * ```html
336
     * <igx-pivot-grid [pivotConfiguration]="config"></igx-pivot-grid>
337
     * ```
338
     */
339
    @Input()
340
    public set pivotConfiguration(value: IPivotConfiguration) {
341
        this._pivotConfiguration = value;
152✔
342
        this.emitInitEvents(this._pivotConfiguration);
152✔
343
        this.filteringExpressionsTree = PivotUtil.buildExpressionTree(value);
152✔
344
        if (!this._init) {
152✔
345
            this.setupColumns();
22✔
346
        }
347
        this.notifyChanges(true);
152✔
348
    }
349

350
    /* mustSetInCodePlatforms: WebComponents;Blazor */
351
    public get pivotConfiguration() {
352
        return this._pivotConfiguration || { rows: null, columns: null, values: null, filters: null };
932,483✔
353
    }
354

355
    /**
356
     * Gets/Sets whether to auto-generate the pivot configuration based on the provided data.
357
     *
358
     * @remarks
359
     * The default value is false. When set to true, it will override all dimensions and values in the pivotConfiguration.
360
     * @example
361
     * ```html
362
     * <igx-pivot-grid [data]="Data" [autoGenerateConfig]="true"></igx-pivot-grid>
363
     * ```
364
     */
365
    @Input({ transform: booleanAttribute })
366
    public autoGenerateConfig = false;
130✔
367

368
    @Input()
369
    /**
370
     * Gets/Sets the pivot ui settings for the pivot grid - chips and their
371
     * corresponding containers for row, filter, column dimensions and values
372
     * as well as headers for the row dimensions values.
373
     * @example
374
     * ```html
375
     * <igx-pivot-grid [pivotUI]="{ showRowHeaders: true }"></igx-pivot-grid>
376
     * ```
377
     */
378
    public set pivotUI(value: IPivotUISettings) {
379
        this._pivotUI = Object.assign(this._pivotUI, value || {});
11!
380
        this.pipeTrigger++;
11✔
381
        this.notifyChanges(true);
11✔
382
    }
383

384
    public get pivotUI() {
385
        return this._pivotUI;
134,178✔
386
    }
387

388
    /**
389
     * @hidden @internal
390
     */
391
    @HostBinding('attr.role')
392
    public role = 'grid';
130✔
393

394

395
    /**
396
     * Enables a super compact theme for the component.
397
     * @remarks
398
     * Overrides the grid size option if one is set.
399
     * @example
400
     * ```html
401
     * <igx-pivot-grid [superCompactMode]="true"></igx-pivot-grid>
402
     * ```
403
     */
404
    @HostBinding('class.igx-grid__pivot--super-compact')
405
    @Input()
406
    public get superCompactMode() {
407
        return this._superCompactMode;
111,842✔
408
    }
409

410
    public set superCompactMode(value) {
411
        this._superCompactMode = value;
3✔
412
    }
413

414
    /** @hidden @internal */
415
    public override get gridSize() {
416
        if (this.superCompactMode) {
105,333✔
417
            return Size.Small;
139✔
418
        }
419
        return super.gridSize;
105,194✔
420
    }
421

422

423
    /**
424
     * Gets/Sets the values clone strategy of the pivot grid when assigning them to different dimensions.
425
     *
426
     * @example
427
     * ```html
428
     *  <igx-pivot-grid #grid [data]="localData" [pivotValueCloneStrategy]="customCloneStrategy"></igx-pivot-grid>
429
     * ```
430
     * @hidden @internal
431
     */
432
    @Input()
433
    public get pivotValueCloneStrategy(): IDataCloneStrategy {
434
        return this._pivotValueCloneStrategy;
4,556✔
435
    }
436

437
    public set pivotValueCloneStrategy(strategy: IDataCloneStrategy) {
438
        if (strategy) {
×
439
            this._pivotValueCloneStrategy = strategy;
×
440
        }
441
    }
442

443
    /**
444
     * @hidden @internal
445
     */
446
    @ViewChild('record_template', { read: TemplateRef, static: true })
447
    public recordTemplate: TemplateRef<any>;
448

449
    /**
450
     * @hidden @internal
451
     */
452
    @ViewChild('headerTemplate', { read: TemplateRef, static: true })
453
    public headerTemplate: TemplateRef<any>;
454

455
    /**
456
     * @hidden @internal
457
     */
458
    @ViewChildren('rowDimensionContainer', { read: ElementRef })
459
    public rowDimensionContainer: QueryList<ElementRef<any>>;
460

461
    /**
462
     * @hidden @internal
463
     */
464
    @ViewChild(IgxPivotGridColumnResizerComponent)
465
    public override resizeLine: IgxPivotGridColumnResizerComponent;
466

467
    /**
468
     * @hidden @internal
469
     */
470
    @ViewChildren(IgxGridExcelStyleFilteringComponent, { read: IgxGridExcelStyleFilteringComponent })
471
    public override excelStyleFilteringComponents: QueryList<IgxGridExcelStyleFilteringComponent>;
472

473
    /**
474
     * @hidden @internal
475
     */
476
    @ViewChildren(IgxPivotRowDimensionContentComponent)
477
    protected rowDimensionContentCollection: QueryList<IgxPivotRowDimensionContentComponent>;
478

479
    /**
480
     * @hidden @internal
481
     */
482
    public override get minColumnWidth() {
483
        if (this.superCompactMode) {
5,619✔
484
            return MINIMUM_COLUMN_WIDTH_SUPER_COMPACT;
1✔
485
        } else {
486
            return MINIMUM_COLUMN_WIDTH;
5,618✔
487
        }
488
    }
489

490
    /**
491
     * @hidden @internal
492
     */
493
    @ViewChildren('verticalRowDimScrollContainer', { read: IgxGridForOfDirective })
494
    public verticalRowDimScrollContainers: QueryList<IgxGridForOfDirective<any, any[]>>;
495

496
    /**
497
     * @hidden @internal
498
     */
499
    @ViewChildren(IgxPivotRowDimensionMrlRowComponent)
500
    public rowDimensionMrlRowsCollection: QueryList<IgxPivotRowDimensionMrlRowComponent>;
501

502
    /**
503
     * @hidden @internal
504
     */
505
    @Input()
506
    public override addRowEmptyTemplate: TemplateRef<void>;
507

508
    /**
509
     * @hidden @internal
510
     */
511
    @Input()
512
    public override autoGenerateExclude: string[] = [];
130✔
513

514
    /**
515
     * @hidden @internal
516
     */
517
    @Input()
518
    public override snackbarDisplayTime = 6000;
130✔
519

520
    /**
521
     * @hidden @internal
522
     */
523
    @Output()
524
    public override cellEdit = new EventEmitter<IGridEditEventArgs>();
130✔
525

526
    /**
527
     * @hidden @internal
528
     */
529
    @Output()
530
    public override cellEditDone = new EventEmitter<IGridEditDoneEventArgs>();
130✔
531

532
    /**
533
     * @hidden @internal
534
     */
535
    @Output()
536
    public override cellEditEnter = new EventEmitter<IGridEditEventArgs>();
130✔
537

538
    /**
539
     * @hidden @internal
540
     */
541
    @Output()
542
    public override cellEditExit = new EventEmitter<IGridEditDoneEventArgs>();
130✔
543

544
    /**
545
     * @hidden @internal
546
     */
547
    @Output()
548
    public override columnMovingStart = new EventEmitter<IColumnMovingStartEventArgs>();
130✔
549

550
    /**
551
     * @hidden @internal
552
     */
553
    @Output()
554
    public override columnMoving = new EventEmitter<IColumnMovingEventArgs>();
130✔
555

556
    /**
557
     * @hidden @internal
558
     */
559
    @Output()
560
    public override columnMovingEnd = new EventEmitter<IColumnMovingEndEventArgs>();
130✔
561

562
    /**
563
     * @hidden @internal
564
     */
565
    @Output()
566
    public override columnPin = new EventEmitter<IPinColumnCancellableEventArgs>();
130✔
567

568
    /**
569
     * @hidden @internal
570
     */
571
    @Output()
572
    public override columnPinned = new EventEmitter<IPinColumnEventArgs>();
130✔
573

574
    /**
575
     * @hidden @internal
576
     */
577
    @Output()
578
    public override rowAdd = new EventEmitter<IRowDataCancelableEventArgs>();
130✔
579

580
    /**
581
     * @hidden @internal
582
     */
583
    @Output()
584
    public override rowAdded = new EventEmitter<IRowDataEventArgs>();
130✔
585

586
    /**
587
     * @hidden @internal
588
     */
589
    @Output()
590
    public override rowDeleted = new EventEmitter<IRowDataEventArgs>();
130✔
591

592
    /**
593
     * @hidden @internal
594
     */
595
    @Output()
596
    public override rowDelete = new EventEmitter<IRowDataCancelableEventArgs>();
130✔
597

598
    /**
599
     * @hidden @internal
600
     */
601
    @Output()
602
    public override rowDragStart = new EventEmitter<IRowDragStartEventArgs>();
130✔
603

604
    /**
605
     * @hidden @internal
606
     */
607
    @Output()
608
    public override rowDragEnd = new EventEmitter<IRowDragEndEventArgs>();
130✔
609

610
    /**
611
     * @hidden @internal
612
     */
613
    @Output()
614
    public override rowEditEnter = new EventEmitter<IGridEditEventArgs>();
130✔
615

616
    /**
617
     * @hidden @internal
618
     */
619
    @Output()
620
    public override rowEdit = new EventEmitter<IGridEditEventArgs>();
130✔
621

622
    /**
623
     * @hidden @internal
624
     */
625
    @Output()
626
    public override rowEditDone = new EventEmitter<IGridEditDoneEventArgs>();
130✔
627

628
    /**
629
     * @hidden @internal
630
     */
631
    @Output()
632
    public override rowEditExit = new EventEmitter<IGridEditDoneEventArgs>();
130✔
633

634
    /**
635
     * @hidden @internal
636
     */
637
    @Output()
638
    public override rowPinning = new EventEmitter<IPinRowEventArgs>();
130✔
639

640
    /**
641
     * @hidden @internal
642
     */
643
    @Output()
644
    public override rowPinned = new EventEmitter<IPinRowEventArgs>();
130✔
645

646
    /** @hidden @internal */
647
    public columnGroupStates = new Map<string, boolean>();
130✔
648
    /** @hidden @internal */
649
    public dimensionDataColumns: any[];
650
    /** @hidden @internal */
651
    public get pivotKeys() {
652
        return this.pivotConfiguration.pivotKeys || DEFAULT_PIVOT_KEYS;
162,974✔
653
    }
654
    /** @hidden @internal */
655
    public override get type(): GridType["type"] {
656
        return 'pivot';
5,292✔
657
    }
658

659
    /**
660
     * @hidden @internal
661
     */
662
    public override dragRowID = null;
130✔
663

664
    /**
665
    * @hidden @internal
666
    */
667
    public override get rootSummariesEnabled(): boolean {
668
        return false;
5,406✔
669
    }
670

671
    /**
672
     * @hidden @internal
673
     */
674
    public rowDimensionResizing = true;
130✔
675

676
    private _emptyRowDimension: IPivotDimension = { memberName: '', enabled: true, level: 0 };
130✔
677
    /**
678
     * @hidden @internal
679
     */
680
    public get emptyRowDimension(): IPivotDimension {
681
        return this._emptyRowDimension;
2,574✔
682
    }
683

684
    protected _pivotValueCloneStrategy: IDataCloneStrategy = new DefaultDataCloneStrategy();
130✔
685
    protected override _defaultExpandState = false;
130✔
686
    protected override _filterStrategy: IFilteringStrategy = new DimensionValuesFilteringStrategy();
130✔
687
    protected regroupTrigger = 0;
130✔
688
    private _data;
689
    private _pivotConfiguration: IPivotConfiguration = { rows: null, columns: null, values: null, filters: null };
130✔
690
    private p_id = `igx-pivot-grid-${NEXT_ID++}`;
130✔
691
    private _superCompactMode = false;
130✔
692
    private _pivotUI: IPivotUISettings = {
130✔
693
        showConfiguration: true,
694
        showRowHeaders: false,
695
        rowLayout: PivotRowLayoutType.Vertical,
696
        horizontalSummariesPosition: PivotSummaryPosition.Bottom
697
    };
698
    private _sortableColumns = true;
130✔
699
    private _visibleRowDimensions: IPivotDimension[] = [];
130✔
700
    private _shouldUpdateSizes = false;
130✔
701

702
    /**
703
    * Gets/Sets the default expand state for all rows.
704
    */
705
    @Input({ transform: booleanAttribute })
706
    public get defaultExpandState() {
707
        return this._defaultExpandState;
2,151✔
708
    }
709

710
    public set defaultExpandState(val: boolean) {
711
        this._defaultExpandState = val;
120✔
712
    }
713

714
    /**
715
     * @hidden @internal
716
     */
717
    @Input()
718
    public override get pagingMode() {
719
        return;
×
720
    }
721

722
    public override set pagingMode(_val: GridPagingMode) {
723
    }
724

725
    /**
726
     * @hidden @internal
727
     */
728
    @WatchChanges()
729
    @Input({ transform: booleanAttribute })
730
    public override get hideRowSelectors() {
731
        return;
×
732
    }
733

734
    public override set hideRowSelectors(_value: boolean) {
735
    }
736

737
    /**
738
     * @hidden @internal
739
     */
740
    public override autoGenerate = true;
130✔
741

742
    /**
743
     * @hidden @internal
744
     */
745
    public override get actionStrip() {
746
        return undefined as any;
×
747
    }
748

749
    /**
750
     * @hidden @internal
751
     * @deprecated in version 18.2.0. This property is no longer supported.
752
     */
753
    public override get shouldGenerate(): boolean {
754
        return false;
×
755
    }
756

757
    public override set shouldGenerate(value: boolean) {
758
    }
759

760
    /**
761
     * @hidden @internal
762
     */
763
    public override moving = false;
130✔
764

765
    /**
766
     * @hidden @internal
767
     */
768
    public override toolbarExporting = new EventEmitter<IGridToolbarExportEventArgs>();
130✔
769

770
    /**
771
     * @hidden @internal
772
     */
773
    @Input({ transform: booleanAttribute })
774
    public override get rowDraggable(): boolean {
775
        return;
×
776
    }
777

778

779
    public override set rowDraggable(_val: boolean) {
780
    }
781

782
    /**
783
     * @hidden @internal
784
     */
785
    @Input({ transform: booleanAttribute })
786
    public override get allowAdvancedFiltering() {
787
        return false;
×
788
    }
789

790
    public override set allowAdvancedFiltering(_value) {
791
    }
792

793
    /**
794
     * @hidden @internal
795
     */
796
    @Input()
797
    public override get filterMode() {
798
        return FilterMode.quickFilter;
×
799
    }
800

801
    public override set filterMode(_value: FilterMode) {
802
    }
803

804
    /**
805
     * @hidden @internal
806
     */
807
    @Input({ transform: booleanAttribute })
808
    public override get allowFiltering() {
809
        return false;
36,140✔
810
    }
811

812
    public override set allowFiltering(_value) {
813
    }
814

815
    /**
816
     * @hidden @internal
817
     */
818
    @Input()
819
    public override get page(): number {
820
        return 0;
×
821
    }
822

823
    public override set page(_val: number) {
824
    }
825

826
    /**
827
     * @hidden @internal
828
     */
829
    @Input()
830
    public override get perPage(): number {
831
        return;
×
832
    }
833

834
    public override set perPage(_val: number) {
835
    }
836

837
    /**
838
     * @hidden @internal
839
     */
840
    public override get pinnedColumns(): IgxColumnComponent[] {
841
        return [];
147,599✔
842
    }
843

844
    /**
845
    * @hidden @internal
846
    */
847
    public override get unpinnedColumns(): IgxColumnComponent[] {
848
        return super.unpinnedColumns;
25,574✔
849
    }
850

851
    /**
852
    * @hidden @internal
853
    */
854
    public override get unpinnedDataView(): any[] {
855
        return super.unpinnedDataView;
×
856
    }
857

858
    /**
859
    * @hidden @internal
860
    */
861
    public override get unpinnedWidth() {
862
        return super.unpinnedWidth;
23,093✔
863
    }
864

865
    /**
866
     * @hidden @internal
867
     */
868
    public override get pinnedWidth() {
869
        return super.pinnedWidth;
6,040✔
870
    }
871

872
    /**
873
     * @hidden @internal
874
     */
875
    @Input()
876
    public override set summaryRowHeight(_value: number) {
877
    }
878

879
    public override get summaryRowHeight(): number {
880
        return 0;
603✔
881
    }
882

883
    /**
884
     * @hidden @internal
885
     */
886
    public override get transactions(): TransactionService<Transaction, State> {
887
        return this._transactions;
527,355✔
888
    }
889

890

891

892
    /**
893
     * @hidden @internal
894
     */
895
    public override get dragIndicatorIconTemplate(): TemplateRef<any> {
896
        return;
×
897
    }
898

899
    public override set dragIndicatorIconTemplate(_val: TemplateRef<any>) {
900
    }
901

902
    /**
903
     * @hidden @internal
904
     */
905
    @WatchChanges()
906
    @Input({ transform: booleanAttribute })
907
    public override get rowEditable(): boolean {
908
        return;
224,139✔
909
    }
910

911
    public override set rowEditable(_val: boolean) {
912
    }
913

914
    /**
915
     * @hidden @internal
916
     */
917
    @Input()
918
    public override get pinning() {
919
        return {};
181,618✔
920
    }
921
    public override set pinning(_value) {
922
    }
923

924
    /**
925
     * @hidden @internal
926
     */
927
    @Input()
928
    public override get summaryPosition() {
929
        return;
×
930
    }
931

932
    public override set summaryPosition(_value: GridSummaryPosition) {
933
    }
934

935
    /**
936
     * @hidden @interal
937
     */
938
    @Input()
939
    public override get summaryCalculationMode() {
940
        return;
×
941
    }
942

943
    public override set summaryCalculationMode(_value: GridSummaryCalculationMode) {
944
    }
945

946
    /**
947
     * @hidden @interal
948
     */
949
    @Input({ transform: booleanAttribute })
950
    public override get showSummaryOnCollapse() {
951
        return;
×
952
    }
953

954
    public override set showSummaryOnCollapse(_value: boolean) {
955
    }
956

957
    /**
958
     * @hidden @internal
959
     */
960
    public override get hiddenColumnsCount() {
961
        return null;
×
962
    }
963

964
    /**
965
     * @hidden @internal
966
     */
967
    public override get pinnedColumnsCount() {
968
        return null;
×
969
    }
970

971
    /**
972
     * @hidden @internal
973
     */
974
    @Input({ transform: booleanAttribute })
975
    public override get batchEditing(): boolean {
976
        return;
×
977
    }
978

979
    public override set batchEditing(_val: boolean) {
980
    }
981

982
    /* csSuppress */
983
    public override get selectedRows(): any[] {
984
        if (this.selectionService.getSelectedRows().length === 0) {
19✔
985
            return [];
4✔
986
        }
987
        const selectedRowIds = [];
15✔
988
        this.dataView.forEach(record => {
15✔
989
            const prev = [];
182✔
990
            for (const dim of this.rowDimensions) {
182✔
991
                let currDim = dim;
345✔
992
                let shouldBreak = false;
345✔
993
                do {
345✔
994
                    const key = PivotUtil.getRecordKey(record, currDim);
651✔
995
                    if (this.selectionService.isPivotRowSelected(key) && !selectedRowIds.find(x => x === record)) {
651✔
996
                        selectedRowIds.push(record);
29✔
997
                        shouldBreak = true;
29✔
998
                        break;
29✔
999
                    }
1000
                    currDim = currDim.childLevel;
622✔
1001
                } while (currDim);
1002
                prev.push(dim);
345✔
1003
                if (shouldBreak) {
345✔
1004
                    break;
29✔
1005
                }
1006
            }
1007

1008
        });
1009

1010
        return selectedRowIds;
15✔
1011
    }
1012

1013
    constructor(
1014
        validationService: IgxGridValidationService,
1015
        selectionService: IgxGridSelectionService,
1016
        colResizingService: IgxPivotColumnResizingService,
1017
        gridAPI: GridBaseAPIService<IgxGridBaseDirective & GridType>,
1018
        transactionFactory: IgxFlatTransactionFactory,
1019
        elementRef: ElementRef<HTMLElement>,
1020
        zone: NgZone,
1021
        @Inject(DOCUMENT) document,
1022
        cdr: ChangeDetectorRef,
1023
        differs: IterableDiffers,
1024
        viewRef: ViewContainerRef,
1025
        injector: Injector,
1026
        envInjector: EnvironmentInjector,
1027
        navigation: IgxPivotGridNavigationService,
1028
        filteringService: IgxFilteringService,
1029
        textHighlightService: IgxTextHighlightService,
1030
        @Inject(IgxOverlayService) overlayService: IgxOverlayService,
1031
        summaryService: IgxGridSummaryService,
1032
        @Inject(LOCALE_ID) localeId: string,
1033
        platform: PlatformUtil,
1034
        @Optional() @Inject(IgxGridTransaction) _diTransactions?: TransactionService<Transaction, State>
1035
    ) {
1036
        super(
130✔
1037
            validationService,
1038
            selectionService,
1039
            colResizingService,
1040
            gridAPI,
1041
            transactionFactory,
1042
            elementRef,
1043
            zone,
1044
            document,
1045
            cdr,
1046
            differs,
1047
            viewRef,
1048
            injector,
1049
            envInjector,
1050
            navigation,
1051
            filteringService,
1052
            textHighlightService,
1053
            overlayService,
1054
            summaryService,
1055
            localeId,
1056
            platform,
1057
            _diTransactions);
1058
    }
1059

1060
    /**
1061
     * @hidden
1062
     */
1063
    public override ngOnInit() {
1064
        // pivot grid always generates columns automatically.
1065
        this.autoGenerate = true;
130✔
1066
        super.ngOnInit();
130✔
1067
    }
1068

1069
    /**
1070
     * @hidden
1071
     */
1072
    public override ngAfterContentInit() {
1073
        // ignore any user defined columns and auto-generate based on pivot config.
1074
        this.updateColumns([]);
130✔
1075
        Promise.resolve().then(() => {
130✔
1076
            if (this.autoGenerateConfig) {
130!
1077
                this.generateConfig();
×
1078
            }
1079
            this.setupColumns();
130✔
1080
        });
1081
        if (this.valueChipTemplateDirective) {
130!
1082
            this.valueChipTemplate = this.valueChipTemplateDirective.template;
×
1083
        }
1084
        if (this.rowDimensionHeaderDirective) {
130!
1085
            this.rowDimensionHeaderTemplate = this.rowDimensionHeaderDirective.template;
×
1086
        }
1087
    }
1088

1089
    /**
1090
     * @hidden @internal
1091
     */
1092
    public override ngAfterViewInit() {
1093
        Promise.resolve().then(() => {
130✔
1094
            super.ngAfterViewInit();
130✔
1095
        });
1096
    }
1097

1098
    /**
1099
     * @hidden @internal
1100
     */
1101
    public ngOnChanges(changes: SimpleChanges) {
1102
        if (changes.superCompactMode && !changes.superCompactMode.isFirstChange()) {
177!
1103
            this._shouldUpdateSizes = true;
×
1104
            resizeObservable(this.verticalScrollContainer.displayContainer).pipe(take(1), takeUntil(this.destroy$)).subscribe(() => this.resizeNotify.next());
×
1105
        }
1106
    }
1107

1108
    /**
1109
     * Notifies for dimension change.
1110
     */
1111
    public notifyDimensionChange(regenerateColumns = false) {
×
1112
        if (regenerateColumns) {
19✔
1113
            this.setupColumns();
19✔
1114
        }
1115
        this.pipeTrigger++;
19✔
1116
        this.cdr.detectChanges();
19✔
1117
    }
1118

1119
    /**
1120
     * Gets the full list of dimensions.
1121
     *
1122
     * @example
1123
     * ```typescript
1124
     * const dimensions = this.grid.allDimensions;
1125
     * ```
1126
     */
1127
    public get allDimensions() {
1128
        const config = this._pivotConfiguration;
1,636✔
1129
        if (!config) return [];
1,636✔
1130
        return (config.rows || []).concat((config.columns || [])).concat(config.filters || []).filter(x => x !== null && x !== undefined);
4,040!
1131
    }
1132

1133
    protected get allVisibleDimensions() {
1134
        const config = this._pivotConfiguration;
278✔
1135
        if (!config) return [];
278✔
1136
        const uniqueVisibleRowDims = this.visibleRowDimensions.filter(dim => !config.rows.find(configRow => configRow.memberName === dim.memberName));
327✔
1137
        const rows = (config.rows || []).concat(...uniqueVisibleRowDims);
274!
1138
        return rows.concat((config.columns || [])).concat(config.filters || []).filter(x => x !== null && x !== undefined);
774!
1139
    }
1140

1141
    protected override get shouldResize(): boolean {
1142
        if (!this.dataRowList.first?.cells || this.dataRowList.first.cells.length === 0) {
128!
1143
            return false;
×
1144
        }
1145
        const isSizePropChanged = super.shouldResize;
128✔
1146
        if (isSizePropChanged || this._shouldUpdateSizes) {
128✔
1147
            this._shouldUpdateSizes = false;
58✔
1148
            return true;
58✔
1149
        }
1150
        return false;
70✔
1151
    }
1152

1153
    /** @hidden @internal */
1154
    public createFilterESF(dropdown: any, column: ColumnType, options: OverlaySettings, shouldReatach: boolean) {
1155
        options.outlet = this.outlet;
5✔
1156
        if (dropdown) {
5✔
1157
            dropdown.initialize(column, this.overlayService);
5✔
1158
            if (shouldReatach) {
5✔
1159
                const id = this.overlayService.attach(dropdown.element, options);
3✔
1160
                dropdown.overlayComponentId = id;
3✔
1161
                return { id, ref: undefined };
3✔
1162
            }
1163
            return { id: dropdown.overlayComponentId, ref: undefined };
2✔
1164
        }
1165
    }
1166

1167
    /** @hidden */
1168
    public override featureColumnsWidth() {
1169
        return this.pivotRowWidths || 0;
8,046✔
1170
    }
1171

1172
    /* blazorSuppress */
1173
    /**
1174
     * Gets/Sets the value of the `id` attribute.
1175
     *
1176
     * @remarks
1177
     * If not provided it will be automatically generated.
1178
     * @example
1179
     * ```html
1180
     * <igx-pivot-grid [id]="'igx-pivot-1'" [data]="Data"></igx-pivot-grid>
1181
     * ```
1182
     */
1183
    @HostBinding('attr.id')
1184
    @Input()
1185
    public get id(): string {
1186
        return this.p_id;
90,972✔
1187
    }
1188
    /* blazorSuppress */
1189
    public set id(value: string) {
1190
        this.p_id = value;
×
1191
    }
1192

1193
    /* treatAsRef */
1194
    /* blazorAlternateType: object */
1195
    /**
1196
     * Gets/Sets the array of data that populates the component.
1197
     * ```html
1198
     * <igx-pivot-grid [data]="Data"></igx-pivot-grid>
1199
     * ```
1200
     */
1201
    @Input()
1202
    public set data(value: any[] | null) {
1203
        this._data = value || [];
138!
1204
        if (!this._init) {
138✔
1205
            if (this.autoGenerateConfig) {
8✔
1206
                this.generateConfig();
1✔
1207
            }
1208
            this.setupColumns();
8✔
1209
            this.reflow();
8✔
1210
        }
1211
        this.cdr.markForCheck();
138✔
1212
        if (this.height === null || this.height.indexOf('%') !== -1) {
138✔
1213
            // If the height will change based on how much data there is, recalculate sizes in igxForOf.
1214
            this.notifyChanges(true);
52✔
1215
        }
1216
    }
1217

1218
    /* treatAsRef */
1219
    /* blazorAlternateType: object */
1220
    /**
1221
     * Returns an array of data set to the component.
1222
     * ```typescript
1223
     * let data = this.grid.data;
1224
     * ```
1225
     */
1226
    public get data(): any[] | null {
1227
        return this._data;
9,140✔
1228
    }
1229

1230
    /**
1231
     * @hidden
1232
     */
1233
    public getContext(rowData, rowIndex): any {
1234
        return {
10,866✔
1235
            $implicit: rowData,
1236
            templateID: {
1237
                type: 'dataRow',
1238
                id: null
1239
            },
1240
            index: this.getDataViewIndex(rowIndex, false)
1241
        };
1242
    }
1243

1244
    /**
1245
     * @hidden @internal
1246
     */
1247
    public get pivotRowWidths() {
1248
        return this.visibleRowDimensions.length ? this.visibleRowDimensions.reduce((accumulator, dim) => accumulator + this.rowDimensionWidthToPixels(dim), 0) :
19,635✔
1249
            this.rowDimensionWidthToPixels(this.emptyRowDimension);
1250
    }
1251

1252
    /**
1253
     * @hidden @internal
1254
     */
1255
    public rowDimensionWidth(dim): string {
1256
        const isAuto = dim.width && dim.width.indexOf('auto') !== -1;
43,069✔
1257
        if (isAuto) {
43,069✔
1258
            return dim.autoWidth ? dim.autoWidth + 'px' : 'fit-content';
121!
1259
        } else {
1260
            return this.rowDimensionWidthToPixels(dim) + 'px';
42,948✔
1261
        }
1262
    }
1263

1264
    /**
1265
     * @hidden @internal
1266
     */
1267
    public rowDimensionWidthToPixels(dim: IPivotDimension): number {
1268
        if (!dim?.width) {
87,677✔
1269
            return MINIMUM_COLUMN_WIDTH;
85,133✔
1270
        }
1271
        const isPercent = dim.width && dim.width.indexOf('%') !== -1;
2,544✔
1272
        const isAuto = dim.width && dim.width.indexOf('auto') !== -1;
2,544✔
1273
        if (isPercent) {
2,544✔
1274
            return Math.round(parseFloat(dim.width) / 100 * this.calcWidth);
672✔
1275
        } else if (isAuto) {
1,872✔
1276
            return dim.autoWidth;
101✔
1277
        } else {
1278
            return parseInt(dim.width, 10);
1,771✔
1279
        }
1280
    }
1281

1282
    /**
1283
     * @hidden @internal
1284
     */
1285
    public reverseDimensionWidthToPercent(width: number): number {
1286
        return (width * 100 / this.calcWidth);
1✔
1287
    }
1288

1289
    /** @hidden @internal */
1290
    public get pivotContentCalcWidth() {
1291
        const totalDimWidth = this.rowDimensions.length > 0 ?
2,151✔
1292
            this.rowDimensions.map((dim) => this.rowDimensionWidthToPixels(dim)).reduce((prev, cur) => prev + cur) :
2,924✔
1293
            0;
1294
        return this.calcWidth - totalDimWidth;
2,151✔
1295
    }
1296

1297
    /** @hidden @internal */
1298
    public get pivotPinnedWidth() {
1299
        return !this._init ? (this.isPinningToStart ? this.pinnedWidth : this.headerFeaturesWidth) : 0;
10,755!
1300
    }
1301

1302
    /** @hidden @internal */
1303
    public get pivotUnpinnedWidth() {
1304
        return this.unpinnedWidth || 0;
2,151!
1305
    }
1306

1307
    /** @hidden @internal */
1308
    public get rowDimensions() {
1309
        return this.pivotConfiguration.rows?.filter(x => x.enabled) || [];
116,763✔
1310
    }
1311

1312
    /** @hidden @internal */
1313
    public set visibleRowDimensions(value: IPivotDimension[]) {
1314
        this._visibleRowDimensions = value;
387✔
1315
    }
1316

1317
    public get visibleRowDimensions() {
1318
        return this._visibleRowDimensions || this.rowDimensions;
32,454!
1319
    }
1320

1321
    /** @hidden @internal */
1322
    public get columnDimensions() {
1323
        return this.pivotConfiguration.columns?.filter(x => x.enabled) || [];
305,617✔
1324
    }
1325

1326
    /** @hidden @internal */
1327
    public get filterDimensions() {
1328
        return this.pivotConfiguration.filters?.filter(x => x.enabled) || [];
6,197✔
1329
    }
1330

1331
    /** @hidden @internal */
1332
    public get values() {
1333
        return this.pivotConfiguration.values?.filter(x => x.enabled) || [];
675,565✔
1334
    }
1335

1336
    public toggleColumn(col: IgxColumnComponent) {
1337
        const state = this.columnGroupStates.get(col.field);
4✔
1338
        const newState = !state;
4✔
1339
        this.columnGroupStates.set(col.field, newState);
4✔
1340
        this.toggleRowGroup(col, newState);
4✔
1341
        this.reflow();
4✔
1342
    }
1343

1344
    /**
1345
     * @hidden @internal
1346
     */
1347
    public override isRecordPinnedByIndex(_rowIndex: number) {
1348
        return null;
×
1349
    }
1350

1351
    /**
1352
     * @hidden @internal
1353
     */
1354
    public override toggleColumnVisibility(_args: IColumnVisibilityChangedEventArgs) {
1355
        return;
×
1356
    }
1357

1358
    /**
1359
     * @hidden @internal
1360
     */
1361
    public override expandAll() {
1362
    }
1363

1364
    /**
1365
     * @hidden @internal
1366
     */
1367
    public override collapseAll() {
1368
    }
1369

1370
    /**
1371
     * @hidden @internal
1372
     */
1373
    public override expandRow(_rowID: any) {
1374
    }
1375

1376
    /**
1377
     * @hidden @internal
1378
     */
1379
    public override collapseRow(_rowID: any) {
1380
    }
1381

1382
    /**
1383
     * @hidden @internal
1384
     */
1385
    public override get pinnedRows(): IgxGridRowComponent[] {
1386
        return;
2✔
1387
    }
1388

1389
    /**
1390
     * @hidden @internal
1391
     */
1392
    @Input()
1393
    public override get totalRecords(): number {
1394
        return;
×
1395
    }
1396

1397
    public override set totalRecords(_total: number) {
1398
    }
1399

1400
    /**
1401
     * @hidden @internal
1402
     */
1403
    public override moveColumn(_column: IgxColumnComponent, _target: IgxColumnComponent, _pos: DropPosition = DropPosition.AfterDropTarget) {
×
1404
    }
1405

1406
    /**
1407
     * @hidden @internal
1408
     */
1409
    public override addRow(_data: any): void {
1410
    }
1411

1412
    /**
1413
     * @hidden @internal
1414
     */
1415
    public override deleteRow(_rowSelector: any): any {
1416
    }
1417

1418
    /**
1419
     * @hidden @internal
1420
     */
1421
    public override updateCell(_value: any, _rowSelector: any, _column: string): void {
1422
    }
1423

1424
    /**
1425
     * @hidden @internal
1426
     */
1427
    public override updateRow(_value: any, _rowSelector: any): void {
1428
    }
1429

1430
    /**
1431
     * @hidden @internal
1432
     */
1433
    public override enableSummaries(..._rest) {
1434
    }
1435

1436
    /**
1437
     * @hidden @internal
1438
     */
1439
    public override disableSummaries(..._rest) {
1440
    }
1441

1442
    /**
1443
     * @hidden @internal
1444
     */
1445
    public override pinColumn(_columnName: string | IgxColumnComponent, _index?): boolean {
1446
        return;
×
1447
    }
1448

1449
    /**
1450
     * @hidden @internal
1451
     */
1452
    public override unpinColumn(_columnName: string | IgxColumnComponent, _index?): boolean {
1453
        return;
×
1454
    }
1455

1456
    /**
1457
     * @hidden @internal
1458
     */
1459
    public override pinRow(_rowID: any, _index?: number, _row?: RowType): boolean {
1460
        return;
×
1461
    }
1462

1463
    /**
1464
     * @hidden @internal
1465
     */
1466
    public override unpinRow(_rowID: any, _row?: RowType): boolean {
1467
        return;
×
1468
    }
1469

1470
    /**
1471
     * @hidden @internal
1472
     */
1473
    public override get pinnedRowHeight() {
1474
        return;
2,754✔
1475
    }
1476

1477
    /**
1478
     * @hidden @internal
1479
     */
1480
    public override get hasEditableColumns(): boolean {
1481
        return;
×
1482
    }
1483

1484
    /**
1485
     * @hidden @internal
1486
     */
1487
    public override get hasSummarizedColumns(): boolean {
1488
        return;
8✔
1489
    }
1490

1491
    /**
1492
     * @hidden @internal
1493
     */
1494
    public override get hasMovableColumns(): boolean {
1495
        return;
38,311✔
1496
    }
1497

1498
    /**
1499
     * @hidden @internal
1500
     */
1501
    public override get pinnedDataView(): any[] {
1502
        return [];
10,866✔
1503
    }
1504

1505
    /**
1506
     * @hidden @internal
1507
     */
1508
    public override openAdvancedFilteringDialog(_overlaySettings?: OverlaySettings) {
1509
    }
1510

1511
    /**
1512
     * @hidden @internal
1513
     */
1514
    public override closeAdvancedFilteringDialog(_applyChanges: boolean) {
1515
    }
1516

1517
    /**
1518
     * @hidden @internal
1519
     */
1520
    public override endEdit(_commit = true, _event?: Event): boolean {
×
1521
        return;
×
1522
    }
1523

1524
    /**
1525
     * @hidden @internal
1526
     */
1527
    public override beginAddRowById(_rowID: any, _asChild?: boolean): void {
1528
    }
1529

1530
    /**
1531
     * @hidden @internal
1532
     */
1533
    public override beginAddRowByIndex(_index: number): void {
1534
    }
1535

1536
    /**
1537
     * @hidden @internal
1538
     */
1539
    public override clearSearch() { }
1540

1541
    /**
1542
    * @hidden @internal
1543
    */
1544
    public override refreshSearch(_updateActiveInfo?: boolean, _endEdit = true): number {
101✔
1545
        return 0;
488✔
1546
    }
1547

1548
    /**
1549
    * @hidden @internal
1550
    */
1551
    public override findNext(_text: string, _caseSensitive?: boolean, _exactMatch?: boolean): number {
1552
        return 0;
×
1553
    }
1554

1555
    /**
1556
    * @hidden @internal
1557
    */
1558
    public override findPrev(_text: string, _caseSensitive?: boolean, _exactMatch?: boolean): number {
1559
        return 0;
×
1560
    }
1561

1562
    /**
1563
    * @hidden @internal
1564
    */
1565
    public override getNextCell(currRowIndex: number, curVisibleColIndex: number,
1566
        callback: (IgxColumnComponent) => boolean = null): ICellPosition {
×
1567
        return super.getNextCell(currRowIndex, curVisibleColIndex, callback);
×
1568
    }
1569

1570
    /**
1571
    * @hidden @internal
1572
    */
1573
    public override getPreviousCell(currRowIndex: number, curVisibleColIndex: number,
1574
        callback: (IgxColumnComponent) => boolean = null): ICellPosition {
×
1575
        return super.getPreviousCell(currRowIndex, curVisibleColIndex, callback);
×
1576
    }
1577

1578
    /**
1579
    * @hidden @internal
1580
    */
1581
    public override getPinnedWidth(takeHidden = false) {
597✔
1582
        return super.getPinnedWidth(takeHidden);
2,424✔
1583
    }
1584

1585
    /**
1586
     * @hidden @internal
1587
     */
1588
    public override get totalHeight() {
1589
        return this.calcHeight;
4,946✔
1590
    }
1591

1592
    public getColumnGroupExpandState(col: IgxColumnComponent) {
1593
        const state = this.columnGroupStates.get(col.field);
176✔
1594
        // columns are expanded by default?
1595
        return state !== undefined && state !== null ? state : false;
176✔
1596
    }
1597

1598
    public toggleRowGroup(col: IgxColumnComponent, newState: boolean) {
1599
        if (!col) return;
5!
1600
        if (this.hasMultipleValues) {
5✔
1601
            const parentCols = col.parent ? col.parent.children.toArray() : this._autoGeneratedCols.filter(x => x.level === 0);
88!
1602
            const siblingCol = parentCols.filter(x => x.header === col.header && x !== col)[0];
8✔
1603
            const currIndex = parentCols.indexOf(col);
4✔
1604
            const siblingIndex = parentCols.indexOf(siblingCol);
4✔
1605
            if (currIndex < siblingIndex) {
4✔
1606
                // clicked on the full hierarchy header
1607
                this.resolveToggle(col, newState);
3✔
1608
                siblingCol.headerTemplate = this.headerTemplate;
3✔
1609
            } else {
1610
                // clicked on summary parent column that contains just the measures
1611
                col.headerTemplate = undefined;
1✔
1612
                this.resolveToggle(siblingCol, newState);
1✔
1613
            }
1614
        } else {
1615
            const parentCols = col.parent ? col.parent.children : this._autoGeneratedCols.filter(x => x.level === 0);
5!
1616
            const fieldColumn = parentCols.filter(x => x.header === col.header && !x.columnGroup)[0];
2✔
1617
            const groupColumn = parentCols.filter(x => x.header === col.header && x.columnGroup)[0];
2✔
1618
            this.resolveToggle(groupColumn, newState);
1✔
1619
            if (newState) {
1!
1620
                fieldColumn.headerTemplate = this.headerTemplate;
1✔
1621
            } else {
1622
                fieldColumn.headerTemplate = undefined;
×
1623
            }
1624
        }
1625
    }
1626

1627
    /**
1628
    * @hidden @internal
1629
    */
1630
    public override setupColumns() {
1631
        super.setupColumns();
245✔
1632
    }
1633

1634
    /**
1635
    * @hidden @internal
1636
    */
1637
    public override dataRebinding(event: IForOfDataChangingEventArgs) {
1638
        if (this.hasHorizontalLayout) {
356✔
1639
            this.dimensionDataColumns = this.generateDimensionColumns();
30✔
1640
        }
1641

1642
        super.dataRebinding(event);
356✔
1643
    }
1644

1645
    /**
1646
     * Auto-sizes row dimension cells.
1647
     *
1648
     * @remarks
1649
     * Only sizes based on the dimension cells in view.
1650
     * @example
1651
     * ```typescript
1652
     * this.grid.autoSizeRowDimension(dimension);
1653
     * ```
1654
     * @param dimension The row dimension to size.
1655
     */
1656
    public autoSizeRowDimension(dimension: IPivotDimension) {
1657
        if (this.getDimensionType(dimension) === PivotDimensionType.Row) {
2✔
1658
            const relatedDims: string[] = PivotUtil.flatten([dimension]).map((x: IPivotDimension) => x.memberName);
4✔
1659
            const contentCollection =  this.getContentCollection(dimension);
2✔
1660
            const content = contentCollection.filter(x => relatedDims.indexOf(x.dimension.memberName) !== -1);
19✔
1661
            const headers = content.map(x => x.headerGroups.toArray()).flat().map(x => x.header && x.header.refInstance);
10✔
1662
            if (this.pivotUI.showRowHeaders) {
2!
1663
                const dimensionHeader = this.theadRow.rowDimensionHeaders.find(x => x.column.field === dimension.memberName);
×
1664
                headers.push(dimensionHeader);
×
1665
            }
1666
            const autoWidth = this.getLargesContentWidth(headers);
2✔
1667
            if (dimension.width === "auto") {
2!
1668
                dimension.autoWidth = parseFloat(autoWidth);
×
1669
            } else {
1670
                dimension.width = autoWidth;
2✔
1671
            }
1672
            this.pipeTrigger++;
2✔
1673
            this.cdr.detectChanges();
2✔
1674
        }
1675
    }
1676

1677
    /**
1678
     * Inserts dimension in target collection by type at specified index or at the collection's end.
1679
     *
1680
     * @example
1681
     * ```typescript
1682
     * this.grid.insertDimensionAt(dimension, PivotDimensionType.Row, 1);
1683
     * ```
1684
     * @param dimension The dimension that will be added.
1685
     * @param targetCollectionType The target collection type to add to. Can be Row, Column or Filter.
1686
     * @param index The index in the collection at which to add.
1687
     * This parameter is optional. If not set it will add it to the end of the collection.
1688
     */
1689
    public insertDimensionAt(dimension: IPivotDimension, targetCollectionType: PivotDimensionType, index?: number) {
1690
        const targetCollection = this.getDimensionsByType(targetCollectionType);
12✔
1691
        if (index !== undefined) {
12✔
1692
            targetCollection.splice(index, 0, dimension);
11✔
1693
        } else {
1694
            targetCollection.push(dimension);
1✔
1695
        }
1696
        if (targetCollectionType === PivotDimensionType.Column) {
12✔
1697
            this.setupColumns();
4✔
1698
        }
1699
        this.pipeTrigger++;
12✔
1700
        this.dimensionsChange.emit({ dimensions: targetCollection, dimensionCollectionType: targetCollectionType });
12✔
1701
        if (targetCollectionType === PivotDimensionType.Filter) {
12✔
1702
            this.dimensionDataColumns = this.generateDimensionColumns();
3✔
1703
            this.reflow();
3✔
1704
        }
1705
        this.pivotConfigurationChange.emit({ pivotConfiguration: this.pivotConfiguration });
12✔
1706
    }
1707

1708
    /**
1709
     * Move dimension from its currently collection to the specified target collection by type at specified index or at the collection's end.
1710
     *
1711
     * @example
1712
     * ```typescript
1713
     * this.grid.moveDimension(dimension, PivotDimensionType.Row, 1);
1714
     * ```
1715
     * @param dimension The dimension that will be moved.
1716
     * @param targetCollectionType The target collection type to move it to. Can be Row, Column or Filter.
1717
     * @param index The index in the collection at which to add.
1718
     * This parameter is optional. If not set it will add it to the end of the collection.
1719
     */
1720
    public moveDimension(dimension: IPivotDimension, targetCollectionType: PivotDimensionType, index?: number) {
1721
        const prevCollectionType = this.getDimensionType(dimension);
9✔
1722
        if (prevCollectionType === null) return;
9✔
1723
        // remove from old collection
1724
        this._removeDimensionInternal(dimension);
8✔
1725
        // add to target
1726
        this.insertDimensionAt(dimension, targetCollectionType, index);
8✔
1727

1728
        if (prevCollectionType === PivotDimensionType.Column) {
8✔
1729
            this.setupColumns();
3✔
1730
        }
1731
    }
1732

1733
    /**
1734
     * Removes dimension from its currently collection.
1735
     * @remarks
1736
     * This is different than toggleDimension that enabled/disables the dimension.
1737
     * This completely removes the specified dimension from the collection.
1738
     * @example
1739
     * ```typescript
1740
     * this.grid.removeDimension(dimension);
1741
     * ```
1742
     * @param dimension The dimension to be removed.
1743
     */
1744
    public removeDimension(dimension: IPivotDimension) {
1745
        const prevCollectionType = this.getDimensionType(dimension);
4✔
1746
        this._removeDimensionInternal(dimension);
4✔
1747
        if (prevCollectionType === PivotDimensionType.Column) {
4✔
1748
            this.setupColumns();
1✔
1749
        }
1750
        if (prevCollectionType === PivotDimensionType.Filter) {
4✔
1751
            this.reflow();
1✔
1752
        }
1753
        this.pipeTrigger++;
4✔
1754
        this.cdr.detectChanges();
4✔
1755
    }
1756

1757
    /**
1758
     * Toggles the dimension's enabled state on or off.
1759
     * @remarks
1760
     * The dimension remains in its current collection. This just changes its enabled state.
1761
     * @example
1762
     * ```typescript
1763
     * this.grid.toggleDimension(dimension);
1764
     * ```
1765
     * @param dimension The dimension to be toggled.
1766
     */
1767
    public toggleDimension(dimension: IPivotDimension) {
1768
        const dimType = this.getDimensionType(dimension);
12✔
1769
        if (dimType === null) return;
12✔
1770
        const collection = this.getDimensionsByType(dimType);
11✔
1771
        dimension.enabled = !dimension.enabled;
11✔
1772
        if (dimType === PivotDimensionType.Column) {
11✔
1773
            this.setupColumns();
5✔
1774
        }
1775
        if (!dimension.enabled && dimension.filter) {
11✔
1776
            this.filteringService.clearFilter(dimension.memberName);
1✔
1777
        }
1778
        this.pipeTrigger++;
11✔
1779
        this.dimensionsChange.emit({ dimensions: collection, dimensionCollectionType: dimType });
11✔
1780
        this.cdr.detectChanges();
11✔
1781
        if (dimType === PivotDimensionType.Filter) {
11✔
1782
            this.reflow();
3✔
1783
        }
1784
        this.pivotConfigurationChange.emit({ pivotConfiguration: this.pivotConfiguration });
11✔
1785
    }
1786

1787
    /**
1788
     * Inserts value at specified index or at the end.
1789
     *
1790
     * @example
1791
     * ```typescript
1792
     * this.grid.insertValueAt(value, 1);
1793
     * ```
1794
     * @param value The value definition that will be added.
1795
     * @param index The index in the collection at which to add.
1796
     * This parameter is optional. If not set it will add it to the end of the collection.
1797
     */
1798
    public insertValueAt(value: IPivotValue, index?: number) {
1799
        if (!this.pivotConfiguration.values) {
7✔
1800
            this.pivotConfiguration.values = [];
1✔
1801
        }
1802
        const values = this.pivotConfiguration.values;
7✔
1803
        if (index !== undefined) {
7✔
1804
            values.splice(index, 0, value);
6✔
1805
        } else {
1806
            values.push(value);
1✔
1807
        }
1808
        this.setupColumns();
7✔
1809
        this.pipeTrigger++;
7✔
1810
        this.cdr.detectChanges();
7✔
1811
        this.valuesChange.emit({ values });
7✔
1812
        this.pivotConfigurationChange.emit({ pivotConfiguration: this.pivotConfiguration });
7✔
1813
    }
1814

1815
    /**
1816
     * Move value from its currently at specified index or at the end.
1817
     *
1818
     * @example
1819
     * ```typescript
1820
     * this.grid.moveValue(value, 1);
1821
     * ```
1822
     * @param value The value that will be moved.
1823
     * @param index The index in the collection at which to add.
1824
     * This parameter is optional. If not set it will add it to the end of the collection.
1825
     */
1826
    public moveValue(value: IPivotValue, index?: number) {
1827
        if (this.pivotConfiguration.values.indexOf(value) === -1) return;
6✔
1828
        // remove from old index
1829
        this.removeValue(value);
5✔
1830
        // add to new
1831
        this.insertValueAt(value, index);
5✔
1832
    }
1833

1834
    /**
1835
     * Removes value from collection.
1836
     * @remarks
1837
     * This is different than toggleValue that enabled/disables the value.
1838
     * This completely removes the specified value from the collection.
1839
     * @example
1840
     * ```typescript
1841
     * this.grid.removeValue(dimension);
1842
     * ```
1843
     * @param value The value to be removed.
1844
     */
1845
    public removeValue(value: IPivotValue,) {
1846
        const values = this.pivotConfiguration.values;
6✔
1847
        const currentIndex = values.indexOf(value);
6✔
1848
        if (currentIndex !== -1) {
6✔
1849
            values.splice(currentIndex, 1);
6✔
1850
            this.setupColumns();
6✔
1851
            this.pipeTrigger++;
6✔
1852
            this.valuesChange.emit({ values });
6✔
1853
            this.pivotConfigurationChange.emit({ pivotConfiguration: this.pivotConfiguration });
6✔
1854
        }
1855
    }
1856

1857
    /**
1858
     * Toggles the value's enabled state on or off.
1859
     * @remarks
1860
     * The value remains in its current collection. This just changes its enabled state.
1861
     * @example
1862
     * ```typescript
1863
     * this.grid.toggleValue(value);
1864
     * ```
1865
     * @param value The value to be toggled.
1866
     */
1867
    public toggleValue(value: IPivotValue) {
1868
        if (this.pivotConfiguration.values.indexOf(value) === -1) return;
7✔
1869
        value.enabled = !value.enabled;
6✔
1870
        this.setupColumns();
6✔
1871
        this.pipeTrigger++;
6✔
1872
        this.valuesChange.emit({ values: this.pivotConfiguration.values });
6✔
1873
        this.reflow();
6✔
1874
        this.pivotConfigurationChange.emit({ pivotConfiguration: this.pivotConfiguration });
6✔
1875
    }
1876

1877
    /**
1878
     * Sort the dimension and its children in the provided direction.
1879
     * @example
1880
     * ```typescript
1881
     * this.grid.sortDimension(dimension, SortingDirection.Asc);
1882
     * ```
1883
     * @param value The value to be toggled.
1884
     */
1885
    public sortDimension(dimension: IPivotDimension, sortDirection: SortingDirection) {
1886
        const dimensionType = this.getDimensionType(dimension);
20✔
1887
        dimension.sortDirection = sortDirection;
20✔
1888
        // apply same sort direction to children.
1889
        let dim = dimension;
20✔
1890
        if (this.pivotUI.rowLayout === PivotRowLayoutType.Vertical) {
20✔
1891
            while (dim.childLevel) {
18✔
1892
                dim.childLevel.sortDirection = dimension.sortDirection;
6✔
1893
                dim = dim.childLevel;
6✔
1894
            }
1895
        }
1896

1897
        this.pipeTrigger++;
20✔
1898
        this.dimensionsSortingExpressionsChange.emit(this.dimensionsSortingExpressions);
20✔
1899
        if (dimensionType === PivotDimensionType.Column) {
20✔
1900
            this.setupColumns();
13✔
1901
        }
1902
        this.cdr.detectChanges();
20✔
1903
        this.pivotConfigurationChange.emit({ pivotConfiguration: this.pivotConfiguration });
20✔
1904
    }
1905

1906
    /**
1907
     * Filters a single `IPivotDimension`.
1908
     *
1909
     * @example
1910
     * ```typescript
1911
     * public filter() {
1912
     *      const set = new Set();
1913
     *      set.add('Value 1');
1914
     *      set.add('Value 2');
1915
     *      this.grid1.filterDimension(this.pivotConfigHierarchy.rows[0], set, IgxStringFilteringOperand.instance().condition('in'));
1916
     * }
1917
     * ```
1918
     */
1919
    public filterDimension(dimension: IPivotDimension, value: any, conditionOrExpressionTree?: IFilteringOperation | IFilteringExpressionsTree) {
1920
        this.filteringService.filter(dimension.memberName, value, conditionOrExpressionTree);
2✔
1921
        const dimensionType = this.getDimensionType(dimension);
2✔
1922
        if (dimensionType === PivotDimensionType.Column) {
2✔
1923
            this.setupColumns();
1✔
1924
        }
1925
        this.cdr.detectChanges();
2✔
1926
    }
1927

1928
    /**
1929
     * @hidden @internal
1930
     */
1931
    public getRowDimensionByName(memberName: string) {
1932
        const visibleRows = this.pivotUI.rowLayout === PivotRowLayoutType.Vertical ?
15,931✔
1933
         this.pivotConfiguration.rows :
1934
         PivotUtil.flatten(this.pivotConfiguration.rows);
1935
        const dimIndex = visibleRows.findIndex((target) => target.memberName === memberName);
27,707✔
1936
        const dim = visibleRows[dimIndex];
15,931✔
1937
        return dim;
15,931✔
1938
    }
1939

1940
    /**
1941
     * @hidden @internal
1942
     */
1943
    public getDimensionsByType(dimension: PivotDimensionType) {
1944
        switch (dimension) {
43✔
1945
            case PivotDimensionType.Row:
1946
                if (!this.pivotConfiguration.rows) {
15!
1947
                    this.pivotConfiguration.rows = [];
×
1948
                }
1949
                return this.pivotConfiguration.rows;
15✔
1950
            case PivotDimensionType.Column:
1951
                if (!this.pivotConfiguration.columns) {
16!
1952
                    this.pivotConfiguration.columns = [];
×
1953
                }
1954
                return this.pivotConfiguration.columns;
16✔
1955
            case PivotDimensionType.Filter:
1956
                if (!this.pivotConfiguration.filters) {
11✔
1957
                    this.pivotConfiguration.filters = [];
2✔
1958
                }
1959
                return this.pivotConfiguration.filters;
11✔
1960
            default:
1961
                return null;
1✔
1962
        }
1963
    }
1964

1965
    /**
1966
     * @hidden @internal
1967
     */
1968
    public resizeRowDimensionPixels(dimension: IPivotDimension, newWidth: number) {
1969
        const isPercentageWidth = dimension.width && typeof dimension.width === 'string' && dimension.width.indexOf('%') !== -1;
5✔
1970
        if (isPercentageWidth) {
5✔
1971
            dimension.width = this.reverseDimensionWidthToPercent(newWidth).toFixed(2) + '%';
1✔
1972
        } else {
1973
            dimension.width = newWidth + 'px';
4✔
1974
        }
1975

1976
        // Notify the grid to reflow, to update if horizontal scrollbar needs to be rendered/removed.
1977
        this.pipeTrigger++;
5✔
1978
        this.cdr.detectChanges();
5✔
1979
    }
1980

1981
    /*
1982
    * @hidden
1983
    * @internal
1984
    */
1985
    protected _removeDimensionInternal(dimension) {
1986
        const prevCollectionType = this.getDimensionType(dimension);
12✔
1987
        if (prevCollectionType === null) return;
12✔
1988
        const prevCollection = this.getDimensionsByType(prevCollectionType);
11✔
1989
        const currentIndex = prevCollection.indexOf(dimension);
11✔
1990
        prevCollection.splice(currentIndex, 1);
11✔
1991
        this.pipeTrigger++;
11✔
1992
        this.cdr.detectChanges();
11✔
1993
    }
1994

1995
    protected getDimensionType(dimension: IPivotDimension): PivotDimensionType {
1996
        return PivotUtil.flatten(this.pivotConfiguration.rows).indexOf(dimension) !== -1 ? PivotDimensionType.Row :
61✔
1997
            PivotUtil.flatten(this.pivotConfiguration.columns).indexOf(dimension) !== -1 ? PivotDimensionType.Column :
40✔
1998
                (!!this.pivotConfiguration.filters && PivotUtil.flatten(this.pivotConfiguration.filters).indexOf(dimension) !== -1) ?
39✔
1999
                    PivotDimensionType.Filter : null;
2000
    }
2001

2002
    protected getPivotRowHeaderContentWidth(headerGroup: IgxPivotRowHeaderGroupComponent) {
2003
        const headerSizes = this.getHeaderCellWidth(headerGroup.header.refInstance.nativeElement);
×
2004
        return headerSizes.width + headerSizes.padding;
×
2005
    }
2006

2007
    protected getLargesContentWidth(contents: ElementRef[]): string {
2008
        const largest = new Map<number, number>();
2✔
2009
        if (contents.length > 0) {
2✔
2010
            const cellsContentWidths = [];
2✔
2011
            contents.forEach((elem) => {
2✔
2012
                elem instanceof IgxPivotRowHeaderGroupComponent ?
10!
2013
                    cellsContentWidths.push(this.getPivotRowHeaderContentWidth(elem)) :
2014
                    cellsContentWidths.push(this.getHeaderCellWidth(elem.nativeElement).width);
2015
            });
2016
            const index = cellsContentWidths.indexOf(Math.max(...cellsContentWidths));
2✔
2017
            const cellStyle = this.document.defaultView.getComputedStyle(contents[index].nativeElement);
2✔
2018
            const cellPadding = parseFloat(cellStyle.paddingLeft) + parseFloat(cellStyle.paddingRight) +
2✔
2019
                parseFloat(cellStyle.borderLeftWidth) + parseFloat(cellStyle.borderRightWidth);
2020
            largest.set(Math.max(...cellsContentWidths), cellPadding);
2✔
2021
        }
2022
        const largestCell = Math.max(...Array.from(largest.keys()));
2✔
2023
        const width = Math.ceil(largestCell + largest.get(largestCell));
2✔
2024

2025
        if (Number.isNaN(width)) {
2!
2026
            return null;
×
2027
        } else {
2028
            return width + 'px';
2✔
2029
        }
2030
    }
2031

2032
    /** @hidden @internal */
2033
    public get hasHorizontalLayout() {
2034
        return this.pivotUI.rowLayout === PivotRowLayoutType.Horizontal;
101,089✔
2035
    }
2036

2037
    /**
2038
    * @hidden
2039
    */
2040
    public get hasMultipleValues() {
2041
        return this.values.length > 1;
172,343✔
2042
    }
2043

2044
    /**
2045
    * @hidden
2046
    */
2047
    public get excelStyleFilterMaxHeight() {
2048
        // max 10 rows, row size depends on grid size
2049
        const maxHeight = this.renderedRowHeight * 10;
4,299✔
2050
        return `${maxHeight}px`;
4,299✔
2051
    }
2052

2053
    /**
2054
    * @hidden
2055
    */
2056
    public get excelStyleFilterMinHeight(): string {
2057
        // min 5 rows, row size depends on grid size
2058
        const minHeight = this.renderedRowHeight * 5;
4,299✔
2059
        return `${minHeight}px`;
4,299✔
2060
    }
2061

2062
    /** @hidden @internal */
2063
    public override get activeDescendant() {
2064
        const activeElem = this.navigation.activeNode;
4,302✔
2065
        if ((this.navigation as IgxPivotGridNavigationService).isRowHeaderActive ||
4,302✔
2066
            (this.navigation as IgxPivotGridNavigationService).isRowDimensionHeaderActive) {
2067
            if (!activeElem || !Object.keys(activeElem).length) {
198!
2068
                return this.id;
×
2069
            }
2070

2071
            return `${this.id}_${activeElem.row}_${activeElem.column}`;
198✔
2072
        }
2073

2074
        return super.activeDescendant;
4,104✔
2075
    }
2076

2077
    protected resolveToggle(groupColumn: IgxColumnComponent, state: boolean) {
2078
        if (!groupColumn) return;
8!
2079
        groupColumn.hidden = state;
8✔
2080
        this.columnGroupStates.set(groupColumn.field, state);
8✔
2081
        const childrenTotal = this.hasMultipleValues ?
8✔
2082
            groupColumn.children.filter(x => x.columnGroup && x.children.filter(y => !y.columnGroup).length === this.values.length) :
44✔
2083
            groupColumn.children.filter(x => !x.columnGroup);
3✔
2084
        const childrenSubgroups = this.hasMultipleValues ?
8✔
2085
            groupColumn.children.filter(x => x.columnGroup && x.children.filter(y => !y.columnGroup).length === 0) :
44✔
2086
            groupColumn.children.filter(x => x.columnGroup);
3✔
2087
        childrenTotal.forEach(group => {
8✔
2088
            const newState = this.columnGroupStates.get(group.field) || state;
18✔
2089
            if (newState) {
18✔
2090
                group.headerTemplate = this.headerTemplate;
11✔
2091
            } else {
2092
                group.headerTemplate = undefined;
7✔
2093
            }
2094
        });
2095
        if (!groupColumn.hidden && childrenSubgroups.length > 0) {
8✔
2096
            childrenSubgroups.forEach(group => {
1✔
2097
                const newState = this.columnGroupStates.get(group.field) || state;
3✔
2098
                this.resolveToggle(group, newState);
3✔
2099
            });
2100
        }
2101
    }
2102

2103
    protected override buildDataView(data: any[]) {
2104
        this._dataView = data;
387✔
2105
    }
2106

2107
    /**
2108
     * @hidden @internal
2109
     */
2110
    protected override getDataBasedBodyHeight(): number {
2111
        const dvl = this.dataView?.length || 0;
81!
2112
        return dvl < this._defaultTargetRecordNumber ? 0 : this.defaultTargetBodyHeight;
81✔
2113
    }
2114

2115
    protected override horizontalScrollHandler(event) {
2116
        const scrollLeft = event.target.scrollLeft;
4✔
2117
        this.theadRow.headerContainers.forEach(headerForOf => {
4✔
2118
            headerForOf.onHScroll(scrollLeft);
8✔
2119
        });
2120
        super.horizontalScrollHandler(event);
4✔
2121
    }
2122

2123
    protected override verticalScrollHandler(event) {
2124
        this.verticalRowDimScrollContainers.forEach(x => {
×
2125
            x.onScroll(event);
×
2126
        });
2127
        super.verticalScrollHandler(event);
×
2128
    }
2129

2130
    /**
2131
     * @hidden
2132
     */
2133
    protected override autogenerateColumns() {
2134
        let columns = [];
245✔
2135
        const data = this.gridAPI.filterDataByExpressions(this.filteringExpressionsTree);
245✔
2136
        this.dimensionDataColumns = this.generateDimensionColumns();
245✔
2137
        const flattenedColumnsWithSorting = PivotUtil.flatten(this.columnDimensions).filter(dim => dim.sortDirection);
247✔
2138
        const expressions = flattenedColumnsWithSorting.length > 0 ? PivotSortUtil.generateDimensionSortingExpressions(flattenedColumnsWithSorting) : [];
245✔
2139
        let sortedData = data;
245✔
2140
        if (expressions.length > 0) {
245✔
2141
            sortedData = DataUtil.sort(cloneArray(data), expressions, this.sortStrategy, this);
12✔
2142
        }
2143
        let fieldsMap;
2144
        if (this.pivotConfiguration.columnStrategy && this.pivotConfiguration.columnStrategy instanceof NoopPivotDimensionsStrategy) {
245✔
2145
            const fields = this.generateDataFields(sortedData);
5✔
2146
            if (fields.length === 0) return;
5✔
2147
            const rowFields = PivotUtil.flatten(this.pivotConfiguration.rows).map(x => x.memberName);
6✔
2148
            const keyFields = Object.values(this.pivotKeys);
3✔
2149
            const filteredFields = fields.filter(x => rowFields.indexOf(x) === -1 && keyFields.indexOf(x) === -1 &&
18✔
2150
                x.indexOf(this.pivotKeys.rowDimensionSeparator + this.pivotKeys.level) === -1 &&
2151
                x.indexOf(this.pivotKeys.rowDimensionSeparator + this.pivotKeys.records) === -1);
2152
            fieldsMap = this.generateFromData(filteredFields);
3✔
2153
        } else {
2154
            fieldsMap = PivotUtil.getFieldsHierarchy(
240✔
2155
                sortedData,
2156
                this.columnDimensions,
2157
                PivotDimensionType.Column,
2158
                this.pivotKeys,
2159
                this.pivotValueCloneStrategy
2160
            );
2161
        }
2162
        columns = this.generateColumnHierarchy(fieldsMap, sortedData);
243✔
2163
        this._autoGeneratedCols = columns;
243✔
2164
        // reset expansion states if any are stored.
2165
        this.columnGroupStates.forEach((value, key) => {
243✔
2166
            if (value) {
1✔
2167
                const primaryColumn = columns.find(x => x.field === key && x.headerTemplate === this.headerTemplate);
1✔
2168
                const groupSummaryColumn = columns.find(x => x.field === key && x.headerTemplate !== this.headerTemplate);
14✔
2169
                this.toggleRowGroup(primaryColumn, value);
1✔
2170
                if (groupSummaryColumn) {
1✔
2171
                    groupSummaryColumn.headerTemplate = this.headerTemplate;
1✔
2172
                }
2173
            }
2174
        });
2175

2176
        this.updateColumns(columns);
243✔
2177
        this.pipeTrigger++;
243✔
2178
        this.reflow();
243✔
2179
    }
2180

2181
    protected generateDimensionColumns(): IgxColumnComponent[] {
2182
        const columns = [];
278✔
2183
        this.allVisibleDimensions.forEach((dim) => {
278✔
2184
            const ref = createComponent(IgxColumnComponent, { environmentInjector: this.envInjector, elementInjector: this.injector });
774✔
2185
            ref.instance.field = dim.memberName;
774✔
2186
            ref.instance.header = dim.displayName || dim.memberName;
774✔
2187
            ref.instance.headerTemplate = this.rowDimensionHeaderTemplate;
774✔
2188
            ref.instance.resizable = this.rowDimensionResizing;
774✔
2189
            ref.instance.sortable = dim.sortable === undefined ? true : dim.sortable;
774!
2190
            ref.instance.width = this.rowDimensionWidth(dim);
774✔
2191
            ref.changeDetectorRef.detectChanges();
774✔
2192
            columns.push(ref.instance);
774✔
2193
        });
2194
        return columns;
278✔
2195
    }
2196

2197
    protected override calculateGridSizes(recalcFeatureWidth = true) {
499✔
2198
        super.calculateGridSizes(recalcFeatureWidth);
499✔
2199
        if (this.hasDimensionsToAutosize) {
499✔
2200
            this.cdr.detectChanges();
2✔
2201
            this.zone.onStable.pipe(first()).subscribe(() => {
2✔
2202
                requestAnimationFrame(() => {
2✔
2203
                    this.autoSizeDimensionsInView();
2✔
2204
                });
2205
            });
2206
        }
2207
    }
2208

2209
    protected getContentCollection(dimenstion: IPivotDimension) {
2210
        let contentCollection;
2211
        if (this.hasHorizontalLayout) {
3!
2212
            const allMrlContents = this.rowDimensionMrlRowsCollection.map(mrlRow => mrlRow.contentCells.toArray()).flat();
×
2213
            contentCollection = allMrlContents.filter(cell => cell.rootDimension === dimenstion);
×
2214
        } else {
2215
            contentCollection = this.rowDimensionContentCollection.toArray();
3✔
2216
        }
2217
        return contentCollection;
3✔
2218
    }
2219

2220
    protected autoSizeDimensionsInView() {
2221
        if (!this.hasDimensionsToAutosize) return;
2✔
2222
        for (const dim of this.visibleRowDimensions) {
1✔
2223
            if (dim.width === 'auto') {
1✔
2224
                const contentWidths = [];
1✔
2225
                const relatedDims = PivotUtil.flatten([dim]).map(x => x.memberName);
2✔
2226
                const contentCollection = this.getContentCollection(dim);
1✔
2227
                const content = contentCollection.filter(x => relatedDims.indexOf(x.dimension.memberName) !== -1);
5✔
2228
                const headers = content.map(x => x.headerGroups.toArray()).flat().map(x => x.header && x.header.refInstance);
5✔
2229
                headers.forEach((header) => contentWidths.push(header?.nativeElement?.offsetWidth || 0));
5!
2230
                if (this.pivotUI.showRowHeaders) {
1!
2231
                    const dimensionHeader = this.theadRow.rowDimensionHeaders.find(x => x.column.field === dim.memberName);
×
2232
                    contentWidths.push(parseFloat(this.getLargesContentWidth([dimensionHeader])));
×
2233
                }
2234
                const max = Math.max(...contentWidths);
1✔
2235
                if (max === 0) {
1!
2236
                    // cells not in DOM yet...
2237
                    continue;
×
2238
                }
2239
                const maxSize = Math.ceil(Math.max(...contentWidths));
1✔
2240
                dim.autoWidth = maxSize;
1✔
2241
            }
2242
        }
2243

2244
        if (this.isColumnWidthSum) {
1!
2245
            this.calcWidth = this.getColumnWidthSum();
×
2246
        }
2247
    }
2248

2249
    /** @hidden @internal */
2250
    public get hasDimensionsToAutosize() {
2251
        return this.rowDimensions.some(x => x.width === 'auto' && !x.autoWidth);
694✔
2252
    }
2253

2254
    protected generateFromData(fields: string[]) {
2255
        const separator = this.pivotKeys.columnDimensionSeparator;
3✔
2256
        const dataArr = fields.map(x => x.split(separator)).sort(x => x.length);
12✔
2257
        const hierarchy = new Map<string, any>();
3✔
2258
        const columnDimensions =  PivotUtil.flatten(this.columnDimensions);
3✔
2259
        dataArr.forEach(arr => {
3✔
2260
            let currentHierarchy = hierarchy;
12✔
2261
            const path = [];
12✔
2262
            let index = 0;
12✔
2263
            for (const val of arr) {
12✔
2264
                path.push(val);
12✔
2265
                const newPath = path.join(separator);
12✔
2266
                let targetHierarchy = currentHierarchy.get(newPath);
12✔
2267
                if (!targetHierarchy) {
12✔
2268
                    const currentColumnDimension = columnDimensions[index];
12✔
2269
                    currentHierarchy.set(newPath, { value: newPath, expandable: !!currentColumnDimension.childLevel, children: new Map<string, any>(), dimension: currentColumnDimension });
12✔
2270
                    targetHierarchy = currentHierarchy.get(newPath);
12✔
2271
                }
2272
                currentHierarchy = targetHierarchy.children;
12✔
2273
                index++;
12✔
2274
            }
2275
        });
2276
        return hierarchy;
3✔
2277
    }
2278

2279
    protected generateColumnHierarchy(fields: Map<string, any>, data, parent = null): IgxColumnComponent[] {
243✔
2280
        let columns = [];
307✔
2281
        if (fields.size === 0) {
307✔
2282
            this.values.forEach((value) => {
19✔
2283
                const ref = createComponent(IgxColumnComponent, { environmentInjector: this.envInjector, elementInjector: this.injector });
19✔
2284
                ref.instance.header = value.displayName;
19✔
2285
                ref.instance.field = value.member;
19✔
2286
                ref.instance.parent = parent;
19✔
2287
                ref.instance.sortable = true;
19✔
2288
                ref.instance.dataType = value.dataType || this.resolveDataTypes(data.length ? data[0][value.member] : null);
19!
2289
                ref.instance.formatter = value.formatter;
19✔
2290
                columns.push(ref.instance);
19✔
2291
            });
2292
            return columns;
19✔
2293
        }
2294
        const currentFields = fields;
288✔
2295
        currentFields.forEach((value) => {
288✔
2296
            let shouldGenerate = true;
982✔
2297
            if (data.length === 0) {
982!
2298
                shouldGenerate = false;
×
2299
            }
2300
            if (shouldGenerate && (value.children == null || value.children.length === 0 || value.children.size === 0)) {
982✔
2301
                const col = this.createColumnForDimension(value, data, parent, this.hasMultipleValues);
918✔
2302
                columns.push(col);
918✔
2303
                if (this.hasMultipleValues) {
918✔
2304
                    const measureChildren = this.getMeasureChildren(data, col, false, value.dimension.width);
750✔
2305
                    col.children.reset(measureChildren);
750✔
2306
                    columns = columns.concat(measureChildren);
750✔
2307
                }
2308

2309
            } else if (shouldGenerate) {
64✔
2310
                const col = this.createColumnForDimension(value, data, parent, true);
64✔
2311
                if (value.expandable) {
64✔
2312
                    col.headerTemplate = this.headerTemplate;
21✔
2313
                }
2314
                const children = this.generateColumnHierarchy(value.children, data, col);
64✔
2315
                const filteredChildren = children.filter(x => x.level === col.level + 1);
456✔
2316
                columns.push(col);
64✔
2317
                if (this.hasMultipleValues) {
64✔
2318
                    let measureChildren = this.getMeasureChildren(data, col, true, value.dimension.width);
63✔
2319
                    const nestedChildren = filteredChildren;
63✔
2320
                    //const allChildren = children.concat(measureChildren);
2321
                    col.children.reset(nestedChildren);
63✔
2322
                    columns = columns.concat(children);
63✔
2323
                    if (value.dimension.childLevel) {
63✔
2324
                        const sibling = this.createColumnForDimension(value, data, parent, true);
20✔
2325
                        columns.push(sibling);
20✔
2326

2327
                        measureChildren = this.getMeasureChildren(data, sibling, false, value.dimension?.width);
20✔
2328
                        sibling.children.reset(measureChildren);
20✔
2329
                        columns = columns.concat(measureChildren);
20✔
2330
                    }
2331

2332
                } else {
2333
                    col.children.reset(filteredChildren);
1✔
2334
                    columns = columns.concat(children);
1✔
2335
                    if (value.dimension.childLevel) {
1✔
2336
                        const sibling = this.createColumnForDimension(value, data, parent, false);
1✔
2337
                        columns.push(sibling);
1✔
2338
                    }
2339
                }
2340
            }
2341
        });
2342

2343
        return columns;
288✔
2344
    }
2345

2346

2347
    protected generateConfig() {
2348
        if (!this.data) return;
1!
2349

2350
        const data = this.data;
1✔
2351
        const fields = this.generateDataFields(data);
1✔
2352
        const columnDimensions: IPivotDimension[] = [];
1✔
2353
        const rowDimensions: IPivotDimension[] = [];
1✔
2354
        const values: IPivotValue[] = [];
1✔
2355
        let isFirstDate = true;
1✔
2356
        fields.forEach((field) => {
1✔
2357
            const dataType = this.resolveDataTypes(data[0][field]);
6✔
2358
            switch (dataType) {
6✔
2359
                case "number":
2360
                    {
2361
                        const value: IPivotValue = {
2✔
2362
                            member: field,
2363
                            displayName: field,
2364
                            dataType: dataType,
2365
                            aggregate: {
2366
                                key: 'sum',
2367
                                label: 'Sum',
2368
                                aggregatorName: "SUM"
2369
                            },
2370
                            enabled: true
2371
                        };
2372
                        values.push(value);
2✔
2373
                        break;
2✔
2374
                }
2375
            case "date":
2376
            {
2377
                const dimension: IPivotDimension = new IgxPivotDateDimension(
1✔
2378
                    {
2379
                        memberName: field,
2380
                        enabled: isFirstDate,
2381
                        dataType: dataType
2382
                    }
2383
                )
2384
                rowDimensions.push(dimension);
1✔
2385
                isFirstDate = false;
1✔
2386
                break;
1✔
2387
            }
2388
                default: {
2389
                    const dimension: IPivotDimension = {
3✔
2390
                        memberName: field,
2391
                        enabled: false,
2392
                        dataType: dataType
2393
                    };
2394
                    columnDimensions.push(dimension);
3✔
2395
                    break;
3✔
2396
                }
2397
            }
2398
        });
2399
        const config: IPivotConfiguration = {
1✔
2400
            columns: columnDimensions,
2401
            rows: rowDimensions,
2402
            values: values
2403
        };
2404
        this.pivotConfiguration = config;
1✔
2405
    }
2406

2407
    protected createColumnForDimension(value: any, data: any, parent: ColumnType, isGroup: boolean) {
2408
        const key = value.value;
1,003✔
2409
        const ref = isGroup ?
1,003✔
2410
            createComponent(IgxColumnGroupComponent, { environmentInjector: this.envInjector, elementInjector: this.injector }) :
2411
            createComponent(IgxColumnComponent, { environmentInjector: this.envInjector, elementInjector: this.injector });
2412
        ref.instance.header = parent != null ? key.split(parent.header + this.pivotKeys.columnDimensionSeparator)[1] : key;
1,003✔
2413
        ref.instance.field = key;
1,003✔
2414
        ref.instance.parent = parent;
1,003✔
2415
        if (value.dimension.width) {
1,003!
2416
            ref.instance.width = value.dimension.width;
×
2417
        }
2418
        const valueDefinition = this.values[0];
1,003✔
2419
        ref.instance.dataType = valueDefinition?.dataType || this.resolveDataTypes(data[0][valueDefinition?.member]);
1,003✔
2420
        ref.instance.formatter = valueDefinition?.formatter;
1,003✔
2421
        ref.instance.sortable = true;
1,003✔
2422
        ref.changeDetectorRef.detectChanges();
1,003✔
2423
        return ref.instance;
1,003✔
2424
    }
2425

2426
    protected resolveColumnDimensionWidth(dim: IPivotDimension) {
2427
        if (dim.width) {
×
2428
            return dim.width;
×
2429
        }
2430
        return this.minColumnWidth + 'px';
×
2431
    }
2432

2433
    protected getMeasureChildren(data, parent, hidden, parentWidth) {
2434
        const cols = [];
833✔
2435
        const count = this.values.length;
833✔
2436
        const childWidth = parseInt(parentWidth, 10) / count;
833✔
2437
        const isPercent = parentWidth && parentWidth.indexOf('%') !== -1;
833!
2438
        const isAuto = parentWidth && parentWidth.indexOf('auto') !== -1;
833!
2439
        this.values.forEach(val => {
833✔
2440
            const ref = createComponent(IgxColumnComponent, { environmentInjector: this.envInjector, elementInjector: this.injector });
1,671✔
2441
            ref.instance.header = val.displayName || val.member;
1,671✔
2442
            ref.instance.field = parent.field + this.pivotKeys.columnDimensionSeparator + val.member;
1,671✔
2443
            ref.instance.parent = parent;
1,671✔
2444
            if (parentWidth) {
1,671!
2445
                ref.instance.width = isAuto ? 'auto' : isPercent ? childWidth + '%' : childWidth + 'px';
×
2446
            }
2447
            ref.instance.hidden = hidden;
1,671✔
2448
            ref.instance.sortable = this._sortableColumns;
1,671✔
2449
            ref.instance.dataType = val.dataType || this.resolveDataTypes(data[0][val.member]);
1,671✔
2450
            ref.instance.formatter = val.formatter;
1,671✔
2451
            ref.changeDetectorRef.detectChanges();
1,671✔
2452
            cols.push(ref.instance);
1,671✔
2453
        });
2454
        return cols;
833✔
2455
    }
2456

2457
    /**
2458
    * @hidden @internal
2459
    */
2460
    @ViewChild('emptyPivotGridTemplate', { read: TemplateRef, static: true })
2461
    public defaultEmptyPivotGridTemplate: TemplateRef<any>;
2462

2463
    /**
2464
     * Gets/Sets a custom template when pivot grid is empty.
2465
     *
2466
     * @example
2467
     * ```html
2468
     * <igx-pivot-grid [emptyPivotGridTemplate]="myTemplate"><igx-pivot-grid>
2469
     * ```
2470
     */
2471
    @Input()
2472
    public emptyPivotGridTemplate: TemplateRef<void>;
2473

2474
    /**
2475
    * @hidden @internal
2476
    */
2477
    public override get template(): TemplateRef<any> {
2478
        const allEnabledDimensions = this.rowDimensions.concat(this.columnDimensions);
2,151✔
2479
        if (allEnabledDimensions.length === 0 && this.values.length === 0) {
2,151✔
2480
            // no enabled values and dimensions
2481
            return this.emptyPivotGridTemplate || this.defaultEmptyPivotGridTemplate;
55✔
2482
        }
2483
        return super.template;
2,096✔
2484
    }
2485

2486
    private emitInitEvents(pivotConfig: IPivotConfiguration) {
2487
        const dimensions = PivotUtil.flatten(this.allDimensions);
152✔
2488
        dimensions.forEach(dim => {
152✔
2489
            this.dimensionInit.emit(dim);
531✔
2490
        });
2491
        const values = pivotConfig?.values;
152✔
2492
        values?.forEach(val => {
152✔
2493
            this.valueInit.emit(val);
267✔
2494
        });
2495
    }
2496

2497
    protected rowDimensionByName(memberName: string) {
2498
        return this.visibleRowDimensions.find((rowDim) => rowDim.memberName === memberName);
×
2499
    }
2500

2501
    protected calculateResizerTop() {
2502
        return this.pivotUI.showRowHeaders ?
18✔
2503
            (this.theadRow.pivotFilterContainer?.nativeElement.offsetHeight || 0) + (this.theadRow.pivotRowContainer?.nativeElement.offsetHeight || 0) :
8!
2504
            this.theadRow.nativeElement.offsetHeight;
2505
    }
2506

2507
    protected override updateDefaultRowHeight() {
2508
        super.updateDefaultRowHeight();
190✔
2509
        if (this.hasHorizontalLayout) {
190✔
2510
            // Trigger pipes to recalc heights for the horizontal layout mrl rows.
2511
            this.regroupTrigger++;
12✔
2512
        }
2513
    }
2514

2515
    /**
2516
    * @hidden @internal
2517
    */
2518
    public createRow(index: number, data?: any): RowType {
2519
        let row: RowType;
2520

NEW
2521
        const dataIndex = this._getDataViewIndex(index);
×
NEW
2522
        const rec = data ?? this.dataView[dataIndex];
×
2523

2524

NEW
2525
        if (!row && rec) {
×
NEW
2526
            row = new IgxPivotGridRow(this, index, rec);
×
2527
        }
NEW
2528
        return row;
×
2529
    }
2530
}
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

© 2025 Coveralls, Inc