Skip to content

Commit d31b721

Browse files
authored
Merge pull request #10265 from IgniteUI/mkirova/pivot-multiple-measures
Add support for multiple measures.
2 parents 238fcc4 + 36c6558 commit d31b721

File tree

4 files changed

+120
-20
lines changed

4 files changed

+120
-20
lines changed

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

Lines changed: 67 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -209,20 +209,36 @@ export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnIni
209209
const state = this.columnGroupStates.get(col.field);
210210
const newState = !state;
211211
this.columnGroupStates.set(col.field, newState);
212-
const parentCols = col.parent ? col.parent.children : this.columns.filter(x => x.level === 0);
213-
const fieldColumn = parentCols.filter(x => x.header === col.header && !x.columnGroup)[0];
214-
const groupColumn = parentCols.filter(x => x.header === col.header && x.columnGroup)[0];
215-
groupColumn.hidden = newState;
216-
this.resolveToggle(groupColumn);
217-
fieldColumn.hidden = !newState;
218-
if (newState) {
219-
fieldColumn.headerTemplate = this.headerTemplate;
220-
} else {
221-
fieldColumn.headerTemplate = undefined;
222-
}
212+
this.toggleGroup(col, newState);
223213
this.reflow();
224214
}
225215

216+
protected toggleGroup(col: IgxColumnComponent, newState: boolean) {
217+
if (this.hasMultipleValues) {
218+
const fieldColumns = col.children.filter(x => !x.columnGroup);
219+
const groupColumns = col.children.filter(x => x.columnGroup);
220+
groupColumns.forEach(groupColumn => {
221+
groupColumn.hidden = newState;
222+
this.resolveToggle(groupColumn);
223+
});
224+
fieldColumns.forEach(fieldColumn => {
225+
fieldColumn.hidden = !newState;
226+
});
227+
} else {
228+
const parentCols = col.parent ? col.parent.children : this.columns.filter(x => x.level === 0);
229+
const fieldColumn = parentCols.filter(x => x.header === col.header && !x.columnGroup)[0];
230+
const groupColumn = parentCols.filter(x => x.header === col.header && x.columnGroup)[0];
231+
groupColumn.hidden = newState;
232+
this.resolveToggle(groupColumn);
233+
fieldColumn.hidden = !newState;
234+
if (newState) {
235+
fieldColumn.headerTemplate = this.headerTemplate;
236+
} else {
237+
fieldColumn.headerTemplate = undefined;
238+
}
239+
}
240+
}
241+
226242
protected resolveToggle(groupColumn: IgxColumnComponent) {
227243
const hasChildGroup = groupColumn.children.filter(x => x.columnGroup).length > 0;
228244
if (!groupColumn.hidden && hasChildGroup) {
@@ -244,6 +260,10 @@ export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnIni
244260
protected calcGridHeadRow() {
245261
}
246262

263+
protected get hasMultipleValues() {
264+
return this.pivotConfiguration.values.length > 1;
265+
}
266+
247267
/**
248268
* @hidden
249269
*/
@@ -270,20 +290,29 @@ export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnIni
270290
let columns = [];
271291
fields.forEach((value, key) => {
272292
if (value.children == null || value.children.length === 0 || value.children.size === 0) {
273-
const ref = factoryColumn.create(this.viewRef.injector);
293+
const ref = this.hasMultipleValues ?
294+
factoryColumnGroup.create(this.viewRef.injector) :
295+
factoryColumn.create(this.viewRef.injector);
274296
ref.instance.header = parent != null ? key.split(parent.header + '-')[1] : key;
275297
ref.instance.field = key;
276-
ref.instance.dataType = this.resolveDataTypes(data[0][key]);
277298
ref.instance.parent = parent;
278299
ref.changeDetectorRef.detectChanges();
279300
columns.push(ref.instance);
301+
if (this.hasMultipleValues) {
302+
const measureChildren = this.getMeasureChildren(factoryColumn, data , ref.instance, false);
303+
ref.instance.children.reset(measureChildren);
304+
columns = columns.concat(measureChildren);
305+
}
306+
280307
} else {
281308
const ref = factoryColumnGroup.create(this.viewRef.injector);
282309
ref.instance.parent = parent;
283310
ref.instance.field = key;
284311
ref.instance.header = parent != null ? key.split(parent.header + '-')[1] : key;
285312
if (value.expandable) {
286313
ref.instance.headerTemplate = this.headerTemplate;
314+
}
315+
if(!this.hasMultipleValues) {
287316
const refSibling = factoryColumn.create(this.viewRef.injector);
288317
refSibling.instance.header = parent != null ? key.split(parent.header + '-')[1] : key;
289318
refSibling.instance.field = key;
@@ -295,15 +324,36 @@ export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnIni
295324
const children = this.generateColumnHierarchy(value.children, data, ref.instance);
296325
const filteredChildren = children.filter(x => x.level === ref.instance.level + 1);
297326
ref.changeDetectorRef.detectChanges();
298-
299-
ref.instance.children.reset(filteredChildren);
300-
301327
columns.push(ref.instance);
302-
columns = columns.concat(children);
328+
if (this.hasMultipleValues) {
329+
const measureChildren = this.getMeasureChildren(factoryColumn, data , ref.instance, true);
330+
const nestedChildren = filteredChildren.concat(measureChildren);
331+
const allChildren = children.concat(measureChildren);
332+
ref.instance.children.reset(nestedChildren);
333+
columns = columns.concat(allChildren);
334+
} else {
335+
ref.instance.children.reset(filteredChildren);
336+
columns = columns.concat(children);
337+
}
303338
}
304339
});
305340
return columns;
306341
}
307342

343+
protected getMeasureChildren(colFactory, data, parent, hidden) {
344+
const cols = [];
345+
this.pivotConfiguration.values.forEach(val => {
346+
const ref = colFactory.create(this.viewRef.injector);
347+
ref.instance.header = val.member;
348+
ref.instance.field = parent.field + '-' + val.member;
349+
ref.instance.parent = parent;
350+
ref.instance.hidden = hidden;
351+
ref.instance.dataType = this.resolveDataTypes(data[0][val.member]);
352+
ref.changeDetectorRef.detectChanges();
353+
cols.push(ref.instance);
354+
});
355+
return cols;
356+
}
357+
308358

309359
}

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

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { IgxNumberSummaryOperand } from '../summaries/grid-summary';
2-
import { IPivotConfiguration } from './pivot-grid.interface';
2+
import { IPivotConfiguration, IPivotValue } from './pivot-grid.interface';
33
import { IgxPivotColumnPipe, IgxPivotRowPipe } from './pivot-grid.pipes';
44

55
describe('Pivot pipes', () => {
@@ -75,7 +75,7 @@ describe('Pivot pipes', () => {
7575
}], expansionStates, pivotConfigHierarchy.values);
7676
expect(rowPipeResult).toEqual([
7777
{
78-
ProductCategory: 'Clothing', level: 0, records: [
78+
ProductCategory: 'Clothing', level: 0, records: [
7979
{ ProductCategory: 'Clothing', UnitPrice: 12.81, SellerName: 'Stanley', Country: 'Bulgaria', Date: '01/01/2021', UnitsSold: 282 },
8080
{ ProductCategory: 'Clothing', UnitPrice: 49.57, SellerName: 'Elisa', Country: 'USA', Date: '01/05/2019', UnitsSold: 296 },
8181
{ ProductCategory: 'Clothing', UnitPrice: 68.33, SellerName: 'Larry', Country: 'Uruguay', Date: '05/12/2020', UnitsSold: 456 },
@@ -403,4 +403,44 @@ describe('Pivot pipes', () => {
403403
{'field1':'Components','level':1,'USA':240,'USA-John':240,'USA-John-12/08/2021':240}
404404
]);
405405
});
406+
407+
it('transforms flat data to pivot data 2 value dimensions', () => {
408+
const values: IPivotValue[] = [
409+
{
410+
member: 'UnitsSold',
411+
aggregate: IgxNumberSummaryOperand.sum,
412+
enabled: true
413+
},
414+
{
415+
member: 'UnitPrice',
416+
aggregate: IgxNumberSummaryOperand.sum,
417+
enabled: true
418+
}
419+
];
420+
const rowPipeResult = rowPipe.transform(data, pivotConfigHierarchy.rows, expansionStates, values);
421+
const columnPipeResult = columnPipe.transform(rowPipeResult, pivotConfigHierarchy.columns, values);
422+
expect(columnPipeResult).toEqual([{
423+
'field1':'All','records':[
424+
{'field1':'Clothing','level':1,'All-UnitsSold':1526,'All-Bulgaria-UnitsSold':774,
425+
'All-Bulgaria-UnitPrice':28.86,'All-USA-UnitsSold':296,'All-USA-UnitPrice':49.57,'All-Uruguay-UnitsSold':456,
426+
'All-Uruguay-UnitPrice':68.33,'All-UnitPrice':146.76},
427+
{'field1':'Bikes','level':1,'All-UnitsSold':68,'All-Uruguay-UnitsSold':68,
428+
'All-Uruguay-UnitPrice':3.56,'All-UnitPrice':3.56},
429+
{'field1':'Accessories','level':1,'All-UnitsSold':293,'All-USA-UnitsSold':293,
430+
'All-USA-UnitPrice':85.58,'All-UnitPrice':85.58},
431+
{'field1':'Components','level':1,'All-UnitsSold':240,'All-USA-UnitsSold':240,
432+
'All-USA-UnitPrice':18.13,'All-UnitPrice':18.13}
433+
],'level':0,'All-UnitsSold':2127,'All-Bulgaria-UnitsSold':774,'All-Bulgaria-UnitPrice':28.86,'All-USA-UnitsSold':829,
434+
'All-USA-UnitPrice':153.28,'All-Uruguay-UnitsSold':524,'All-Uruguay-UnitPrice':71.89,'All-UnitPrice':254.02999999999997},
435+
{'field1':'Clothing','level':1,'All-UnitsSold':1526,'All-Bulgaria-UnitsSold':774,
436+
'All-Bulgaria-UnitPrice':28.86,'All-USA-UnitsSold':296,'All-USA-UnitPrice':49.57,'All-Uruguay-UnitsSold':456,
437+
'All-Uruguay-UnitPrice':68.33,'All-UnitPrice':146.76},
438+
{'field1':'Bikes','level':1,'All-UnitsSold':68,'All-Uruguay-UnitsSold':68,
439+
'All-Uruguay-UnitPrice':3.56,'All-UnitPrice':3.56},
440+
{'field1':'Accessories','level':1,'All-UnitsSold':293,'All-USA-UnitsSold':293,
441+
'All-USA-UnitPrice':85.58,'All-UnitPrice':85.58},
442+
{'field1':'Components','level':1,'All-UnitsSold':240,'All-USA-UnitsSold':240,
443+
'All-USA-UnitPrice':18.13,'All-UnitPrice':18.13}
444+
]);
445+
});
406446
});

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,9 +127,14 @@ export class PivotUtil {
127127
const flatData = [];
128128
hierarchies.forEach((h, key) => {
129129
const obj = {};
130+
const multipleValues = values.length > 1;
130131
for (const value of values) {
131132
if(h[pivotKeys.aggregations]) {
132-
obj[key] = h[pivotKeys.aggregations][value.member];
133+
if (multipleValues) {
134+
obj[key + '-' + value.member] = h[pivotKeys.aggregations][value.member];
135+
} else {
136+
obj[key] = h[pivotKeys.aggregations][value.member];
137+
}
133138
}
134139
obj[pivotKeys.records] = h[pivotKeys.records];
135140
flatData.push(obj);

src/app/pivot-grid/pivot-grid.sample.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,11 @@ export class PivotGridSampleComponent {
8282
member: 'UnitsSold',
8383
aggregate: IgxNumberSummaryOperand.sum,
8484
enabled: true
85+
},
86+
{
87+
member: 'UnitPrice',
88+
aggregate: IgxNumberSummaryOperand.sum,
89+
enabled: true
8590
}
8691
],
8792
filters: null

0 commit comments

Comments
 (0)