Skip to content

Commit 598dac6

Browse files
committed
Merge branch 'pivot-grid-master' of https://github.com/IgniteUI/igniteui-angular into mdragnev/row-dimensions
2 parents f12963e + cc3279e commit 598dac6

File tree

8 files changed

+217
-71
lines changed

8 files changed

+217
-71
lines changed
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
import { IgxDateSummaryOperand, IgxNumberSummaryOperand, IgxTimeSummaryOperand } from '../summaries/grid-summary';
2+
3+
4+
export class IgxPivotAggregate {
5+
/**
6+
* Counts all the records in the data source.
7+
* If filtering is applied, counts only the filtered records.
8+
* ```typescript
9+
* IgxSummaryOperand.count(dataSource);
10+
* ```
11+
*
12+
* @memberof IgxPivotAggregate
13+
*/
14+
public static count(members: number[]): number {
15+
return members.length;
16+
}
17+
}
18+
19+
export class IgxPivotNumericAggregate extends IgxPivotAggregate {
20+
/**
21+
* Returns the minimum numeric value in the provided data records.
22+
* If filtering is applied, returns the minimum value in the filtered data records.
23+
* ```typescript
24+
* IgxPivotNumericAggregate.min(members, data);
25+
* ```
26+
*
27+
* @memberof IgxPivotNumericAggregate
28+
*/
29+
public static min(members: number[]): number {
30+
return IgxNumberSummaryOperand.min(members);
31+
}
32+
33+
/**
34+
* Returns the maximum numeric value in the provided data records.
35+
* If filtering is applied, returns the maximum value in the filtered data records.
36+
* ```typescript
37+
* IgxPivotNumericAggregate.max(data);
38+
* ```
39+
*
40+
* @memberof IgxPivotNumericAggregate
41+
*/
42+
public static max(members: number[]): number {
43+
return IgxNumberSummaryOperand.max(members);
44+
}
45+
46+
/**
47+
* Returns the sum of the numeric values in the provided data records.
48+
* If filtering is applied, returns the sum of the numeric values in the data records.
49+
* ```typescript
50+
* IgxPivotNumericAggregate.sum(data);
51+
* ```
52+
*
53+
* @memberof IgxPivotNumericAggregate
54+
*/
55+
public static sum(members: number[]): number {
56+
return IgxNumberSummaryOperand.sum(members);
57+
}
58+
59+
/**
60+
* Returns the average numeric value in the data provided data records.
61+
* If filtering is applied, returns the average numeric value in the filtered data records.
62+
* ```typescript
63+
* IgxPivotNumericAggregate.average(data);
64+
* ```
65+
*
66+
* @memberof IgxPivotNumericAggregate
67+
*/
68+
public static average(members: number[]): number {
69+
return IgxNumberSummaryOperand.average(members);
70+
}
71+
}
72+
73+
export class IgxPivotDateAggregate extends IgxPivotAggregate {
74+
/**
75+
* Returns the latest date value in the data records.
76+
* If filtering is applied, returns the latest date value in the filtered data records.
77+
* ```typescript
78+
* IgxPivotDateAggregate.latest(data);
79+
* ```
80+
*
81+
* @memberof IgxPivotDateAggregate
82+
*/
83+
public static latest(members: number[]) {
84+
return IgxDateSummaryOperand.latest(members);
85+
}
86+
87+
/**
88+
* Returns the earliest date value in the data records.
89+
* If filtering is applied, returns the latest date value in the filtered data records.
90+
* ```typescript
91+
* IgxPivotDateAggregate.earliest(data);
92+
* ```
93+
*
94+
* @memberof IgxPivotDateAggregate
95+
*/
96+
public static earliest(members: number[]) {
97+
return IgxDateSummaryOperand.earliest(members);
98+
}
99+
}
100+
101+
export class IgxPivotTimeAggregate extends IgxPivotAggregate {
102+
/**
103+
* Returns the latest time value in the data records. Compare only the time part of the date.
104+
* If filtering is applied, returns the latest time value in the filtered data records.
105+
* ```typescript
106+
* IgxPivotTimeAggregate.latestTime(data);
107+
* ```
108+
*
109+
* @memberof IgxPivotTimeAggregate
110+
*/
111+
public static latestTime(members: number[]) {
112+
return IgxTimeSummaryOperand.latestTime(members);
113+
}
114+
115+
/**
116+
* Returns the earliest time value in the data records. Compare only the time part of the date.
117+
* If filtering is applied, returns the earliest time value in the filtered data records.
118+
* ```typescript
119+
* IgxPivotTimeAggregate.earliestTime(data);
120+
* ```
121+
*
122+
* @memberof IgxPivotTimeAggregate
123+
*/
124+
public static earliestTime(members: number[]) {
125+
return IgxTimeSummaryOperand.earliestTime(members);
126+
}
127+
}

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

