Skip to content

Commit f61966c

Browse files
authored
Merge pull request #10146 from IgniteUI/mkirova/pivot-grid-colGeneration
Add support for members defined via custom function for rows/columns.
2 parents 291057f + 872516a commit f61966c

File tree

7 files changed

+121
-65
lines changed

7 files changed

+121
-65
lines changed

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

Lines changed: 53 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,11 @@ import { GridType } from '../common/grid.interface';
1717
import { IgxGridNavigationService } from '../grid-navigation.service';
1818
import { IgxGridCRUDService } from '../common/crud.service';
1919
import { IgxGridSummaryService } from '../summaries/grid-summary.service';
20-
import { IPivotConfiguration } from './pivot-grid.interface';
20+
import { IPivotConfiguration, IPivotDimension } from './pivot-grid.interface';
2121
import { IgxPivotHeaderRowComponent } from './pivot-header-row.component';
2222

2323
let NEXT_ID = 0;
24+
const MINIMUM_COLUMN_WIDTH = 136;
2425
@Component({
2526
changeDetection: ChangeDetectionStrategy.OnPush,
2627
preserveWhitespaces: false,
@@ -72,6 +73,7 @@ export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnIni
7273
private _data;
7374
private _filteredData;
7475
private p_id = `igx-pivot-grid-${NEXT_ID++}`;
76+
private _origData = [];
7577

7678
/**
7779
* @hidden
@@ -83,6 +85,11 @@ export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnIni
8385
super.ngOnInit();
8486
}
8587

88+
/** @hidden */
89+
public featureColumnsWidth() {
90+
return this.pivotRowWidths;
91+
}
92+
8693
/**
8794
* Gets/Sets the value of the `id` attribute.
8895
*
@@ -128,9 +135,31 @@ export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnIni
128135
* let data = this.grid.data;
129136
* ```
130137
*/
131-
public get data(): any[] | null {
138+
public get data(): any[] | null {
132139
return this._data;
133-
}
140+
}
141+
142+
/**
143+
* Returns an array of data set to the component.
144+
* ```typescript
145+
* let processedData = this.grid.processedData;
146+
* ```
147+
*/
148+
public get originalData(): any[] | null {
149+
return this._origData;
150+
}
151+
152+
153+
/**
154+
* An @Input property that lets you fill the `IgxPivotGridComponent` with an array of data.
155+
* ```html
156+
* <igx-pivot-grid [processedData]="Data"></igx-pivot-grid>
157+
* ```
158+
*/
159+
@Input()
160+
public set originalData(value: any[] | null) {
161+
this._origData = value || [];
162+
}
134163

135164
/**
136165
* Sets an array of objects containing the filtered data.
@@ -172,44 +201,31 @@ export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnIni
172201
};
173202
}
174203

175-
public get pivotRows() {
176-
// TODO - resolve member if member is not string.
177-
const rowKeys = this.pivotConfiguration.rows.map(x => x.member);
178-
const cols = this.columns.filter(x => rowKeys.indexOf(x.field) !== -1);
179-
// create copies in order to not pollute the original column.
180-
const columns = [];
181-
const topLevelCols = cols.filter(c => c.level === 0);
182-
topLevelCols.forEach((col) => {
183-
const ref = this._createColumn(col);
184-
ref.changeDetectorRef.detectChanges();
185-
columns.push(ref.instance);
186-
});
187-
return columns;
188-
}
189-
190204
public get pivotRowWidths() {
191-
let width = 0;
192-
this.pivotRows.forEach(col => {
193-
width += col.calcWidth;
194-
});
195-
return width;
196-
}
197-
198-
public get pivotColumns() {
199-
// TODO - resolve member if member is not string.
200-
const rowKeys = this.pivotConfiguration.rows.map(x => x.member);
201-
return this.columns.filter(x => rowKeys.indexOf(x.field) === -1);
205+
const rowDimCount = this.pivotConfiguration.rows.length;
206+
return MINIMUM_COLUMN_WIDTH * rowDimCount;
202207
}
203208

204-
public get unpinnedColumns(){
205-
const rowKeys = this.pivotConfiguration.rows.map(x => x.member);
206-
const cols = this._unpinnedColumns.filter(x => rowKeys.indexOf(x.field) === -1);
207-
return cols;
209+
// TODO: should work on original data, before pipes.
210+
// That should be data, but for this poc since we have no pipes use a different prop.
211+
protected generateDataFields(data: any[]): string[] {
212+
let fields = new Map<string, string>();
213+
for (const rec of this.originalData) {
214+
const vals = this.extractValuesFromDimension(this.pivotConfiguration.columns, rec);
215+
for (const val of vals) {
216+
fields = fields.set(val, val);
217+
}
218+
}
219+
const keys = Array.from(fields.keys());
220+
return keys;
208221
}
209222

210-
public get pinnedColumns(){
211-
const rowKeys = this.pivotConfiguration.rows.map(x => x.member);
212-
const cols = this._pinnedColumns.filter(x => rowKeys.indexOf(x.field) === -1);
213-
return cols;
223+
private extractValuesFromDimension(dims: IPivotDimension[], recData: any){
224+
const vals = [];
225+
for (const col of dims) {
226+
const value = typeof col.member === 'string' ? recData[col.member] : col.member.call(this, recData);
227+
vals.push(value);
228+
}
229+
return vals;
214230
}
215231
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
<!-- Column headers area -->
55
<div class="igx-grid__tr" role="row" [style.width.px]="width">
66

7-
<ng-container *ngIf="grid.pivotConfiguration?.rows.length > 0 ">
8-
<div #pivotContainer class="igx-grid__tr-action" [style.min-width] = "grid.pivotRowWidths"
7+
<ng-container *ngIf="!row">
8+
<div #pivotContainer class="igx-grid__tr-action" [style.min-width.px] = "grid.pivotRowWidths"
99
(pointerdown)="$event.preventDefault()">
1010

1111
</div>

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import {
22
ChangeDetectionStrategy,
3-
Component
3+
Component,
4+
Input
45
} from '@angular/core';
56
import { IgxGridHeaderRowComponent } from '../headers/grid-header-row.component';
7+
import { IgxPivotRowComponent } from './pivot-row.component';
68

79
export interface IgxGridRowSelectorsTemplateContext {
810
$implicit: {
@@ -27,4 +29,6 @@ export interface IgxGridRowSelectorsTemplateContext {
2729
templateUrl: './pivot-header-row.component.html'
2830
})
2931
export class IgxPivotHeaderRowComponent extends IgxGridHeaderRowComponent {
32+
@Input()
33+
public row: IgxPivotRowComponent;
3034
}

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
<!-- Row Dimension -->
2-
<div #rowDimension>
3-
<!-- TODO: Render headers based on hierarchy here -->
4-
<igx-grid-header-row class="igx-grid-thead" tabindex="0"
2+
<div #rowDimensionContainer>
3+
<igx-pivot-header-row class="igx-grid-thead" tabindex="0"
54
[grid]="grid"
65
[hasMRL]="grid.hasColumnLayouts"
76
[density]="grid.displayDensity"
87
[activeDescendant]="grid.activeDescendant"
9-
[width]="getRowColumnWidth(grid.pivotRows)"
10-
[unpinnedColumnCollection]="getRowColumns(rowData, grid.pivotRows)"
8+
[width]="grid.pivotRowWidths"
9+
[unpinnedColumnCollection]="rowDimension"
1110
(scroll)="grid.preventHeaderScroll($event)"
11+
[row]="this"
1212
>
13-
</igx-grid-header-row>
13+
</igx-pivot-header-row>
1414
</div>
1515

1616

Lines changed: 45 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,41 @@
11
import {
22
ChangeDetectionStrategy,
3+
ChangeDetectorRef,
34
Component,
4-
forwardRef
5+
ComponentFactoryResolver,
6+
ElementRef,
7+
forwardRef,
8+
OnInit,
9+
ViewContainerRef
510
} from '@angular/core';
611
import { IgxPivotGridComponent } from './pivot-grid.component';
712
import { IgxRowDirective } from '../row.directive';
8-
import { IgxColumnComponent } from '../hierarchical-grid/public_api';
13+
import { GridBaseAPIService, IgxColumnComponent } from '../hierarchical-grid/public_api';
14+
import { IgxGridSelectionService } from '../selection/selection.service';
915

16+
17+
const MINIMUM_COLUMN_WIDTH = 136;
1018
@Component({
1119
changeDetection: ChangeDetectionStrategy.OnPush,
1220
selector: 'igx-pivot-row',
1321
templateUrl: './pivot-row.component.html',
1422
providers: [{ provide: IgxRowDirective, useExisting: forwardRef(() => IgxPivotRowComponent) }]
1523
})
16-
export class IgxPivotRowComponent extends IgxRowDirective<IgxPivotGridComponent> {
24+
export class IgxPivotRowComponent extends IgxRowDirective<IgxPivotGridComponent> implements OnInit {
25+
26+
27+
public rowDimension: IgxColumnComponent[] = [];
28+
29+
constructor(
30+
public gridAPI: GridBaseAPIService<IgxPivotGridComponent>,
31+
public selectionService: IgxGridSelectionService,
32+
public element: ElementRef<HTMLElement>,
33+
public cdr: ChangeDetectorRef,
34+
protected resolver: ComponentFactoryResolver,
35+
protected viewRef: ViewContainerRef
36+
){
37+
super(gridAPI, selectionService, element, cdr);
38+
}
1739

1840
/**
1941
* @hidden
@@ -23,22 +45,28 @@ export class IgxPivotRowComponent extends IgxRowDirective<IgxPivotGridComponent>
2345
return this.index;
2446
}
2547

26-
public getRowColumns(rowData, cols: IgxColumnComponent[]) {
27-
cols.forEach(col => {
28-
col.header = rowData[col.field];
29-
col.field = rowData[col.field];
30-
col.title = rowData[col.field];
31-
(col as any)._vIndex = this.grid.columns.length + this.index;
32-
});
33-
return cols;
48+
public ngOnInit() {
49+
// generate rowDimension
50+
const rowDimConfig = this.grid.pivotConfiguration.rows;
51+
let field = null;
52+
for (const dim of rowDimConfig) {
53+
if (typeof dim.member === 'string') {
54+
field = this.rowData[dim.member];
55+
} else if (typeof dim.member === 'function'){
56+
field = dim.member.call(this, this.rowData);
57+
}
58+
const col = this._createColComponent(field);
59+
this.rowDimension.push(col);
60+
}
3461
}
3562

36-
public getRowColumnWidth(cols: IgxColumnComponent[]) {
37-
let width = 0;
38-
cols.forEach(col => {
39-
width += col.calcWidth;
40-
});
41-
return width;
63+
protected _createColComponent(field: string) {
64+
const factoryColumn = this.resolver.resolveComponentFactory(IgxColumnComponent);
65+
const ref = this.viewRef.createComponent(factoryColumn, null, this.viewRef.injector);
66+
ref.instance.field = field;
67+
ref.instance.width = MINIMUM_COLUMN_WIDTH + 'px';
68+
(ref as any).instance._vIndex = this.grid.columns.length + this.index;
69+
return ref.instance;
4270
}
4371
}
4472

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]="data" [pivotConfiguration]="pivotConfig">
2+
<igx-pivot-grid #grid1 [data]="data" [originalData]="origData" [pivotConfiguration]="pivotConfig">
33
</igx-pivot-grid>
44
</div>

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export class PivotGridSampleComponent {
1919
childLevels:[]
2020
}],
2121
rows: [{
22-
member: 'ProductCategory',
22+
member: (data) => data.ProductCategory,
2323
enabled: true,
2424
childLevels:[]
2525
}],
@@ -50,4 +50,12 @@ export class PivotGridSampleComponent {
5050
{ ProductCategory: 'Accessories', USA: 293 },
5151
{ ProductCategory: 'Components', USA: 240 }
5252
];
53+
54+
public dataHierarchical = [
55+
{ ProductCategory: 'All', Bulgaria: 774, USA: 829, Uruguay: 524 },
56+
{ ProductCategory: 'Clothing', Bulgaria: 774, USA: 296, Uruguay: 456 },
57+
{ ProductCategory: 'Bikes', Uruguay: 68 },
58+
{ ProductCategory: 'Accessories', USA: 293 },
59+
{ ProductCategory: 'Components', USA: 240 }
60+
];
5361
}

0 commit comments

Comments
 (0)