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

IgniteUI / igniteui-angular / 13548857950

26 Feb 2025 04:38PM CUT coverage: 91.546%. First build
13548857950

Pull #15224

github

web-flow
Merge 175e9d0f8 into 4866dfb75
Pull Request #15224: fix(pivot-grid): added createRow method for grid based events - 18.2

12992 of 15242 branches covered (85.24%)

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

26325 of 28756 relevant lines covered (91.55%)

34002.18 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
    standalone: true,
163
    imports: [
164
        NgIf,
165
        NgFor,
166
        NgClass,
167
        NgStyle,
168
        NgTemplateOutlet,
169
        IgxPivotHeaderRowComponent,
170
        IgxGridBodyDirective,
171
        IgxGridDragSelectDirective,
172
        IgxColumnMovingDropDirective,
173
        IgxGridForOfDirective,
174
        IgxTemplateOutletDirective,
175
        IgxPivotRowComponent,
176
        IgxToggleDirective,
177
        IgxCircularProgressBarComponent,
178
        IgxSnackbarComponent,
179
        IgxOverlayOutletDirective,
180
        IgxPivotGridColumnResizerComponent,
181
        IgxIconComponent,
182
        IgxPivotRowDimensionContentComponent,
183
        IgxGridExcelStyleFilteringComponent,
184
        IgxExcelStyleColumnOperationsTemplateDirective,
185
        IgxExcelStyleFilterOperationsTemplateDirective,
186
        IgxExcelStyleSearchComponent,
187
        IgxGridRowClassesPipe,
188
        IgxGridRowStylesPipe,
189
        IgxPivotRowPipe,
190
        IgxPivotRowExpansionPipe,
191
        IgxPivotAutoTransform,
192
        IgxPivotColumnPipe,
193
        IgxPivotGridFilterPipe,
194
        IgxPivotGridSortingPipe,
195
        IgxPivotGridColumnSortingPipe,
196
        IgxPivotCellMergingPipe,
197
        IgxPivotGridHorizontalRowGrouping,
198
        IgxPivotRowDimensionMrlRowComponent
199
    ],
200
    schemas: [CUSTOM_ELEMENTS_SCHEMA]
201
})
202
export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnInit, AfterContentInit,
2✔
203
    GridType, AfterViewInit, OnChanges {
204

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

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

231

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

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

258

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

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

285

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

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

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

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

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

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

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

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

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

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

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

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

395

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

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

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

423

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

779

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

891

892

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1009
        });
1010

1011
        return selectedRowIds;
15✔
1012
    }
1013

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2344
        return columns;
288✔
2345
    }
2346

2347

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2525

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