Skip to content

Commit 1dca5eb

Browse files
MKirovaMKirova
authored andcommitted
Move column pipe before flattening so that hierarchical group data can be more easily sorted in their own hierarchy after aggregates are populated. Make all columns sortable by default.
1 parent cd7687f commit 1dca5eb

File tree

5 files changed

+122
-77
lines changed

5 files changed

+122
-77
lines changed

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

Lines changed: 83 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -30,50 +30,50 @@ export class PivotRowDimensionsStrategy implements IPivotDimensionStrategy {
3030
}
3131

3232
public process(
33-
collection: any,
34-
rows: IPivotDimension[],
35-
values?: IPivotValue[],
36-
pivotKeys: IPivotKeys =
37-
{ aggregations: 'aggregations', records: 'records', children: 'children', level: 'level'}
38-
): any[] {
39-
let hierarchies;
40-
let data;
41-
const prevRowDims = [];
42-
let prevDim;
43-
for (const row of rows) {
44-
if (!data) {
45-
// build hierarchies - groups and subgroups
46-
hierarchies = PivotUtil.getFieldsHierarchy(collection, [row], PivotDimensionType.Row, pivotKeys);
47-
// generate flat data from the hierarchies
48-
data = PivotUtil.processHierarchy(hierarchies, collection[0] ?? [], pivotKeys, 0, true);
49-
prevRowDims.push(row);
50-
prevDim = row;
51-
} else {
52-
const newData = [...data];
53-
for (let i = 0; i < newData.length; i++) {
54-
const currData = newData[i][prevDim.memberName + '_' + pivotKeys.records];
55-
const hierarchyFields = PivotUtil
56-
.getFieldsHierarchy(currData, [row], PivotDimensionType.Row, pivotKeys);
57-
const siblingData = PivotUtil
58-
.processHierarchy(hierarchyFields, newData[i] ?? [], pivotKeys, 0);
59-
PivotUtil.processSiblingProperties(newData[i], siblingData, pivotKeys);
60-
61-
PivotUtil.processSubGroups(row, prevRowDims.slice(0), siblingData, pivotKeys);
62-
if (PivotUtil.getDimensionDepth(prevDim) > PivotUtil.getDimensionDepth(row)) {
63-
newData[i][row.memberName + '_' + pivotKeys.records] = siblingData;
64-
} else {
65-
newData.splice(i , 1, ...siblingData);
66-
}
67-
i += siblingData.length - 1;
33+
collection: any,
34+
rows: IPivotDimension[],
35+
values?: IPivotValue[],
36+
pivotKeys: IPivotKeys =
37+
{ aggregations: 'aggregations', records: 'records', children: 'children', level: 'level' }
38+
): any[] {
39+
let hierarchies;
40+
let data;
41+
const prevRowDims = [];
42+
let prevDim;
43+
for (const row of rows) {
44+
if (!data) {
45+
// build hierarchies - groups and subgroups
46+
hierarchies = PivotUtil.getFieldsHierarchy(collection, [row], PivotDimensionType.Row, pivotKeys);
47+
// generate flat data from the hierarchies
48+
data = PivotUtil.processHierarchy(hierarchies, collection[0] ?? [], pivotKeys, 0, true);
49+
prevRowDims.push(row);
50+
prevDim = row;
51+
} else {
52+
const newData = [...data];
53+
for (let i = 0; i < newData.length; i++) {
54+
const currData = newData[i][prevDim.memberName + '_' + pivotKeys.records];
55+
const hierarchyFields = PivotUtil
56+
.getFieldsHierarchy(currData, [row], PivotDimensionType.Row, pivotKeys);
57+
const siblingData = PivotUtil
58+
.processHierarchy(hierarchyFields, newData[i] ?? [], pivotKeys, 0);
59+
PivotUtil.processSiblingProperties(newData[i], siblingData, pivotKeys);
60+
61+
PivotUtil.processSubGroups(row, prevRowDims.slice(0), siblingData, pivotKeys);
62+
if (PivotUtil.getDimensionDepth(prevDim) > PivotUtil.getDimensionDepth(row)) {
63+
newData[i][row.memberName + '_' + pivotKeys.records] = siblingData;
64+
} else {
65+
newData.splice(i, 1, ...siblingData);
6866
}
69-
data = newData;
70-
prevDim = row;
71-
prevRowDims.push(row);
67+
i += siblingData.length - 1;
7268
}
69+
data = newData;
70+
prevDim = row;
71+
prevRowDims.push(row);
7372
}
74-
return data;
7573
}
74+
return data;
7675
}
76+
}
7777

7878
export class PivotColumnDimensionsStrategy implements IPivotDimensionStrategy {
7979
private static _instance: PivotRowDimensionsStrategy = null;
@@ -83,43 +83,54 @@ export class PivotColumnDimensionsStrategy implements IPivotDimensionStrategy {
8383
}
8484

8585
public process(
86-
collection: any[],
87-
columns: IPivotDimension[],
88-
values: IPivotValue[],
89-
pivotKeys: IPivotKeys = {aggregations: 'aggregations', records: 'records', children: 'children', level: 'level'}
90-
): any[] {
91-
const result = [];
92-
collection.forEach(hierarchy => {
93-
// apply aggregations based on the created groups and generate column fields based on the hierarchies
94-
this.groupColumns(hierarchy, columns, values, pivotKeys);
95-
if (hierarchy[pivotKeys.children]) {
96-
let flatCols = {};
97-
PivotUtil.flattenColumnHierarchy(hierarchy[pivotKeys.children], values, pivotKeys).forEach(o => {
98-
delete o[pivotKeys.records];
99-
flatCols = {...flatCols, ...o};
100-
});
101-
delete hierarchy[pivotKeys.children]; /* or we can keep it
102-
and use when creating the columns in pivot grid instead of recreating it */
103-
const keys = Object.keys(hierarchy);
104-
//remove all record keys from final data since we don't need them anymore.
105-
keys.forEach(k => {
106-
if (k.indexOf(pivotKeys.records) !== -1 || k === pivotKeys.level) {
107-
delete hierarchy[k];
86+
collection: any[],
87+
columns: IPivotDimension[],
88+
values: IPivotValue[],
89+
pivotKeys: IPivotKeys = { aggregations: 'aggregations', records: 'records', children: 'children', level: 'level' }
90+
): any[] {
91+
const res = this.processHierarchy(collection, columns, values, pivotKeys);
92+
return res;
93+
}
94+
95+
private processHierarchy(collection, columns: IPivotDimension[], values, pivotKeys) {
96+
const result = [];
97+
collection.forEach(hierarchy => {
98+
// apply aggregations based on the created groups and generate column fields based on the hierarchies
99+
this.groupColumns(hierarchy, columns, values, pivotKeys);
100+
if (hierarchy[pivotKeys.children]) {
101+
let flatCols = {};
102+
PivotUtil.flattenColumnHierarchy(hierarchy[pivotKeys.children], values, pivotKeys).forEach(o => {
103+
delete o[pivotKeys.records];
104+
flatCols = { ...flatCols, ...o };
105+
});
106+
delete hierarchy[pivotKeys.children]; /* or we can keep it
107+
and use when creating the columns in pivot grid instead of recreating it */
108+
const keys = Object.keys(hierarchy);
109+
//remove all record keys from final data since we don't need them anymore.
110+
keys.forEach(k => {
111+
if (k.indexOf(pivotKeys.records) !== -1) {
112+
if (hierarchy[k]) {
113+
this.processHierarchy(hierarchy[k], columns, values, pivotKeys);
108114
}
109-
});
110-
if (this.isLeaf(hierarchy, pivotKeys)) {
111-
delete hierarchy[pivotKeys.records]; /* remove the helper records of the actual records so that
112-
expand indicators can be rendered properly */
115+
//delete hierarchy[k];
113116
}
114-
for (const property in flatCols) {
115-
if (flatCols.hasOwnProperty(property)) {
116-
hierarchy[property] = flatCols[property];
117-
}
117+
if (k === pivotKeys.level) {
118+
delete hierarchy[k];
118119
}
119-
result.push(hierarchy);
120+
});
121+
if (this.isLeaf(hierarchy, pivotKeys)) {
122+
delete hierarchy[pivotKeys.records]; /* remove the helper records of the actual records so that
123+
expand indicators can be rendered properly */
120124
}
121-
});
122-
return result;
125+
for (const property in flatCols) {
126+
if (flatCols.hasOwnProperty(property)) {
127+
hierarchy[property] = flatCols[property];
128+
}
129+
}
130+
result.push(hierarchy);
131+
}
132+
});
133+
return result;
123134
}
124135

125136
private groupColumns(hierarchy, columns, values, pivotKeys) {

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,9 @@
3333
<ng-template igxGridFor let-rowData [igxGridForOf]="data
3434
| pivotGridFilter:pivotConfiguration:filterStrategy:advancedFilteringExpressionsTree
3535
| pivotGridRow:pivotConfiguration:expansionStates:pipeTrigger
36-
| pivotGridRowExpansion:pivotConfiguration:expansionStates:pipeTrigger
37-
| pivotGridColumn:pivotConfiguration:expansionStates:pipeTrigger"
36+
| pivotGridColumn:pivotConfiguration:expansionStates:pipeTrigger
37+
| pivotGridColumnSort:sortingExpressions:sortStrategy:id:pipeTrigger:true
38+
| pivotGridRowExpansion:pivotConfiguration:expansionStates:pipeTrigger"
3839
let-rowIndex="index" [igxForScrollOrientation]="'vertical'" [igxForScrollContainer]='verticalScroll'
3940
[igxForContainerSize]='calcHeight'
4041
[igxForItemSize]="hasColumnLayouts ? rowHeight * multiRowLayoutRowSize + 1 : renderedRowHeight"

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -847,6 +847,7 @@ export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnIni
847847
ref.instance.parent = parent;
848848
ref.instance.dataType = this.pivotConfiguration.values[0]?.dataType || this.resolveDataTypes(data[0][key]);
849849
ref.instance.formatter = this.pivotConfiguration.values[0]?.formatter;
850+
ref.instance.sortable = true;
850851
ref.changeDetectorRef.detectChanges();
851852
columns.push(ref.instance);
852853
if (this.hasMultipleValues) {
@@ -859,6 +860,7 @@ export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnIni
859860
const ref = factoryColumnGroup.create(this.viewRef.injector);
860861
ref.instance.parent = parent;
861862
ref.instance.field = key;
863+
ref.instance.sortable = true;
862864
ref.instance.header = parent != null ? key.split(parent.header + '-')[1] : key;
863865
if (value.expandable) {
864866
ref.instance.headerTemplate = this.headerTemplate;
@@ -868,6 +870,7 @@ export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnIni
868870
refSibling.instance.header = parent != null ? key.split(parent.header + '-')[1] : key;
869871
refSibling.instance.field = key;
870872
refSibling.instance.parent = parent;
873+
ref.instance.sortable = true;
871874
refSibling.instance.hidden = true;
872875
refSibling.instance.dataType = this.pivotConfiguration.values[0]?.dataType || this.resolveDataTypes(data[0][key]);
873876
refSibling.instance.formatter = this.pivotConfiguration.values[0]?.formatter;
@@ -901,6 +904,7 @@ export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnIni
901904
ref.instance.field = parent.field + '-' + val.member;
902905
ref.instance.parent = parent;
903906
ref.instance.hidden = hidden;
907+
ref.instance.sortable = true;
904908
ref.instance.dataType = val.dataType || this.resolveDataTypes(data[0][val.member]);
905909
ref.instance.formatter = val.formatter;
906910
ref.changeDetectorRef.detectChanges();

projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-grid.module.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
22
import { IgxGridModule } from '../grid/grid.module';
33
import { IgxPivotGridComponent } from './pivot-grid.component';
44
import { IgxPivotRowComponent } from './pivot-row.component';
5-
import { IgxPivotRowPipe, IgxPivotColumnPipe, IgxPivotGridFilterPipe, IgxPivotRowExpansionPipe } from './pivot-grid.pipes';
5+
import { IgxPivotRowPipe, IgxPivotColumnPipe, IgxPivotGridFilterPipe,
6+
IgxPivotRowExpansionPipe, IgxPivotGridSortingPipe } from './pivot-grid.pipes';
67
import { IgxGridComponent } from '../grid/grid.component';
78
import { IgxPivotHeaderRowComponent } from './pivot-header-row.component';
89

@@ -17,7 +18,8 @@ import { IgxPivotHeaderRowComponent } from './pivot-header-row.component';
1718
IgxPivotRowPipe,
1819
IgxPivotRowExpansionPipe,
1920
IgxPivotColumnPipe,
20-
IgxPivotGridFilterPipe
21+
IgxPivotGridFilterPipe,
22+
IgxPivotGridSortingPipe
2123
],
2224
exports: [
2325
IgxGridModule,
@@ -27,7 +29,8 @@ import { IgxPivotHeaderRowComponent } from './pivot-header-row.component';
2729
IgxPivotRowExpansionPipe,
2830
IgxPivotRowPipe,
2931
IgxPivotColumnPipe,
30-
IgxPivotGridFilterPipe
32+
IgxPivotGridFilterPipe,
33+
IgxPivotGridSortingPipe
3134
],
3235
imports: [
3336
IgxGridModule,

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

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import { IPivotConfiguration, IPivotDimension, IPivotKeys } from './pivot-grid.i
77
import { PivotColumnDimensionsStrategy, PivotRowDimensionsStrategy } from '../../data-operations/pivot-strategy';
88
import { PivotUtil } from './pivot-util';
99
import { FilteringLogic } from '../../data-operations/filtering-expression.interface';
10+
import { ISortingExpression } from '../../data-operations/sorting-expression.interface';
11+
import { IGridSortingStrategy } from '../../data-operations/sorting-strategy';
1012
/**
1113
* @hidden
1214
*/
@@ -127,3 +129,27 @@ export class IgxPivotGridFilterPipe implements PipeTransform {
127129
return result;
128130
}
129131
}
132+
133+
134+
/**
135+
* @hidden
136+
*/
137+
@Pipe({
138+
name: 'pivotGridColumnSort',
139+
pure: true
140+
})
141+
export class IgxPivotGridSortingPipe implements PipeTransform {
142+
143+
public transform(collection: any[], expressions: ISortingExpression[], sorting: IGridSortingStrategy,
144+
id: string, pipeTrigger: number, pinned?): any[] {
145+
let result: any[];
146+
147+
if (!expressions.length) {
148+
result = collection;
149+
} else {
150+
result = DataUtil.sort(cloneArray(collection), expressions, sorting);
151+
}
152+
153+
return result;
154+
}
155+
}

0 commit comments

Comments
 (0)