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

IgniteUI / igniteui-angular / 13331632524

14 Feb 2025 02:51PM CUT coverage: 22.015% (-69.6%) from 91.622%
13331632524

Pull #15372

github

web-flow
Merge d52d57714 into bcb78ae0a
Pull Request #15372: chore(*): test ci passing

1990 of 15592 branches covered (12.76%)

431 of 964 new or added lines in 18 files covered. (44.71%)

19956 existing lines in 307 files now uncovered.

6452 of 29307 relevant lines covered (22.02%)

249.17 hits per line

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

0.61
/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

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

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

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

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

229

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

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

256

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

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

283

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

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

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

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

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

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

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

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

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

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

383
    public get pivotUI() {
UNCOV
384
        return this._pivotUI;
×
385
    }
386

387
    /**
388
     * @hidden @internal
389
     */
390
    @HostBinding('attr.role')
UNCOV
391
    public role = 'grid';
×
392

393

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

409
    public set superCompactMode(value) {
UNCOV
410
        this._superCompactMode = value;
×
411
    }
412

413
    /** @hidden @internal */
414
    public override get gridSize() {
UNCOV
415
        if (this.superCompactMode) {
×
UNCOV
416
            return Size.Small;
×
417
        }
UNCOV
418
        return super.gridSize;
×
419
    }
420

421

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

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

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

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

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

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

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

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

478
    /**
479
     * @hidden @internal
480
     */
481
    public override get minColumnWidth() {
UNCOV
482
        if (this.superCompactMode) {
×
UNCOV
483
            return MINIMUM_COLUMN_WIDTH_SUPER_COMPACT;
×
484
        } else {
UNCOV
485
            return MINIMUM_COLUMN_WIDTH;
×
486
        }
487
    }
488

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

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

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

507
    /**
508
     * @hidden @internal
509
     */
510
    @Input()
UNCOV
511
    public override autoGenerateExclude: string[] = [];
×
512

513
    /**
514
     * @hidden @internal
515
     */
516
    @Input()
UNCOV
517
    public override snackbarDisplayTime = 6000;
×
518

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

609
    /**
610
     * @hidden @internal
611
     */
612
    @Output()
UNCOV
613
    public override rowEditEnter = new EventEmitter<IGridEditEventArgs>();
×
614

615
    /**
616
     * @hidden @internal
617
     */
618
    @Output()
UNCOV
619
    public override rowEdit = new EventEmitter<IGridEditEventArgs>();
×
620

621
    /**
622
     * @hidden @internal
623
     */
624
    @Output()
UNCOV
625
    public override rowEditDone = new EventEmitter<IGridEditDoneEventArgs>();
×
626

627
    /**
628
     * @hidden @internal
629
     */
630
    @Output()
UNCOV
631
    public override rowEditExit = new EventEmitter<IGridEditDoneEventArgs>();
×
632

633
    /**
634
     * @hidden @internal
635
     */
636
    @Output()
UNCOV
637
    public override rowPinning = new EventEmitter<IPinRowEventArgs>();
×
638

639
    /**
640
     * @hidden @internal
641
     */
642
    @Output()
UNCOV
643
    public override rowPinned = new EventEmitter<IPinRowEventArgs>();
×
644

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

658
    /**
659
     * @hidden @internal
660
     */
UNCOV
661
    public override dragRowID = null;
×
662

663
    /**
664
    * @hidden @internal
665
    */
666
    public override get rootSummariesEnabled(): boolean {
UNCOV
667
        return false;
×
668
    }
669

670
    /**
671
     * @hidden @internal
672
     */
UNCOV
673
    public rowDimensionResizing = true;
×
674

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

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

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

709
    public set defaultExpandState(val: boolean) {
UNCOV
710
        this._defaultExpandState = val;
×
711
    }
712

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

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

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

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

736
    /**
737
     * @hidden @internal
738
     */
UNCOV
739
    public override autoGenerate = true;
×
740

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

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

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

759
    /**
760
     * @hidden @internal
761
     */
UNCOV
762
    public override moving = false;
×
763

764
    /**
765
     * @hidden @internal
766
     */
UNCOV
767
    public override toolbarExporting = new EventEmitter<IGridToolbarExportEventArgs>();
×
768

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

777

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

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

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

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

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