Lines changed: 48 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnIni
8282

8383

8484
public columnGroupStates = new Map<string, boolean>();
85-
public pivotKeys: IPivotKeys = {aggregations: 'aggregations', records: 'records', children: 'children', level: 'level'};
85+
public pivotKeys: IPivotKeys = { aggregations: 'aggregations', records: 'records', children: 'children', level: 'level' };
8686
public isPivot = true;
8787
protected _defaultExpandState = true;
8888
private _data;
@@ -102,11 +102,11 @@ export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnIni
102102
* @hidden
103103
*/
104104
public ngAfterContentInit() {
105-
// ignore any user defined columns and auto-generate based on pivot config.
106-
this.columnList.reset([]);
107-
Promise.resolve().then(() => {
108-
this.setupColumns();
109-
});
105+
// ignore any user defined columns and auto-generate based on pivot config.
106+
this.columnList.reset([]);
107+
Promise.resolve().then(() => {
108+
this.setupColumns();
109+
});
110110
}
111111

112112
/** @hidden */
@@ -207,18 +207,18 @@ export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnIni
207207
return MINIMUM_COLUMN_WIDTH * rowDimCount;
208208
}
209209

210-
public toggleColumn(col: IgxColumnComponent) {
211-
const state = this.columnGroupStates.get(col.field);
212-
const newState = !state;
213-
this.columnGroupStates.set(col.field, newState);
214-
this.toggleGroup(col, newState);
215-
this.reflow();
216-
}
210+
public toggleColumn(col: IgxColumnComponent) {
211+
const state = this.columnGroupStates.get(col.field);
212+
const newState = !state;
213+
this.columnGroupStates.set(col.field, newState);
214+
this.toggleGroup(col, newState);
215+
this.reflow();
216+
}
217217

218-
protected toggleGroup(col: IgxColumnComponent, newState: boolean) {
218+
protected toggleGroup(col: IgxColumnComponent, newState: boolean) {
219219
if (this.hasMultipleValues) {
220-
const fieldColumns = col.children.filter(x => !x.columnGroup);
221-
const groupColumns = col.children.filter(x => x.columnGroup);
220+
const fieldColumns = col.children.filter(x => !x.columnGroup);
221+
const groupColumns = col.children.filter(x => x.columnGroup);
222222
groupColumns.forEach(groupColumn => {
223223
groupColumn.hidden = newState;
224224
this.resolveToggle(groupColumn);
@@ -228,23 +228,23 @@ export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnIni
228228
});
229229
} else {
230230
const parentCols = col.parent ? col.parent.children : this.columns.filter(x => x.level === 0);
231-
const fieldColumn = parentCols.filter(x => x.header === col.header && !x.columnGroup)[0];
232-
const groupColumn = parentCols.filter(x => x.header === col.header && x.columnGroup)[0];
231+
const fieldColumn = parentCols.filter(x => x.header === col.header && !x.columnGroup)[0];
232+
const groupColumn = parentCols.filter(x => x.header === col.header && x.columnGroup)[0];
233233
groupColumn.hidden = newState;
234234
this.resolveToggle(groupColumn);
235235
fieldColumn.hidden = !newState;
236236
if (newState) {
237-
fieldColumn.headerTemplate = this.headerTemplate;
237+
fieldColumn.headerTemplate = this.headerTemplate;
238238
} else {
239-
fieldColumn.headerTemplate = undefined;
239+
fieldColumn.headerTemplate = undefined;
240240
}
241241
}
242-
}
242+
}
243243

