Skip to content

Commit 5993c89

Browse files
authored
Perf. improvements with activation and cell merge. (#16251)
1 parent 8ef93bd commit 5993c89

File tree

10 files changed

+101
-18
lines changed

10 files changed

+101
-18
lines changed

projects/igniteui-angular/src/lib/data-operations/merge-strategy.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { GridType } from '../grids/common/grid.interface';
77
export interface IMergeByResult {
88
rowSpan: number;
99
root?: any;
10+
childRecords?: any[];
1011
}
1112

1213
/**
@@ -75,10 +76,11 @@ export class DefaultMergeStrategy implements IGridMergeStrategy {
7576
continue;
7677
}
7778
const recToUpdateData = recData ?? { recordRef: grid.isGhostRecord(rec) ? rec.recordRef : rec, cellMergeMeta: new Map<string, IMergeByResult>(), ghostRecord: rec.ghostRecord };
78-
recToUpdateData.cellMergeMeta.set(field, { rowSpan: 1 });
79+
recToUpdateData.cellMergeMeta.set(field, { rowSpan: 1, childRecords: [] });
7980
if (prev && comparer.call(this, prev.recordRef, recToUpdateData.recordRef, field, isDate, isTime) && prev.ghostRecord === recToUpdateData.ghostRecord) {
8081
const root = prev.cellMergeMeta.get(field)?.root ?? prev;
8182
root.cellMergeMeta.get(field).rowSpan += 1;
83+
root.cellMergeMeta.get(field).childRecords.push(recToUpdateData);
8284
recToUpdateData.cellMergeMeta.get(field).root = root;
8385
}
8486
prev = recToUpdateData;

projects/igniteui-angular/src/lib/grids/grid/grid.component.html

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@
6969
| gridRowPinning:id:true:pipeTrigger
7070
| gridFiltering:filteringExpressionsTree:filterStrategy:advancedFilteringExpressionsTree:id:pipeTrigger:filteringPipeTrigger:true
7171
| gridSort:sortingExpressions:groupingExpressions:sortStrategy:id:pipeTrigger:true
72-
| gridCellMerge:columnsToMerge:cellMergeMode:mergeStrategy:activeRowIndexes:true:pipeTrigger; as pinnedData) {
72+
| gridCellMerge:columnsToMerge:cellMergeMode:mergeStrategy:pipeTrigger
73+
| gridUnmergeActive:columnsToMerge:activeRowIndexes:true:pipeTrigger; as pinnedData) {
7374
@if (pinnedData.length > 0) {
7475
<div #pinContainer
7576
[ngClass]="{
@@ -96,7 +97,8 @@
9697
| gridDetails:hasDetails:expansionStates:pipeTrigger
9798
| gridAddRow:false:pipeTrigger
9899
| gridRowPinning:id:false:pipeTrigger
99-
| gridCellMerge:columnsToMerge:cellMergeMode:mergeStrategy:activeRowIndexes:false:pipeTrigger"
100+
| gridCellMerge:columnsToMerge:cellMergeMode:mergeStrategy:pipeTrigger
101+
| gridUnmergeActive:columnsToMerge:activeRowIndexes:false:pipeTrigger"
100102
let-rowIndex="index" [igxForScrollOrientation]="'vertical'" [igxForScrollContainer]="verticalScroll"
101103
[igxForContainerSize]="calcHeight"
102104
[igxForItemSize]="hasColumnLayouts ? rowHeight * multiRowLayoutRowSize + 1 : renderedRowHeight"

projects/igniteui-angular/src/lib/grids/grid/grid.component.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import { IGridGroupingStrategy } from '../common/strategy';
3434
import { IgxGridValidationService } from './grid-validation.service';
3535
import { IgxGridDetailsPipe } from './grid.details.pipe';
3636
import { IgxGridSummaryPipe } from './grid.summary.pipe';
37-
import { IgxGridGroupingPipe, IgxGridPagingPipe, IgxGridSortingPipe, IgxGridFilteringPipe, IgxGridCellMergePipe } from './grid.pipes';
37+
import { IgxGridGroupingPipe, IgxGridPagingPipe, IgxGridSortingPipe, IgxGridFilteringPipe, IgxGridCellMergePipe, IgxGridUnmergeActivePipe } from './grid.pipes';
3838
import { IgxSummaryDataPipe } from '../summaries/grid-root-summary.pipe';
3939
import { IgxGridTransactionPipe, IgxHasVisibleColumnsPipe, IgxGridRowPinningPipe, IgxGridAddRowPipe, IgxGridRowClassesPipe, IgxGridRowStylesPipe, IgxStringReplacePipe } from '../common/pipes';
4040
import { IgxGridColumnResizerComponent } from '../resizing/resizer.component';
@@ -154,6 +154,7 @@ export interface IGroupingDoneEventArgs extends IBaseEventArgs {
154154
IgxGridDetailsPipe,
155155
IgxStringReplacePipe,
156156
IgxGridCellMergePipe,
157+
IgxGridUnmergeActivePipe,
157158
IgxScrollInertiaDirective
158159
],
159160
schemas: [CUSTOM_ELEMENTS_SCHEMA]

projects/igniteui-angular/src/lib/grids/grid/grid.pipes.ts

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,14 +86,76 @@ export class IgxGridCellMergePipe implements PipeTransform {
8686

8787
constructor(@Inject(IGX_GRID_BASE) private grid: GridType) { }
8888

89-
public transform(collection: any, colsToMerge: ColumnType[], mergeMode: GridCellMergeMode, mergeStrategy: IGridMergeStrategy, activeRowIndexes: number[], pinned: boolean, _pipeTrigger: number) {
89+
public transform(collection: any, colsToMerge: ColumnType[], mergeMode: GridCellMergeMode, mergeStrategy: IGridMergeStrategy, _pipeTrigger: number) {
90+
if (colsToMerge.length === 0) {
91+
return collection;
92+
}
93+
const result = DataUtil.merge(collection, colsToMerge, mergeStrategy, [], this.grid);
94+
return result;
95+
}
96+
}
97+
98+
@Pipe({
99+
name: 'gridUnmergeActive',
100+
standalone: true
101+
})
102+
export class IgxGridUnmergeActivePipe implements PipeTransform {
103+
104+
constructor(@Inject(IGX_GRID_BASE) private grid: GridType) { }
105+
106+
public transform(collection: any, colsToMerge: ColumnType[], activeRowIndexes: number[], pinned: boolean, _pipeTrigger: number) {
90107
if (colsToMerge.length === 0) {
91108
return collection;
92109
}
93110
if (this.grid.hasPinnedRecords && !pinned && this.grid.pinning.rows !== RowPinningPosition.Bottom) {
94111
activeRowIndexes = activeRowIndexes.map(x => x - this.grid.pinnedRecordsCount);
95112
}
96-
const result = DataUtil.merge(cloneArray(collection), colsToMerge, mergeStrategy, activeRowIndexes, this.grid);
113+
activeRowIndexes = Array.from(new Set(activeRowIndexes)).filter(x => !isNaN(x));
114+
const rootsToUpdate = [];
115+
activeRowIndexes.forEach(index => {
116+
const target = collection[index];
117+
if (target) {
118+
colsToMerge.forEach(col => {
119+
const colMeta = target.cellMergeMeta.get(col.field);
120+
const root = colMeta.root || (colMeta.rowSpan > 1 ? target : null);
121+
if (root) {
122+
rootsToUpdate.push(root);
123+
}
124+
});
125+
}
126+
});
127+
const uniqueRoots = Array.from(new Set(rootsToUpdate));
128+
if (uniqueRoots.length === 0) {
129+
// if nothing to update, return
130+
return collection;
131+
}
132+
let result = cloneArray(collection) as any;
133+
uniqueRoots.forEach(x => {
134+
const index = result.indexOf(x);
135+
const colKeys = [...x.cellMergeMeta.keys()];
136+
const cols = colsToMerge.filter(col => colKeys.indexOf(col.field) !== -1);
137+
let res = [];
138+
for (const col of cols) {
139+
140+
let childData = x.cellMergeMeta.get(col.field).childRecords;
141+
const childRecs = childData.map(rec => rec.recordRef);
142+
const isDate = col?.dataType === 'date' || col?.dataType === 'dateTime';
143+
const isTime = col?.dataType === 'time' || col?.dataType === 'dateTime';
144+
res = this.grid.mergeStrategy.merge(
145+
[x.recordRef, ...childRecs],
146+
col.field,
147+
col.mergingComparer,
148+
res,
149+
activeRowIndexes.map(ri => ri - index),
150+
isDate,
151+
isTime,
152+
this.grid);
153+
154+
}
155+
result = result.slice(0, index).concat(res, result.slice(index + res.length));
156+
});
157+
158+
97159
return result;
98160
}
99161
}

projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.html

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@
5151
| gridRowPinning:id:true:pipeTrigger
5252
| gridFiltering:filteringExpressionsTree:filterStrategy:advancedFilteringExpressionsTree:id:pipeTrigger:filteringPipeTrigger:true
5353
| gridSort:sortingExpressions:[]:sortStrategy:id:pipeTrigger:true
54-
| gridCellMerge:columnsToMerge:cellMergeMode:mergeStrategy:activeRowIndexes:true:pipeTrigger; as pinnedData
54+
| gridCellMerge:columnsToMerge:cellMergeMode:mergeStrategy:pipeTrigger
55+
| gridUnmergeActive:columnsToMerge:activeRowIndexes:true:pipeTrigger; as pinnedData
5556
) {
5657
@if (pinnedData.length > 0) {
5758
<div #pinContainer class="igx-grid__tr--pinned"
@@ -76,7 +77,8 @@
7677
| gridHierarchical:expansionStates:id:primaryKey:childLayoutKeys:pipeTrigger
7778
| gridAddRow:false:pipeTrigger
7879
| gridRowPinning:id:false:pipeTrigger
79-
| gridCellMerge:columnsToMerge:cellMergeMode:mergeStrategy:activeRowIndexes:false:pipeTrigger"
80+
| gridCellMerge:columnsToMerge:cellMergeMode:mergeStrategy:pipeTrigger
81+
| gridUnmergeActive:columnsToMerge:activeRowIndexes:false:pipeTrigger"
8082
[igxForScrollOrientation]="'vertical'" [igxForScrollContainer]="verticalScroll"
8183
[igxForContainerSize]="calcHeight" [igxForItemSize]="renderedRowHeight" [igxForTrackBy]="trackChanges"
8284
#verticalScrollContainer (chunkPreload)="dataLoading($event)" (dataChanging)="dataRebinding($event)" (dataChanged)="dataRebound($event)">

projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ import { IgxGridValidationService } from '../grid/grid-validation.service';
5050
import { IgxGridHierarchicalPipe, IgxGridHierarchicalPagingPipe } from './hierarchical-grid.pipes';
5151
import { IgxSummaryDataPipe } from '../summaries/grid-root-summary.pipe';
5252
import { IgxGridTransactionPipe, IgxHasVisibleColumnsPipe, IgxGridRowPinningPipe, IgxGridAddRowPipe, IgxGridRowClassesPipe, IgxGridRowStylesPipe, IgxStringReplacePipe } from '../common/pipes';
53-
import { IgxGridSortingPipe, IgxGridFilteringPipe, IgxGridCellMergePipe } from '../grid/grid.pipes';
53+
import { IgxGridSortingPipe, IgxGridFilteringPipe, IgxGridCellMergePipe, IgxGridUnmergeActivePipe } from '../grid/grid.pipes';
5454
import { IgxGridColumnResizerComponent } from '../resizing/resizer.component';
5555
import { IgxRowEditTabStopDirective } from '../grid.rowEdit.directive';
5656
import { IgxIconComponent } from '../../icon/icon.component';
@@ -353,7 +353,8 @@ export class IgxChildGridRowComponent implements AfterViewInit, OnInit {
353353
IgxGridHierarchicalPagingPipe,
354354
IgxStringReplacePipe,
355355
IgxGridCellMergePipe,
356-
IgxScrollInertiaDirective
356+
IgxScrollInertiaDirective,
357+
IgxGridUnmergeActivePipe
357358
],
358359
schemas: [CUSTOM_ELEMENTS_SCHEMA]
359360
})

projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid.component.html

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@
5353
| gridRowPinning:id:true:pipeTrigger
5454
| treeGridFiltering:filteringExpressionsTree:filterStrategy:advancedFilteringExpressionsTree:pipeTrigger:filteringPipeTrigger:true
5555
| treeGridSorting:sortingExpressions:treeGroupArea?.expressions:sortStrategy:pipeTrigger:true
56-
| gridCellMerge:columnsToMerge:cellMergeMode:mergeStrategy:activeRowIndexes:true:pipeTrigger; as pinnedData
56+
| gridCellMerge:columnsToMerge:cellMergeMode:mergeStrategy:pipeTrigger
57+
| gridUnmergeActive:columnsToMerge:activeRowIndexes:true:pipeTrigger; as pinnedData
5758
) {
5859
@if (pinnedData.length > 0) {
5960
<div #pinContainer
@@ -82,7 +83,8 @@
8283
| treeGridSummary:hasSummarizedColumns:summaryCalculationMode:summaryPosition:showSummaryOnCollapse:pipeTrigger:summaryPipeTrigger
8384
| treeGridAddRow:false:pipeTrigger
8485
| gridRowPinning:id:false:pipeTrigger
85-
| gridCellMerge:columnsToMerge:cellMergeMode:mergeStrategy:activeRowIndexes:false:pipeTrigger"
86+
| gridCellMerge:columnsToMerge:cellMergeMode:mergeStrategy:pipeTrigger
87+
| gridUnmergeActive:columnsToMerge:activeRowIndexes:false:pipeTrigger"
8688
let-rowIndex="index" [igxForScrollOrientation]="'vertical'" [igxForScrollContainer]='verticalScroll'
8789
[igxForContainerSize]='calcHeight' [igxForItemSize]="renderedRowHeight" #verticalScrollContainer
8890
(dataChanging)="dataRebinding($event)" (dataChanged)="dataRebound($event)">

projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid.component.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ import { IgxGridDragSelectDirective } from '../selection/drag-select.directive';
8282
import { IgxGridBodyDirective } from '../grid.common';
8383
import { IgxGridHeaderRowComponent } from '../headers/grid-header-row.component';
8484
import { IgxTextHighlightService } from '../../directives/text-highlight/text-highlight.service';
85-
import { IgxGridCellMergePipe } from '../grid/grid.pipes';
85+
import { IgxGridCellMergePipe, IgxGridUnmergeActivePipe } from '../grid/grid.pipes';
8686
import { DefaultTreeGridMergeStrategy, IGridMergeStrategy } from '../../data-operations/merge-strategy';
8787
import { IgxScrollInertiaDirective } from '../../directives/scroll-inertia/scroll_inertia.directive';
8888

@@ -173,7 +173,8 @@ let NEXT_ID = 0;
173173
IgxTreeGridAddRowPipe,
174174
IgxStringReplacePipe,
175175
IgxGridCellMergePipe,
176-
IgxScrollInertiaDirective
176+
IgxScrollInertiaDirective,
177+
IgxGridUnmergeActivePipe
177178
],
178179
schemas: [CUSTOM_ELEMENTS_SCHEMA]
179180
})

src/app/grid-cellMerging/grid-cellMerging.component.html

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ <h4 class="sample-title">Grid with cell merge</h4>
5050
Value: {{val}},Index: {{cell.row.index}}
5151
</ng-template>
5252
</igx-column>
53-
<igx-column field="ShipCountry" header="Ship Country" width="200px" [merge]="true" sortable="true">
53+
<igx-column field="ShipCountry" header="Ship Country" [merge]="true" width="200px" sortable="true">
5454
</igx-column>
5555
<igx-column field="OrderDate" header="Order Date" width="200px" [merge]="true" [groupable]="true" [dataType]="'date'" sortable="true">
5656
</igx-column>
@@ -70,8 +70,7 @@ <h4 class="sample-title">Grid with cell merge</h4>
7070
</igx-column>
7171
<igx-column field="Quantity" header="Quantity" width="150px" dataType="number">
7272
</igx-column>
73-
<igx-paginator [perPage]="20">
74-
</igx-paginator>
73+
7574
<igx-action-strip>
7675
<igx-grid-pinning-actions></igx-grid-pinning-actions>
7776
</igx-action-strip>

src/app/grid-cellMerging/grid-cellMerging.component.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ import { INVOICE_DATA } from '../shared/invoiceData';
3838
FormsModule,
3939
IgxColumnComponent,
4040
IgxGridComponent,
41-
IgxPaginatorComponent,
41+
// IgxPaginatorComponent,
4242
IgxActionStripComponent,
4343
IgxGridPinningActionsComponent,
4444
IgxGridToolbarComponent,
@@ -66,6 +66,17 @@ export class GridCellMergingComponent {
6666
@ViewChild('grid1', { static: true }) public grid: IgxGridComponent;
6767
public data = INVOICE_DATA;
6868

69+
constructor(){
70+
const allData = INVOICE_DATA
71+
const length = INVOICE_DATA.length;
72+
for (let i = 1; i <= 600_000; i++) {
73+
const rnd = Math.floor(Math.random() * length);
74+
allData.push(Object.assign({}, INVOICE_DATA[rnd]));
75+
}
76+
77+
this.data = allData;
78+
}
79+
6980
public toggleStrategy() {
7081
if (this.treeGridMergeStrategy instanceof ByLevelTreeGridMergeStrategy) {
7182
this.treeGridMergeStrategy = new DefaultTreeGridMergeStrategy();

0 commit comments

Comments
 (0)