803
    /**
804
     * @hidden @internal
805
     */
806
    @Input({ transform: booleanAttribute })
807
    public override get allowFiltering() {
UNCOV
808
        return false;
×
809
    }
810

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

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

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

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

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

836
    /**
837
     * @hidden @internal
838
     */
839
    public override get pinnedColumns(): IgxColumnComponent[] {
UNCOV
840
        return [];
×
841
    }
842

843
    /**
844
    * @hidden @internal
845
    */
846
    public override get unpinnedColumns(): IgxColumnComponent[] {
UNCOV
847
        return super.unpinnedColumns;
×
848
    }
849

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

857
    /**
858
    * @hidden @internal
859
    */
860
    public override get unpinnedWidth() {
UNCOV
861
        return super.unpinnedWidth;
×
862
    }
863

864
    /**
865
     * @hidden @internal
866
     */
867
    public override get pinnedWidth() {
UNCOV
868
        return super.pinnedWidth;
×
869
    }
870

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

878
    public override get summaryRowHeight(): number {
UNCOV
879
        return 0;
×
880
    }
881

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

889

890

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

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

901
    /**
902
     * @hidden @internal
903
     */
904
    @WatchChanges()
905
    @Input({ transform: booleanAttribute })
906
    public override get rowEditable(): boolean {
UNCOV
907
        return;
×
908
    }
909

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

913
    /**
914
     * @hidden @internal
915
     */
916
    @Input()
917
    public override get pinning() {
UNCOV
918
        return {};
×
919
    }
920
    public override set pinning(_value) {
921
    }
922

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

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

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

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

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

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

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

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

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

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

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

1007
        });
1008

UNCOV
1009
        return selectedRowIds;
×
1010
    }
1011

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

1059
    public override navigation: IgxPivotGridNavigationService;
1060

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

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

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

1099
    /**
1100
     * @hidden @internal
1101
     */