244-
protected resolveToggle(groupColumn: IgxColumnComponent) {
245-
const hasChildGroup = groupColumn.children.filter(x => x.columnGroup).length > 0;
246-
if (!groupColumn.hidden && hasChildGroup) {
247-
const fieldChildren = groupColumn.children.filter(x => !x.columnGroup);
244+
protected resolveToggle(groupColumn: IgxColumnComponent) {
245+
const hasChildGroup = groupColumn.children.filter(x => x.columnGroup).length > 0;
246+
if (!groupColumn.hidden && hasChildGroup) {
247+
const fieldChildren = groupColumn.children.filter(x => !x.columnGroup);
248248
const groupChildren = groupColumn.children.filter(x => x.columnGroup);
249249
groupChildren.forEach(group => {
250250
this.resolveToggle(group);
@@ -269,26 +269,26 @@ export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnIni
269269
/**
270270
* @hidden
271271
*/
272-
protected autogenerateColumns() {
273-
let columns = [];
274-
const data = this.gridAPI.get_data();
275-
let fieldsMap;
276-
if (this.pivotConfiguration.columnStrategy && this.pivotConfiguration.columnStrategy instanceof NoopPivotDimensionsStrategy) {
272+
protected autogenerateColumns() {
273+
let columns = [];
274+
const data = this.gridAPI.get_data();
275+
let fieldsMap;
276+
if (this.pivotConfiguration.columnStrategy && this.pivotConfiguration.columnStrategy instanceof NoopPivotDimensionsStrategy) {
277277
const fields = this.generateDataFields(data);
278278
const rowFields = PivotUtil.flatten(this.pivotConfiguration.rows).map(x => x.memberName);
279279
const keyFields = Object.values(this.pivotKeys);
280280
const filteredFields = fields.filter(x => rowFields.indexOf(x) === -1 && keyFields.indexOf(x) === -1 &&
281-
x.indexOf('_level') === -1 && x.indexOf('_records') === -1);
281+
x.indexOf('_level') === -1 && x.indexOf('_records') === -1);
282282
fieldsMap = this.generateFromData(filteredFields);
283-
} else {
283+
} else {
284284
fieldsMap = PivotUtil.getFieldsHierarchy(
285-
data,
286-
this.pivotConfiguration.columns,
287-
PivotDimensionType.Column,
288-
{aggregations: 'aggregations', records: 'records', children: 'children', level: 'level'}
285+
data,
286+
this.pivotConfiguration.columns,
287+
PivotDimensionType.Column,
288+
{ aggregations: 'aggregations', records: 'records', children: 'children', level: 'level' }
289289
);
290-
}
291-
columns = this.generateColumnHierarchy(fieldsMap, data);
290+
}
291+
columns = this.generateColumnHierarchy(fieldsMap, data);
292292
this._autoGeneratedCols = columns;
293293

294294
this.columnList.reset(columns);
@@ -303,11 +303,11 @@ export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnIni
303303
dataArr.forEach(arr => {
304304
let currentHierarchy = hierarchy;
305305
const path = [];
306-
for(const val of arr) {
306+
for (const val of arr) {
307307
path.push(val);
308308
let h = currentHierarchy.get(path.join('-'));
309-
if(!h) {
310-
currentHierarchy.set(path.join('-'), { expandable: true, children: new Map<string, any>()});
309+
if (!h) {
310+
currentHierarchy.set(path.join('-'), { expandable: true, children: new Map<string, any>() });
311311
h = currentHierarchy.get(path.join('-'));
312312
}
313313
currentHierarchy = h.children;
@@ -316,22 +316,22 @@ export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnIni
316316
return hierarchy;
317317
}
318318

319-
protected generateColumnHierarchy(fields: Map<string, any>, data, parent = null): IgxColumnComponent[] {
319+
protected generateColumnHierarchy(fields: Map<string, any>, data, parent = null): IgxColumnComponent[] {
320320
const factoryColumn = this.resolver.resolveComponentFactory(IgxColumnComponent);
321321
const factoryColumnGroup = this.resolver.resolveComponentFactory(IgxColumnGroupComponent);
322322
let columns = [];
323323
fields.forEach((value, key) => {
324324
if (value.children == null || value.children.length === 0 || value.children.size === 0) {
325325
const ref = this.hasMultipleValues ?
326-
factoryColumnGroup.create(this.viewRef.injector) :
327-
factoryColumn.create(this.viewRef.injector);
326+
factoryColumnGroup.create(this.viewRef.injector) :
327+
factoryColumn.create(this.viewRef.injector);
328328
ref.instance.header = parent != null ? key.split(parent.header + '-')[1] : key;
329329
ref.instance.field = key;
330330
ref.instance.parent = parent;
331331
ref.changeDetectorRef.detectChanges();
332332
columns.push(ref.instance);
333333
if (this.hasMultipleValues) {
334-
const measureChildren = this.getMeasureChildren(factoryColumn, data , ref.instance, false);
334+
const measureChildren = this.getMeasureChildren(factoryColumn, data, ref.instance, false);
335335
ref.instance.children.reset(measureChildren);
336336
columns = columns.concat(measureChildren);
337337
}
@@ -344,7 +344,7 @@ export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnIni
344344
if (value.expandable) {
345345
ref.instance.headerTemplate = this.headerTemplate;
346346
}
347-
if(!this.hasMultipleValues) {
347+
if (!this.hasMultipleValues) {
348348
const refSibling = factoryColumn.create(this.viewRef.injector);
349349
refSibling.instance.header = parent != null ? key.split(parent.header + '-')[1] : key;
350350
refSibling.instance.field = key;
@@ -358,7 +358,7 @@ export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnIni
358358
ref.changeDetectorRef.detectChanges();
359359
columns.push(ref.instance);
360360
if (this.hasMultipleValues) {
361-
const measureChildren = this.getMeasureChildren(factoryColumn, data , ref.instance, true);
361+
const measureChildren = this.getMeasureChildren(factoryColumn, data, ref.instance, true);
362362
const nestedChildren = filteredChildren.concat(measureChildren);
363363
const allChildren = children.concat(measureChildren);
364364
ref.instance.children.reset(nestedChildren);
@@ -377,7 +377,7 @@ export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnIni
377377
const cols = [];
378378
this.pivotConfiguration.values.forEach(val => {
379379
const ref = colFactory.create(this.viewRef.injector);
380-
ref.instance.header = val.member;
380+
ref.instance.header = val.displayName || val.member;
381381
ref.instance.field = parent.field + '-' + val.member;
382382
ref.instance.parent = parent;
383383
ref.instance.hidden = hidden;

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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ import { FilteringExpressionsTree } from '../../data-operations/filtering-expres
22
import { IPivotDimensionStrategy } from '../../data-operations/pivot-strategy';
33

44

5+
6+
export type PivotAggregation = (members: any[], data: any[]) => any;
7+
58
export interface IPivotConfiguration {
69
rowStrategy?: IPivotDimensionStrategy | null;
710
columnStrategy?: IPivotDimensionStrategy | null;
@@ -25,8 +28,13 @@ export interface IPivotDimension {
2528

2629
export interface IPivotValue {
2730
member: string;
28-
// aggregate function - can use one of the predefined like IgxNumberSummaryOperand.sum etc.
29-
aggregate: (data: any[]) => any;
31+
// display name if present shows instead of member for the column header of this value
32+
displayName?: string;
33+
/**
34+
* Aggregation function - can be a custom implementation of PivotAggregation or
35+
* use predefined ones from IgxPivotAggregate and its variants
36+
*/
37+
aggregate: PivotAggregation;
3038
// Enables/Disables a particular value from pivot aggregation.
3139
enabled: boolean;
3240
// Allow conditionally styling of the IgxPivotGrid cells

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ export class PivotUtil {
188188
public static aggregate(records, values: IPivotValue[]) {
189189
const result = {};
190190
for (const pivotValue of values) {
191-
result[pivotValue.member] = pivotValue.aggregate(records.map(r => r[pivotValue.member]));
191+
result[pivotValue.member] = pivotValue.aggregate(records.map(r => r[pivotValue.member]), records);
192192
}
193193

194194
return result;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
export * from './pivot-grid.component';
22
export * from './pivot-grid.interface';
3+
export * from './pivot-grid-aggregate';
34
export * from './pivot-grid.module';
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
<div class="sample-column">
2-
<igx-pivot-grid #grid1 [data]="origData" [width]= '"1200px"' [pivotConfiguration]="pivotConfigHierarchy">
2+
<igx-pivot-grid #grid1 [data]="origData" [width]="'1200px'" [height]="'100%'" [pivotConfiguration]="pivotConfigHierarchy">
33
</igx-pivot-grid>
44
</div>

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
:host ::ng-deep {
22
.upFont {
3-
color: green;
3+
color: lightgreen;
44
}
55

66
.downFont {
7-
color:red;
7+
color: lightcoral;
88
}
99

1010
.upFont1 {
11-
color: blue;
11+
color: skyblue;
1212
}
1313

1414
.downFont1 {
15-
color:yellow;
15+
color: yellow;
1616
}
1717

1818
.sample-column {

0 commit comments

Comments
 (0)