Skip to content

Commit 897e4f0

Browse files
committed
feat(pivot): Introduce additional memberFunction to pivot dimensions
1 parent 589df05 commit 897e4f0

File tree

9 files changed

+160
-158
lines changed

9 files changed

+160
-158
lines changed

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

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,23 +46,21 @@ export class PivotRowDimensionsStrategy implements IPivotDimensionStrategy {
4646
hierarchies = PivotUtil.getFieldsHierarchy(collection, [row], PivotDimensionType.Row, pivotKeys);
4747
// generate flat data from the hierarchies
4848
data = PivotUtil.processHierarchy(hierarchies, collection[0] ?? [], pivotKeys, 0, true);
49-
row.fieldName = hierarchies.get(hierarchies.keys().next().value).dimension.fieldName;
5049
prevRowDims.push(row);
5150
prevDim = row;
5251
} else {
5352
const newData = [...data];
5453
for (let i = 0; i < newData.length; i++) {
55-
const currData = newData[i][prevDim.fieldName + '_' + pivotKeys.records];
54+
const currData = newData[i][prevDim.memberName + '_' + pivotKeys.records];
5655
const hierarchyFields = PivotUtil
5756
.getFieldsHierarchy(currData, [row], PivotDimensionType.Row, pivotKeys);
5857
const siblingData = PivotUtil
5958
.processHierarchy(hierarchyFields, newData[i] ?? [], pivotKeys, 0);
60-
row.fieldName = hierarchyFields.get(hierarchyFields.keys().next().value).dimension.fieldName;
6159
PivotUtil.processSiblingProperties(newData[i], siblingData, pivotKeys);
6260

6361
PivotUtil.processSubGroups(row, prevRowDims.slice(0), siblingData, pivotKeys);
6462
if (PivotUtil.getDimensionDepth(prevDim) > PivotUtil.getDimensionDepth(row)) {
65-
newData[i][row.fieldName + '_' + pivotKeys.records] = siblingData;
63+
newData[i][row.memberName + '_' + pivotKeys.records] = siblingData;
6664
} else {
6765
newData.splice(i , 1, ...siblingData);
6866
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnIni
275275
let fieldsMap;
276276
if (this.pivotConfiguration.columnStrategy && this.pivotConfiguration.columnStrategy instanceof NoopPivotDimensionsStrategy) {
277277
const fields = this.generateDataFields(data);
278-
const rowFields = PivotUtil.flatten(this.pivotConfiguration.rows).map(x => x.fieldName);
278+
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 &&
281281
x.indexOf('_level') === -1 && x.indexOf('_records') === -1);

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@ export interface IPivotConfiguration {
1515
export interface IPivotDimension {
1616
// allow defining a hierarchy when multiple sub groups need to be extracted from single member.
1717
childLevels?: IPivotDimension[];
18-
// field name which to use to extract value or function that extract the value.
19-
member: string | ((data: any) => any);
18+
// field name which to use to extract value
19+
memberName: string;
20+
// function that extract the value
21+
memberFunction?: (data: any) => any;
2022
// Enables/Disables a particular dimension from pivot structure.
2123
enabled: boolean;
22-
// additional field name when using member as a function
23-
fieldName?: string;
2424
}
2525

2626
export interface IPivotValue {

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

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,20 +21,23 @@ describe('Pivot pipes', () => {
2121

2222
const pivotConfigHierarchy: IPivotConfiguration = {
2323
columns: [{
24-
member: () => 'All',
24+
memberName: 'All',
25+
memberFunction: () => 'All',
2526
enabled: true,
2627
childLevels: [{
27-
member: 'Country',
28+
memberName: 'Country',
2829
enabled: true,
2930
childLevels: []
3031
}]
3132
}],
3233
rows: [{
33-
member: () => 'All',
34+
memberName: 'All',
35+
memberFunction: () => 'All',
3436
enabled: true,
3537
childLevels: [
3638
{
37-
member: (d) => d.ProductCategory,
39+
memberName: 'ProductCategory',
40+
memberFunction: (d) => d.ProductCategory,
3841
enabled: true,
3942
childLevels: []
4043
}
@@ -66,7 +69,7 @@ describe('Pivot pipes', () => {
6669
it('transforms flat data to pivot data single row dimension and no children are defined', () => {
6770
const config = Object.assign({}, pivotConfigHierarchy);
6871
config.rows = [{
69-
member: 'ProductCategory',
72+
memberName: 'ProductCategory',
7073
enabled: true,
7174
childLevels: []
7275
}];
@@ -221,12 +224,12 @@ describe('Pivot pipes', () => {
221224
it('transforms flat data to pivot data multiple row dimensions', () => {
222225
const config = Object.assign({}, pivotConfigHierarchy);
223226
config.rows = [{
224-
member: 'ProductCategory',
227+
memberName: 'ProductCategory',
225228
enabled: true,
226229
childLevels: []
227230
},
228231
{
229-
member: 'Date',
232+
memberName: 'Date',
230233
enabled: true,
231234
childLevels: []
232235
}];
@@ -297,19 +300,21 @@ describe('Pivot pipes', () => {
297300
it('transforms flat data to pivot data with multiple nested row dimensions', () => {
298301
const config = Object.assign({}, pivotConfigHierarchy);
299302
config.rows = [{
300-
member: () => 'AllProd',
303+
memberName: 'AllProd',
304+
memberFunction: () => 'AllProd',
301305
enabled: true,
302306
childLevels: [{
303-
member: 'ProductCategory',
307+
memberName: 'ProductCategory',
304308
enabled: true,
305309
childLevels: []
306310
}]
307311
},
308312
{
309-
member: () => 'AllDate',
313+
memberName: 'AllDate',
314+
memberFunction: () => 'AllDate',
310315
enabled: true,
311316
childLevels: [{
312-
member: 'Date',
317+
memberName: 'Date',
313318
enabled: true,
314319
childLevels: []
315320
}]
@@ -338,12 +343,12 @@ describe('Pivot pipes', () => {
338343
it('transforms flat data to pivot data 2 column dimensions', () => {
339344
const config = Object.assign({}, pivotConfigHierarchy);
340345
config.columns = [{
341-
member: 'Country',
346+
memberName: 'Country',
342347
enabled: true,
343348
childLevels:[]
344349
},
345350
{
346-
member: 'Date',
351+
memberName: 'Date',
347352
enabled: true,
348353
childLevels: []
349354
}];
@@ -364,17 +369,17 @@ describe('Pivot pipes', () => {
364369
it('transforms flat data to pivot data 3 column dimensions', () => {
365370
const config = Object.assign({}, pivotConfigHierarchy);
366371
config.columns = [{
367-
member: 'Country',
372+
memberName: 'Country',
368373
enabled: true,
369374
childLevels:[]
370375
},
371376
{
372-
member: 'SellerName',
377+
memberName: 'SellerName',
373378
enabled: true,
374379
childLevels:[]
375380
},
376381
{
377-
member: 'Date',
382+
memberName: 'Date',
378383
enabled: true,
379384
childLevels: []
380385
}];
@@ -436,9 +441,9 @@ describe('Pivot pipes', () => {
436441
{ProductCategory:'Components', level:1, All:240,'All-USA':240}]
437442
, level:0,'All-Bulgaria':774,'All-USA':829,'All-Uruguay':524}];
438443
config.columnStrategy = NoopPivotDimensionsStrategy.instance();
439-
config.columns[0].fieldName = 'All';
444+
config.columns[0].memberName = 'All';
440445
config.rowStrategy = NoopPivotDimensionsStrategy.instance();
441-
config.rows[0].fieldName = 'All';
446+
config.rows[0].memberName = 'All';
442447

443448
const rowPipeResult = rowPipe.transform(preprocessedData, config, new Map<any, boolean>());
444449
const rowStateResult = rowStatePipe.transform(rowPipeResult, config, new Map<any, boolean>());

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,18 +93,19 @@ export class IgxPivotGridTestBaseComponent {
9393

9494
this.pivotConfigHierarchy = {
9595
columns: [{
96-
member: 'Country',
96+
memberName: 'Country',
9797
enabled: true,
9898
childLevels: []
9999
},
100100
],
101101
rows: [{
102-
member: () => 'All',
102+
memberName: 'All',
103+
memberFunction: () => 'All',
103104
enabled: true,
104105
childLevels: [
105106
{
106-
fieldName: 'ProductCategory',
107-
member: (data) => data.ProductCategory,
107+
memberName: 'ProductCategory',
108+
memberFunction: (data) => data.ProductCategory,
108109
enabled: true,
109110
childLevels: []
110111
}

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

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -108,13 +108,8 @@ export class IgxPivotRowComponent extends IgxRowDirective<IgxPivotGridComponent>
108108
}
109109

110110
protected extractFromDimension(dim: IPivotDimension, index: number = 0, lvl = 0) {
111-
const field = PivotUtil.resolveFieldName(dim, this.rowData);
112-
let header = null;
113-
if (typeof dim.member === 'string') {
114-
header = this.rowData[dim.member];
115-
} else if (typeof dim.member === 'function'){
116-
header = dim.member.call(this, this.rowData);
117-
}
111+
const field = dim.memberName;
112+
const header = this.rowData[field];
118113
const col = this._createColComponent(field, header, index, dim, lvl);
119114
return col;
120115
}

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

Lines changed: 21 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
import { cloneValue } from '../../core/utils';
32
import { IPivotDimension, IPivotKeys, IPivotValue, PivotDimensionType } from './pivot-grid.interface';
43

@@ -23,7 +22,7 @@ export class PivotUtil {
2322
}
2423

2524
public static extractValueFromDimension(dim: IPivotDimension, recData: any) {
26-
return typeof dim.member === 'string' ? recData[dim.member] : dim.member.call(null, recData);
25+
return dim.memberFunction ? dim.memberFunction.call(null, recData) : recData[dim.memberName];
2726
}
2827

2928
public static getDimensionDepth(dim) {
@@ -36,20 +35,20 @@ export class PivotUtil {
3635
}
3736

3837
public static getDimensionLevel(dim, rec, pivotKeys) {
39-
let level = rec[dim.fieldName + '_' + pivotKeys.level];
38+
let level = rec[dim.memberName + '_' + pivotKeys.level];
4039
while(dim.childLevels && dim.childLevels.length > 0 && level === undefined) {
4140
dim = dim.childLevels[0];
42-
level = rec[dim.fieldName + '_' + pivotKeys.level];
41+
level = rec[dim.memberName + '_' + pivotKeys.level];
4342
}
44-
return { level, fieldName: dim.fieldName, dimension: dim };
43+
return { level, dimension: dim };
4544
}
4645

4746
public static flattenHierarchy(records, config, dim, expansionStates, pivotKeys, lvl, prevDims, currDimLvl) {
4847
const data = records;
4948
const defaultExpandState = true;
5049
for (let i = 0; i < data.length; i++) {
5150
const rec = data[i];
52-
const field = dim.fieldName;
51+
const field = dim.memberName;
5352
if(!field) {
5453
continue;
5554
}
@@ -68,7 +67,7 @@ export class PivotUtil {
6867
expansionStates, pivotKeys, lvl - 1, prevDims, currDimLvl + 1);
6968
} else {
7069
dimData.forEach(d => {
71-
d[dim.childLevels[0].fieldName + '_' + pivotKeys.level] = currDimLvl + 1;
70+
d[dim.childLevels[0].memberName + '_' + pivotKeys.level] = currDimLvl + 1;
7271
});
7372
}
7473
}
@@ -79,10 +78,10 @@ export class PivotUtil {
7978
let shouldConcat = true;
8079
const prevDim = prevDims ? prevDims[prevDims.length - 1] : null;
8180
if (prevDim) {
82-
let prevDimName = prevDim.fieldName;
81+
let prevDimName = prevDim.memberName;
8382
prevDimRecs = rec[prevDimName + '_' + pivotKeys.records];
8483
if(!prevDimRecs) {
85-
prevDimName = prevDim.childLevels[0].fieldName;
84+
prevDimName = prevDim.childLevels[0].memberName;
8685
prevDimRecs = rec[prevDimName + '_' + pivotKeys.records];
8786
}
8887
prevDimLevel = rec[prevDimName + '_' + pivotKeys.level];
@@ -91,11 +90,11 @@ export class PivotUtil {
9190
dimData.forEach(d => {
9291
if (prevDims && prevDims.length > 0) {
9392
if (!shouldConcat) {
94-
d[dim.fieldName + '_' + pivotKeys.level] = currDimLvl;
93+
d[dim.memberName + '_' + pivotKeys.level] = currDimLvl;
9594
}
9695
prevDims.forEach(prev => {
9796
const dimInfo = PivotUtil.getDimensionLevel(prev, rec, pivotKeys);
98-
d[dimInfo.fieldName + '_' + pivotKeys.level] = dimInfo.level;
97+
d[dimInfo.dimension.memberName + '_' + pivotKeys.level] = dimInfo.level;
9998
});
10099
}
101100
});
@@ -213,36 +212,36 @@ export class PivotUtil {
213212
// process combined groups
214213
while(prevRowDims.length > 0) {
215214
const prevRowDim = prevRowDims.shift();
216-
const prevRowField = prevRowDim.fieldName;
215+
const prevRowField = prevRowDim.memberName;
217216
const sameDimLvl = PivotUtil.getDimensionDepth(prevRowDim) === PivotUtil.getDimensionDepth(row);
218217
for (const sibling of siblingData) {
219218
const childCollection = sibling[prevRowField + '_' + pivotKeys.records] || [];
220219
for (const child of childCollection) {
221220
if (sameDimLvl) {
222-
child[row.fieldName] = sibling[row.fieldName];
221+
child[row.memberName] = sibling[row.memberName];
223222
}
224223
if (!child[pivotKeys.records]) {
225224
continue;
226225
}
227-
child[row.fieldName + '_' + pivotKeys.records] = [];
226+
child[row.memberName + '_' + pivotKeys.records] = [];
228227
const keys = Object.assign({}, pivotKeys) as any;
229-
keys[row.fieldName] = row.fieldName;
228+
keys[row.memberName] = row.memberName;
230229
const hierarchyFields2 = PivotUtil
231230
.getFieldsHierarchy(child[pivotKeys.records], [row], PivotDimensionType.Row, pivotKeys);
232231
const siblingData2 = PivotUtil
233232
.processHierarchy(hierarchyFields2, child ?? [], keys, 0);
234233
if (sameDimLvl) {
235234
// add children to current level if dimensions have same depth
236235
for (const sib of siblingData2) {
237-
if (sib[row.fieldName + '_' + pivotKeys.records]) {
238-
child[row.fieldName + '_' + pivotKeys.records] =
239-
child[row.fieldName + '_' + pivotKeys.records].concat(sib[row.fieldName + '_' + pivotKeys.records]);
240-
child[row.fieldName] = sib[row.fieldName];
236+
if (sib[row.memberName + '_' + pivotKeys.records]) {
237+
child[row.memberName + '_' + pivotKeys.records] =
238+
child[row.memberName + '_' + pivotKeys.records].concat(sib[row.memberName + '_' + pivotKeys.records]);
239+
child[row.memberName] = sib[row.memberName];
241240
}
242241
}
243242
} else {
244243
// otherwise overwrite direct child collection
245-
child[row.fieldName + '_' + pivotKeys.records] = siblingData2;
244+
child[row.memberName + '_' + pivotKeys.records] = siblingData2;
246245
}
247246
PivotUtil.processSiblingProperties(child, siblingData2, keys);
248247
if (prevRowDims.length > 0) {
@@ -256,7 +255,7 @@ export class PivotUtil {
256255
public static processHierarchy(hierarchies, rec, pivotKeys, level = 0, rootData = false) {
257256
const flatData = [];
258257
hierarchies.forEach((h, key) => {
259-
const field = this.resolveFieldName(h.dimension, rec);
258+
const field = h.dimension.memberName;
260259
let obj = {};
261260
obj[field] = key;
262261
if (h[pivotKeys.records]) {
@@ -319,7 +318,7 @@ export class PivotUtil {
319318
return total;
320319
}
321320

322-
public static flattenColumnHierarchy(hierarchies, values, pivotKeys) {
321+
public static flattenColumnHierarchy(hierarchies: any, values: IPivotValue[], pivotKeys: IPivotKeys) {
323322
const flatData = [];
324323
hierarchies.forEach((h, key) => {
325324
const obj = {};
@@ -350,23 +349,6 @@ export class PivotUtil {
350349
return flatData;
351350
}
352351

353-
public static resolveFieldName(dimension, record) {
354-
if (typeof dimension.member === 'string') {
355-
dimension.fieldName = dimension.member;
356-
return dimension.member;
357-
} else {
358-
const fieldName = (dimension && dimension.fieldName) ?? this.generateFieldValue(record);
359-
dimension.fieldName = fieldName;
360-
return fieldName;
361-
}
362-
}
363-
364-
private static generateFieldValue(rec) {
365-
let i = 0;
366-
while (Object.keys(rec).indexOf('field' + ++i) !== -1) { }
367-
return 'field' + i;
368-
}
369-
370352
private static collectAggregations(children, pivotKeys) {
371353
const result = [];
372354
children.forEach(value => result.push(value[pivotKeys.aggregations]));

0 commit comments

Comments
 (0)