1102
    public ngOnChanges(changes: SimpleChanges) {
UNCOV
1103
        if (changes.superCompactMode && !changes.superCompactMode.isFirstChange()) {
×
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) {
×
UNCOV
1113
        if (regenerateColumns) {
×
UNCOV
1114
            this.setupColumns();
×
1115
        }
UNCOV
1116
        this.pipeTrigger++;
×
UNCOV
1117
        this.cdr.detectChanges();
×
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() {
UNCOV
1129
        const config = this._pivotConfiguration;
×
UNCOV
1130
        if (!config) return [];
×
UNCOV
1131
        return (config.rows || []).concat((config.columns || [])).concat(config.filters || []).filter(x => x !== null && x !== undefined);
×
1132
    }
1133

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

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

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

1168
    /** @hidden */
1169
    public override featureColumnsWidth() {
UNCOV
1170
        return this.pivotRowWidths || 0;
×
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 {
UNCOV
1187
        return this.p_id;
×
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) {
UNCOV
1204
        this._data = value || [];
×
UNCOV
1205
        if (!this._init) {
×
UNCOV
1206
            if (this.autoGenerateConfig) {
×
UNCOV
1207
                this.generateConfig();
×
1208
            }
UNCOV
1209
            this.setupColumns();
×
UNCOV
1210
            this.reflow();
×
1211
        }
UNCOV
1212
        this.cdr.markForCheck();
×
UNCOV
1213
        if (this.height === null || this.height.indexOf('%') !== -1) {
×
1214
            // If the height will change based on how much data there is, recalculate sizes in igxForOf.
UNCOV
1215
            this.notifyChanges(true);
×
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 {
UNCOV
1228
        return this._data;
×
1229
    }
1230

1231
    /**
1232
     * @hidden
1233
     */
1234
    public getContext(rowData, rowIndex): any {
UNCOV
1235
        return {
×
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() {
UNCOV
1249
        return this.visibleRowDimensions.length ? this.visibleRowDimensions.reduce((accumulator, dim) => accumulator + this.rowDimensionWidthToPixels(dim), 0) :
×
1250
            this.rowDimensionWidthToPixels(this.emptyRowDimension);
1251
    }
1252

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

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

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

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

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

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

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

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

1318
    public get visibleRowDimensions() {
UNCOV
1319
        return this._visibleRowDimensions || this.rowDimensions;
×
1320
    }
1321

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

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

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

1337
    public toggleColumn(col: IgxColumnComponent) {
UNCOV
1338
        const state = this.columnGroupStates.get(col.field);
×
UNCOV
1339
        const newState = !state;
×
UNCOV
1340
        this.columnGroupStates.set(col.field, newState);
×
UNCOV
1341
        this.toggleRowGroup(col, newState);
×
UNCOV
1342
        this.reflow();
×
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[] {
UNCOV
1387
        return;
×
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() {
UNCOV
1475
        return;
×
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 {
UNCOV
1489
        return;
×
1490
    }
1491

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

1499
    /**
1500
     * @hidden @internal
1501
     */
1502
    public override get pinnedDataView(): any[] {
UNCOV
1503
        return [];
×
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 {
×
UNCOV
1546
        return 0;
×
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) {
×
UNCOV
1583
        return super.getPinnedWidth(takeHidden);
×
1584
    }
1585

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

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

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

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

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

UNCOV
1643
        super.dataRebinding(event);
×
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) {
UNCOV
1658
        if (this.getDimensionType(dimension) === PivotDimensionType.Row) {
×
UNCOV
1659
            const relatedDims: string[] = PivotUtil.flatten([dimension]).map((x: IPivotDimension) => x.memberName);
×
UNCOV
1660
            const contentCollection =  this.getContentCollection(dimension);
×
UNCOV
1661
            const content = contentCollection.filter(x => relatedDims.indexOf(x.dimension.memberName) !== -1);
×
UNCOV
1662
            const headers = content.map(x => x.headerGroups.toArray()).flat().map(x => x.header && x.header.refInstance);
×
UNCOV
1663
            if (this.pivotUI.showRowHeaders) {
×
1664
                const dimensionHeader = this.theadRow.rowDimensionHeaders.find(x => x.column.field === dimension.memberName);
×
1665
                headers.push(dimensionHeader);
×
1666
            }
UNCOV
1667
            const autoWidth = this.getLargesContentWidth(headers);
×
UNCOV
1668
            if (dimension.width === "auto") {
×
1669
                dimension.autoWidth = parseFloat(autoWidth);
×
1670
            } else {
UNCOV
1671
                dimension.width = autoWidth;
×
1672
            }
UNCOV
1673
            this.pipeTrigger++;
×
UNCOV
1674
            this.cdr.detectChanges();
×
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) {
UNCOV
1691
        const targetCollection = this.getDimensionsByType(targetCollectionType);
×
UNCOV
1692
        if (index !== undefined) {
×
UNCOV
1693
            targetCollection.splice(index, 0, dimension);
×
1694
        } else {
UNCOV
1695
            targetCollection.push(dimension);
×
1696
        }
UNCOV
1697
        if (targetCollectionType === PivotDimensionType.Column) {
×
UNCOV
1698
            this.setupColumns();
×
1699
        }
UNCOV
1700
        this.pipeTrigger++;
×
UNCOV
1701
        this.dimensionsChange.emit({ dimensions: targetCollection, dimensionCollectionType: targetCollectionType });
×
UNCOV
1702
        if (targetCollectionType === PivotDimensionType.Filter) {
×
UNCOV
1703
            this.dimensionDataColumns = this.generateDimensionColumns();
×
UNCOV
1704
            this.reflow();
×
1705
        }
UNCOV
1706
        this.pivotConfigurationChange.emit({ pivotConfiguration: this.pivotConfiguration });
×
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) {
UNCOV
1722
        const prevCollectionType = this.getDimensionType(dimension);
×
UNCOV
1723
        if (prevCollectionType === null) return;
×
1724
        // remove from old collection
UNCOV
1725
        this._removeDimensionInternal(dimension);
×
1726
        // add to target
UNCOV
1727
        this.insertDimensionAt(dimension, targetCollectionType, index);
×
1728

UNCOV
1729
        if (prevCollectionType === PivotDimensionType.Column) {
×
UNCOV
1730
            this.setupColumns();
×
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) {
UNCOV
1746
        const prevCollectionType = this.getDimensionType(dimension);
×
UNCOV
1747
        this._removeDimensionInternal(dimension);
×
UNCOV
1748
        if (prevCollectionType === PivotDimensionType.Column) {
×
UNCOV
1749
            this.setupColumns();
×
1750
        }
UNCOV
1751
        if (prevCollectionType === PivotDimensionType.Filter) {
×
UNCOV
1752
            this.reflow();
×
1753
        }
UNCOV
1754
        this.pipeTrigger++;
×
UNCOV
1755
        this.cdr.detectChanges();
×
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) {
UNCOV
1769
        const dimType = this.getDimensionType(dimension);
×
UNCOV
1770
        if (dimType === null) return;
×
UNCOV
1771
        const collection = this.getDimensionsByType(dimType);
×
UNCOV
1772
        dimension.enabled = !dimension.enabled;
×
UNCOV
1773
        if (dimType === PivotDimensionType.Column) {
×
UNCOV
1774
            this.setupColumns();
×
1775
        }
UNCOV
1776
        if (!dimension.enabled && dimension.filter) {
×
UNCOV
1777
            this.filteringService.clearFilter(dimension.memberName);
×
1778
        }
UNCOV
1779
        this.pipeTrigger++;
×
UNCOV
1780
        this.dimensionsChange.emit({ dimensions: collection, dimensionCollectionType: dimType });
×
UNCOV
1781
        this.cdr.detectChanges();
×
UNCOV
1782
        if (dimType === PivotDimensionType.Filter) {
×
UNCOV
1783
            this.reflow();
×
1784
        }
UNCOV
1785
        this.pivotConfigurationChange.emit({ pivotConfiguration: this.pivotConfiguration });
×
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) {
UNCOV
1800
        if (!this.pivotConfiguration.values) {
×
UNCOV
1801
            this.pivotConfiguration.values = [];
×
1802
        }
UNCOV
1803
        const values = this.pivotConfiguration.values;
×
UNCOV
1804
        if (index !== undefined) {
×
UNCOV
1805
            values.splice(index, 0, value);
×
1806
        } else {
UNCOV
1807
            values.push(value);
×
1808
        }
UNCOV
1809
        this.setupColumns();
×
UNCOV
1810
        this.pipeTrigger++;
×
UNCOV
1811
        this.cdr.detectChanges();
×
UNCOV
1812
        this.valuesChange.emit({ values });
×
UNCOV
1813
        this.pivotConfigurationChange.emit({ pivotConfiguration: this.pivotConfiguration });
×
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) {
UNCOV
1828
        if (this.pivotConfiguration.values.indexOf(value) === -1) return;
×
1829
        // remove from old index
UNCOV
1830
        this.removeValue(value);
×
1831
        // add to new
UNCOV
1832
        this.insertValueAt(value, index);
×
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,) {
UNCOV
1847
        const values = this.pivotConfiguration.values;
×
UNCOV
1848
        const currentIndex = values.indexOf(value);
×
UNCOV
1849
        if (currentIndex !== -1) {
×
UNCOV
1850
            values.splice(currentIndex, 1);
×
UNCOV
1851
            this.setupColumns();
×
UNCOV
1852
            this.pipeTrigger++;
×
UNCOV
1853
            this.valuesChange.emit({ values });
×
UNCOV
1854
            this.pivotConfigurationChange.emit({ pivotConfiguration: this.pivotConfiguration });
×
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) {
UNCOV
1869
        if (this.pivotConfiguration.values.indexOf(value) === -1) return;
×
UNCOV
1870
        value.enabled = !value.enabled;
×
UNCOV
1871
        this.setupColumns();
×
UNCOV
1872
        this.pipeTrigger++;
×
UNCOV
1873
        this.valuesChange.emit({ values: this.pivotConfiguration.values });
×
UNCOV
1874
        this.reflow();
×
UNCOV
1875
        this.pivotConfigurationChange.emit({ pivotConfiguration: this.pivotConfiguration });
×
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) {
UNCOV
1887
        const dimensionType = this.getDimensionType(dimension);
×
UNCOV
1888
        dimension.sortDirection = sortDirection;
×
1889
        // apply same sort direction to children.
UNCOV
1890
        let dim = dimension;
×
UNCOV
1891
        if (this.pivotUI.rowLayout === PivotRowLayoutType.Vertical) {
×
UNCOV
1892
            while (dim.childLevel) {
×
UNCOV
1893
                dim.childLevel.sortDirection = dimension.sortDirection;
×
UNCOV
1894
                dim = dim.childLevel;
×
1895
            }
1896
        }
1897

UNCOV
1898
        this.pipeTrigger++;
×
UNCOV
1899
        this.dimensionsSortingExpressionsChange.emit(this.dimensionsSortingExpressions);
×
UNCOV
1900
        if (dimensionType === PivotDimensionType.Column) {
×
UNCOV
1901
            this.setupColumns();
×
1902
        }
UNCOV
1903
        this.cdr.detectChanges();
×
UNCOV
1904
        this.pivotConfigurationChange.emit({ pivotConfiguration: this.pivotConfiguration });
×
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) {
UNCOV
1921
        this.filteringService.filter(dimension.memberName, value, conditionOrExpressionTree);
×
UNCOV
1922
        const dimensionType = this.getDimensionType(dimension);
×
UNCOV
1923
        if (dimensionType === PivotDimensionType.Column) {
×
UNCOV
1924
            this.setupColumns();
×
1925
        }
UNCOV
1926
        this.cdr.detectChanges();
×
1927
    }
1928

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

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

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

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

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

1996
    protected getDimensionType(dimension: IPivotDimension): PivotDimensionType {
UNCOV
1997
        return PivotUtil.flatten(this.pivotConfiguration.rows).indexOf(dimension) !== -1 ? PivotDimensionType.Row :
×
1998
            PivotUtil.flatten(this.pivotConfiguration.columns).indexOf(dimension) !== -1 ? PivotDimensionType.Column :
×
1999
                (!!this.pivotConfiguration.filters && PivotUtil.flatten(this.pivotConfiguration.filters).indexOf(dimension) !== -1) ?
×
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 {
UNCOV
2009
        const largest = new Map<number, number>();
×
UNCOV
2010
        if (contents.length > 0) {
×
UNCOV
2011
            const cellsContentWidths = [];
×
UNCOV
2012
            contents.forEach((elem) => {
×
UNCOV
2013
                elem instanceof IgxPivotRowHeaderGroupComponent ?
×
2014
                    cellsContentWidths.push(this.getPivotRowHeaderContentWidth(elem)) :
2015
                    cellsContentWidths.push(this.getHeaderCellWidth(elem.nativeElement).width);
2016
            });
UNCOV
2017
            const index = cellsContentWidths.indexOf(Math.max(...cellsContentWidths));
×
UNCOV
2018
            const cellStyle = this.document.defaultView.getComputedStyle(contents[index].nativeElement);
×
UNCOV
2019
            const cellPadding = parseFloat(cellStyle.paddingLeft) + parseFloat(cellStyle.paddingRight) +
×
2020
                parseFloat(cellStyle.borderLeftWidth) + parseFloat(cellStyle.borderRightWidth);
UNCOV
2021
            largest.set(Math.max(...cellsContentWidths), cellPadding);
×
2022
        }
UNCOV
2023
        const largestCell = Math.max(...Array.from(largest.keys()));
×
UNCOV
2024
        const width = Math.ceil(largestCell + largest.get(largestCell));
×
2025

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

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

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

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

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

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

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

UNCOV
2075
        return super.activeDescendant;
×
2076
    }
2077

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

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

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

2116
    protected override horizontalScrollHandler(event) {
UNCOV
2117
        const scrollLeft = event.target.scrollLeft;
×
UNCOV
2118
        this.theadRow.headerContainers.forEach(headerForOf => {
×
UNCOV
2119
            headerForOf.onHScroll(scrollLeft);
×
2120
        });
UNCOV
2121
        super.horizontalScrollHandler(event);
×
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() {
UNCOV
2135
        let columns = [];
×
UNCOV
2136
        const data = this.gridAPI.filterDataByExpressions(this.filteringExpressionsTree);
×
UNCOV
2137
        this.dimensionDataColumns = this.generateDimensionColumns();
×
UNCOV
2138
        const flattenedColumnsWithSorting = PivotUtil.flatten(this.columnDimensions).filter(dim => dim.sortDirection);
×
UNCOV
2139
        const expressions = flattenedColumnsWithSorting.length > 0 ? PivotSortUtil.generateDimensionSortingExpressions(flattenedColumnsWithSorting) : [];
×
UNCOV
2140
        let sortedData = data;
×
UNCOV
2141
        if (expressions.length > 0) {
×
UNCOV
2142
            sortedData = DataUtil.sort(cloneArray(data), expressions, this.sortStrategy, this);
×
2143
        }
2144
        let fieldsMap;
UNCOV
2145
        if (this.pivotConfiguration.columnStrategy && this.pivotConfiguration.columnStrategy instanceof NoopPivotDimensionsStrategy) {
×
UNCOV
2146
            const fields = this.generateDataFields(sortedData);
×
UNCOV
2147
            if (fields.length === 0) return;
×
UNCOV
2148
            const rowFields = PivotUtil.flatten(this.pivotConfiguration.rows).map(x => x.memberName);
×
UNCOV
2149
            const keyFields = Object.values(this.pivotKeys);
×
UNCOV
2150
            const filteredFields = fields.filter(x => rowFields.indexOf(x) === -1 && keyFields.indexOf(x) === -1 &&
×
2151
                x.indexOf(this.pivotKeys.rowDimensionSeparator + this.pivotKeys.level) === -1 &&
2152
                x.indexOf(this.pivotKeys.rowDimensionSeparator + this.pivotKeys.records) === -1);
UNCOV
2153
            fieldsMap = this.generateFromData(filteredFields);
×
2154
        } else {
UNCOV
2155
            fieldsMap = PivotUtil.getFieldsHierarchy(
×
2156
                sortedData,
2157
                this.columnDimensions,
2158
                PivotDimensionType.Column,
2159
                this.pivotKeys,
2160
                this.pivotValueCloneStrategy
2161
            );
2162
        }
UNCOV
2163
        columns = this.generateColumnHierarchy(fieldsMap, sortedData);
×
UNCOV
2164
        this._autoGeneratedCols = columns;
×
2165
        // reset expansion states if any are stored.
UNCOV
2166
        this.columnGroupStates.forEach((value, key) => {
×
UNCOV
2167
            if (value) {
×
UNCOV
2168
                const primaryColumn = columns.find(x => x.field === key && x.headerTemplate === this.headerTemplate);
×
UNCOV
2169
                const groupSummaryColumn = columns.find(x => x.field === key && x.headerTemplate !== this.headerTemplate);
×
UNCOV
2170
                this.toggleRowGroup(primaryColumn, value);
×
UNCOV
2171
                if (groupSummaryColumn) {
×
UNCOV
2172
                    groupSummaryColumn.headerTemplate = this.headerTemplate;
×
2173
                }
2174
            }
2175
        });
2176

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

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

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

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

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

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

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

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

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

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

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

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

UNCOV
2344
        return columns;
×
2345
    }
2346

2347

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

UNCOV
2351
        const data = this.data;
×
UNCOV
2352
        const fields = this.generateDataFields(data);
×
UNCOV
2353
        const columnDimensions: IPivotDimension[] = [];
×
UNCOV
2354
        const rowDimensions: IPivotDimension[] = [];
×
UNCOV
2355
        const values: IPivotValue[] = [];
×
UNCOV
2356
        let isFirstDate = true;
×
UNCOV
2357
        fields.forEach((field) => {
×
UNCOV
2358
            const dataType = this.resolveDataTypes(data[0][field]);
×
UNCOV
2359
            switch (dataType) {
×
2360
                case "number":
2361
                    {
UNCOV
2362
                        const value: IPivotValue = {
×
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
                        };
UNCOV
2373
                        values.push(value);
×
UNCOV
2374
                        break;
×
2375
                }
2376
            case "date":
2377
            {
UNCOV
2378
                const dimension: IPivotDimension = new IgxPivotDateDimension(
×
2379
                    {
2380
                        memberName: field,
2381
                        enabled: isFirstDate,
2382
                        dataType: dataType
2383
                    }
2384
                )
UNCOV
2385
                rowDimensions.push(dimension);
×
UNCOV
2386
                isFirstDate = false;
×
UNCOV
2387
                break;
×
2388
            }
2389
                default: {
UNCOV
2390
                    const dimension: IPivotDimension = {
×
2391
                        memberName: field,
2392
                        enabled: false,
2393
                        dataType: dataType
2394
                    };
UNCOV
2395
                    columnDimensions.push(dimension);
×
UNCOV
2396
                    break;
×
2397
                }
2398
            }
2399
        });
UNCOV
2400
        const config: IPivotConfiguration = {
×
2401
            columns: columnDimensions,
2402
            rows: rowDimensions,
2403
            values: values
2404
        };
UNCOV
2405
        this.pivotConfiguration = config;
×
2406
    }
2407

2408
    protected createColumnForDimension(value: any, data: any, parent: ColumnType, isGroup: boolean) {
UNCOV
2409
        const key = value.value;
×
UNCOV
2410
        const ref = isGroup ?
×
2411
            createComponent(IgxColumnGroupComponent, { environmentInjector: this.envInjector, elementInjector: this.injector }) :
2412
            createComponent(IgxColumnComponent, { environmentInjector: this.envInjector, elementInjector: this.injector });
UNCOV
2413
        ref.instance.header = parent != null ? key.split(parent.header + this.pivotKeys.columnDimensionSeparator)[1] : key;
×
UNCOV
2414
        ref.instance.field = key;
×
UNCOV
2415
        ref.instance.parent = parent;
×
UNCOV
2416
        if (value.dimension.width) {
×
2417
            ref.instance.width = value.dimension.width;
×
2418
        }
UNCOV
2419
        const valueDefinition = this.values[0];
×
UNCOV
2420
        ref.instance.dataType = valueDefinition?.dataType || this.resolveDataTypes(data[0][valueDefinition?.member]);
×
UNCOV
2421
        ref.instance.formatter = valueDefinition?.formatter;
×
UNCOV
2422
        ref.instance.sortable = true;
×
UNCOV
2423
        ref.changeDetectorRef.detectChanges();
×
UNCOV
2424
        return ref.instance;
×
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) {
UNCOV
2435
        const cols = [];
×
UNCOV
2436
        const count = this.values.length;
×
UNCOV
2437
        const childWidth = parseInt(parentWidth, 10) / count;
×
UNCOV
2438
        const isPercent = parentWidth && parentWidth.indexOf('%') !== -1;
×
UNCOV
2439
        const isAuto = parentWidth && parentWidth.indexOf('auto') !== -1;
×
UNCOV
2440
        this.values.forEach(val => {
×
UNCOV
2441
            const ref = createComponent(IgxColumnComponent, { environmentInjector: this.envInjector, elementInjector: this.injector });
×
UNCOV
2442
            ref.instance.header = val.displayName || val.member;
×
UNCOV
2443
            ref.instance.field = parent.field + this.pivotKeys.columnDimensionSeparator + val.member;
×
UNCOV
2444
            ref.instance.parent = parent;
×
UNCOV
2445
            if (parentWidth) {
×
2446
                ref.instance.width = isAuto ? 'auto' : isPercent ? childWidth + '%' : childWidth + 'px';
×
2447
            }
UNCOV
2448
            ref.instance.hidden = hidden;
×
UNCOV
2449
            ref.instance.sortable = this._sortableColumns;
×
UNCOV
2450
            ref.instance.dataType = val.dataType || this.resolveDataTypes(data[0][val.member]);
×
UNCOV
2451
            ref.instance.formatter = val.formatter;
×
UNCOV
2452
            ref.changeDetectorRef.detectChanges();
×
UNCOV
2453
            cols.push(ref.instance);
×
2454
        });
UNCOV
2455
        return cols;
×
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> {
UNCOV
2479
        const allEnabledDimensions = this.rowDimensions.concat(this.columnDimensions);
×
UNCOV
2480
        if (allEnabledDimensions.length === 0 && this.values.length === 0) {
×
2481
            // no enabled values and dimensions
UNCOV
2482
            return this.emptyPivotGridTemplate || this.defaultEmptyPivotGridTemplate;
×
2483
        }
UNCOV
2484
        return super.template;
×
2485
    }
2486

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

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

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

2508
    protected override updateDefaultRowHeight() {
UNCOV
2509
        super.updateDefaultRowHeight();
×
UNCOV
2510
        if (this.hasHorizontalLayout) {
×
2511
            // Trigger pipes to recalc heights for the horizontal layout mrl rows.
UNCOV
2512
            this.regroupTrigger++;
×
2513
        }
2514
    }
2515
}
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