Skip to content

Commit 7d181e8

Browse files
MKirovaMKirova
authored andcommitted
merge from base.
2 parents df13191 + 84f6675 commit 7d181e8

File tree

12 files changed

+232
-59
lines changed

12 files changed

+232
-59
lines changed

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

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ import { IgxPivotGridComponent } from '../grids/pivot-grid/pivot-grid.component'
55
import { IPivotDimension, IPivotKeys, IPivotValue, PivotDimensionType } from '../grids/pivot-grid/pivot-grid.interface';
66
import { PivotUtil } from '../grids/pivot-grid/pivot-util';
77
import { FilteringStrategy } from './filtering-strategy';
8+
import { GridColumnDataType } from './data-util';
9+
import { SortingDirection } from './sorting-expression.interface';
10+
import { DefaultSortingStrategy, ISortingStrategy } from './sorting-strategy';
11+
import { parseDate } from '../core/utils';
812

913
export interface IPivotDimensionStrategy {
1014
process(collection: any,
@@ -176,3 +180,40 @@ export class DimensionValuesFilteringStrategy extends FilteringStrategy {
176180
return PivotUtil.extractValueFromDimension(dim, rec);
177181
}
178182
}
183+
184+
export class DefaultPivotSortingStrategy extends DefaultSortingStrategy {
185+
protected static _instance: DefaultPivotSortingStrategy = null;
186+
protected dimension;
187+
public static instance(): DefaultPivotSortingStrategy {
188+
return this._instance || (this._instance = new this());
189+
}
190+
public sort(data: any[],
191+
fieldName: string,
192+
dir: SortingDirection,
193+
ignoreCase: boolean,
194+
valueResolver: (obj: any, key: string, isDate?: boolean) => any,
195+
isDate?: boolean,
196+
isTime?: boolean,
197+
grid?: GridType) {
198+
const key = fieldName;
199+
const config = (grid as any).pivotConfiguration;
200+
const allDimensions = config.rows.concat(config.columns).concat(config.filters).filter(x => x !== null);
201+
const enabledDimensions = allDimensions.filter(x => x && x.enabled);
202+
this.dimension = PivotUtil.flatten(enabledDimensions).find(x => x.memberName === key);
203+
const reverse = (dir === SortingDirection.Desc ? -1 : 1);
204+
const cmpFunc = (obj1, obj2) => this.compareObjects(obj1, obj2, key, reverse, ignoreCase, this.getFieldValue, isDate, isTime);
205+
return this.arraySort(data, cmpFunc);
206+
}
207+
208+
protected getFieldValue(obj: any, key: string, isDate: boolean = false, isTime: boolean = false): any {
209+
let resolvedValue = PivotUtil.extractValueFromDimension(this.dimension, obj);
210+
const formatAsDate = this.dimension.dataType === GridColumnDataType.Date || this.dimension.dataType === GridColumnDataType.DateTime;
211+
if (formatAsDate) {
212+
const date = parseDate(resolvedValue);
213+
resolvedValue = isTime && date ?
214+
new Date().setHours(date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds()) : date;
215+
216+
}
217+
return resolvedValue;
218+
}
219+
}

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

Lines changed: 43 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,17 @@ const TIME_TYPE = 'time';
1313
const DATE_TIME_TYPE = 'dateTime';
1414
export interface ISortingStrategy {
1515
sort: (data: any[],
16-
fieldName: string,
17-
dir: SortingDirection,
18-
ignoreCase: boolean,
19-
valueResolver: (obj: any, key: string, isDate?: boolean) => any,
20-
isDate?: boolean,
21-
isTime?: boolean) => any[];
16+
fieldName: string,
17+
dir: SortingDirection,
18+
ignoreCase: boolean,
19+
valueResolver: (obj: any, key: string, isDate?: boolean) => any,
20+
isDate?: boolean,
21+
isTime?: boolean,
22+
grid?: GridType) => any[];
2223
}
2324

2425
export class DefaultSortingStrategy implements ISortingStrategy {
25-
private static _instance: DefaultSortingStrategy = null;
26+
protected static _instance: DefaultSortingStrategy = null;
2627

2728
protected constructor() {}
2829

@@ -31,12 +32,12 @@ export class DefaultSortingStrategy implements ISortingStrategy {
3132
}
3233

3334
public sort(data: any[],
34-
fieldName: string,
35-
dir: SortingDirection,
36-
ignoreCase: boolean,
37-
valueResolver: (obj: any, key: string, isDate?: boolean) => any,
38-
isDate?: boolean,
39-
isTime?: boolean) {
35+
fieldName: string,
36+
dir: SortingDirection,
37+
ignoreCase: boolean,
38+
valueResolver: (obj: any, key: string, isDate?: boolean) => any,
39+
isDate?: boolean,
40+
isTime?: boolean) {
4041
const key = fieldName;
4142
const reverse = (dir === SortingDirection.Desc ? -1 : 1);
4243
const cmpFunc = (obj1, obj2) => this.compareObjects(obj1, obj2, key, reverse, ignoreCase, valueResolver, isDate, isTime);
@@ -65,8 +66,8 @@ export class DefaultSortingStrategy implements ISortingStrategy {
6566
valueResolver: (obj: any, key: string, isDate?: boolean, isTime?: boolean) => any,
6667
isDate: boolean,
6768
isTime: boolean) {
68-
let a = valueResolver(obj1, key, isDate, isTime);
69-
let b = valueResolver(obj2, key, isDate, isTime);
69+
let a = valueResolver.call(this, obj1, key, isDate, isTime);
70+
let b = valueResolver.call(this, obj2, key, isDate, isTime);
7071
if (ignoreCase) {
7172
a = a && a.toLowerCase ? a.toLowerCase() : a;
7273
b = b && b.toLowerCase ? b.toLowerCase() : b;
@@ -163,38 +164,17 @@ export class IgxSorting implements IGridSortingStrategy {
163164
let resolvedValue = resolveNestedPath(obj, key);
164165
if (isDate || isTime) {
165166
const date = parseDate(resolvedValue);
166-
resolvedValue = isTime && date ?
167+
resolvedValue = isTime && date ?
167168
new Date().setHours(date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds()) : date;
168169

169170
}
170171
return resolvedValue;
171172
}
172173

173-
private groupedRecordsByExpression(data: any[],
174-
index: number,
175-
expression: IGroupingExpression,
176-
isDate: boolean = false): any[] {
177-
const res = [];
178-
const key = expression.fieldName;
179-
const len = data.length;
180-
const groupval = this.getFieldValue(data[index], key, isDate);
181-
res.push(data[index]);
182-
index++;
183-
const comparer = expression.groupingComparer || DefaultSortingStrategy.instance().compareValues;
184-
for (let i = index; i < len; i++) {
185-
if (comparer(this.getFieldValue(data[i], key, isDate), groupval) === 0) {
186-
res.push(data[i]);
187-
} else {
188-
break;
189-
}
190-
}
191-
return res;
192-
}
193-
194-
private sortDataRecursive<T>(data: T[],
195-
expressions: ISortingExpression[],
196-
expressionIndex: number = 0,
197-
grid: GridType): T[] {
174+
protected sortDataRecursive<T>(data: T[],
175+
expressions: ISortingExpression[],
176+
expressionIndex: number = 0,
177+
grid: GridType): T[] {
198178
let i;
199179
let j;
200180
let gbData;
@@ -212,7 +192,7 @@ export class IgxSorting implements IGridSortingStrategy {
212192
const column = grid?.getColumnByName(expr.fieldName);
213193
const isDate = column?.dataType === DATE_TYPE || column?.dataType === DATE_TIME_TYPE;
214194
const isTime = column?.dataType === TIME_TYPE;
215-
data = expr.strategy.sort(data, expr.fieldName, expr.dir, expr.ignoreCase, this.getFieldValue, isDate, isTime);
195+
data = expr.strategy.sort(data, expr.fieldName, expr.dir, expr.ignoreCase, this.getFieldValue, isDate, isTime, grid);
216196
if (expressionIndex === exprsLen - 1) {
217197
return data;
218198
}
@@ -230,6 +210,27 @@ export class IgxSorting implements IGridSortingStrategy {
230210
}
231211
return data;
232212
}
213+
214+
private groupedRecordsByExpression(data: any[],
215+
index: number,
216+
expression: IGroupingExpression,
217+
isDate: boolean = false): any[] {
218+
const res = [];
219+
const key = expression.fieldName;
220+
const len = data.length;
221+
const groupval = this.getFieldValue(data[index], key, isDate);
222+
res.push(data[index]);
223+
index++;
224+
const comparer = expression.groupingComparer || DefaultSortingStrategy.instance().compareValues;
225+
for (let i = index; i < len; i++) {
226+
if (comparer(this.getFieldValue(data[i], key, isDate), groupval) === 0) {
227+
res.push(data[i]);
228+
} else {
229+
break;
230+
}
231+
}
232+
return res;
233+
}
233234
}
234235

235236
export class IgxDataRecordSorting extends IgxSorting {

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
class="igx-grid__scroll-on-drag-pinned" [style.left.px]="pinnedWidth"></span>
3232
<ng-template igxGridFor let-rowData [igxGridForOf]="data
3333
| pivotGridFilter:pivotConfiguration:filterStrategy:advancedFilteringExpressionsTree:filteringPipeTrigger:pipeTrigger
34+
| pivotGridSort:pivotConfiguration:sortStrategy:id:pipeTrigger
3435
| pivotGridRow:pivotConfiguration:expansionStates:pipeTrigger
3536
| pivotGridRowExpansion:pivotConfiguration:expansionStates:pipeTrigger
3637
| pivotGridColumn:pivotConfiguration:expansionStates:pipeTrigger"

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

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ import { IgxGridTransaction } from '../hierarchical-grid/public_api';
6060
import { IgxPivotFilteringService } from './pivot-filtering.service';
6161
import { DataUtil } from '../../data-operations/data-util';
6262
import { IFilteringExpressionsTree } from '../../data-operations/filtering-expressions-tree';
63+
import { SortingDirection } from '../../data-operations/sorting-expression.interface';
6364

6465
let NEXT_ID = 0;
6566
const MINIMUM_COLUMN_WIDTH = 200;
@@ -959,7 +960,17 @@ export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnIni
959960
const factoryColumn = this.resolver.resolveComponentFactory(IgxColumnComponent);
960961
const factoryColumnGroup = this.resolver.resolveComponentFactory(IgxColumnGroupComponent);
961962
let columns = [];
962-
fields.forEach((value, key) => {
963+
if (fields.size === 0) {
964+
return columns;
965+
}
966+
const first = fields.keys().next().value;
967+
const dim: IPivotDimension = fields.get(first).dimension;
968+
let currentFields = fields;
969+
if (dim && dim.sortDirection) {
970+
const reverse = (dim.sortDirection === SortingDirection.Desc ? -1 : 1);
971+
currentFields = new Map([...fields.entries()].sort((a, b) => reverse * (a > b ? 1 : a < b ? -1 : 0)));
972+
}
973+
currentFields.forEach((value, key) => {
963974
let shouldGenerate = true;
964975
if (value.dimension && value.dimension.filters) {
965976
const state = {

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { GridColumnDataType } from '../../data-operations/data-util';
22
import { FilteringExpressionsTree } from '../../data-operations/filtering-expressions-tree';
33
import { IPivotDimensionStrategy } from '../../data-operations/pivot-strategy';
44
import { IgxColumnComponent } from '../columns/column.component';
5+
import { SortingDirection } from '../../data-operations/sorting-expression.interface';
56

67
export type PivotAggregation = (members: any[], data: any[]) => any;
78

@@ -26,6 +27,8 @@ export interface IPivotDimension {
2627
enabled: boolean;
2728
// A predefined or defined via the `igxPivotSelector` filter expression tree for the current dimension to be applied in the filter pipe.
2829
filter?: FilteringExpressionsTree | null;
30+
sortDirection?: SortingDirection;
31+
dataType?: GridColumnDataType;
2932
}
3033

3134
export interface IPivotValue {

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
import { IgxPivotRowDimensionContentComponent } from './pivot-row-dimension-content.component';
@@ -19,7 +20,8 @@ import { IgxPivotRowDimensionContentComponent } from './pivot-row-dimension-cont
1920
IgxPivotRowPipe,
2021
IgxPivotRowExpansionPipe,
2122
IgxPivotColumnPipe,
22-
IgxPivotGridFilterPipe
23+
IgxPivotGridFilterPipe,
24+
IgxPivotGridSortingPipe
2325
],
2426
exports: [
2527
IgxGridModule,
@@ -30,7 +32,8 @@ import { IgxPivotRowDimensionContentComponent } from './pivot-row-dimension-cont
3032
IgxPivotRowExpansionPipe,
3133
IgxPivotRowPipe,
3234
IgxPivotColumnPipe,
33-
IgxPivotGridFilterPipe
35+
IgxPivotGridFilterPipe,
36+
IgxPivotGridSortingPipe
3437
],
3538
imports: [
3639
IgxGridModule,

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

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -506,14 +506,16 @@ describe('Pivot pipes', () => {
506506
});
507507

508508
it('transforms flat data to pivot data multiple row dimensions', () => {
509-
pivotConfig.rows = [{
510-
memberName: 'ProductCategory',
511-
enabled: true
512-
},
513-
{
514-
memberName: 'Date',
515-
enabled: true
516-
}];
509+
pivotConfig.rows = [
510+
{
511+
memberName: 'ProductCategory',
512+
enabled: true
513+
},
514+
{
515+
memberName: 'Date',
516+
enabled: true
517+
}
518+
];
517519
const rowPipeResult = rowPipe.transform(data, pivotConfig, expansionStates);
518520
const rowStatePipeResult = rowStatePipe.transform(rowPipeResult, pivotConfig, expansionStates);
519521

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

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@ import { DataUtil } from '../../data-operations/data-util';
44
import { FilteringExpressionsTree, IFilteringExpressionsTree } from '../../data-operations/filtering-expressions-tree';
55
import { IFilteringStrategy } from '../../data-operations/filtering-strategy';
66
import { IPivotConfiguration, IPivotDimension, IPivotKeys } from './pivot-grid.interface';
7-
import { DimensionValuesFilteringStrategy, PivotColumnDimensionsStrategy,
7+
import { DefaultPivotSortingStrategy, DimensionValuesFilteringStrategy, PivotColumnDimensionsStrategy,
88
PivotRowDimensionsStrategy } from '../../data-operations/pivot-strategy';
99
import { PivotUtil } from './pivot-util';
1010
import { FilteringLogic } from '../../data-operations/filtering-expression.interface';
11+
import { IGridSortingStrategy } from '../../data-operations/sorting-strategy';
12+
import { ISortingExpression, SortingDirection } from '../../data-operations/sorting-expression.interface';
1113
import { GridBaseAPIService, IgxGridBaseDirective } from '../hierarchical-grid/public_api';
1214
import { GridType } from '../common/grid.interface';
1315
/**
@@ -131,3 +133,43 @@ export class IgxPivotGridFilterPipe implements PipeTransform {
131133
return result;
132134
}
133135
}
136+
137+
/**
138+
* @hidden
139+
*/
140+
@Pipe({
141+
name: 'pivotGridSort',
142+
pure: true
143+
})
144+
export class IgxPivotGridSortingPipe implements PipeTransform {
145+
constructor(private gridAPI: GridBaseAPIService<IgxGridBaseDirective & GridType>) { }
146+
public transform(collection: any[], config: IPivotConfiguration, sorting: IGridSortingStrategy,
147+
id: string, pipeTrigger: number, pinned?): any[] {
148+
let result: any[];
149+
const allDimensions = config.rows;
150+
const enabledDimensions = allDimensions.filter(x => x && x.enabled);
151+
const expressions: ISortingExpression[] = [];
152+
PivotUtil.flatten(enabledDimensions).forEach(x => {
153+
if (x.sortDirection) {
154+
expressions.push({
155+
dir: x.sortDirection,
156+
fieldName: x.memberName,
157+
strategy: DefaultPivotSortingStrategy.instance()
158+
});
159+
} else {
160+
expressions.push({
161+
dir: SortingDirection.None,
162+
fieldName: x.memberName,
163+
strategy: DefaultPivotSortingStrategy.instance()
164+
});
165+
}
166+
});
167+
if (!expressions.length) {
168+
result = collection;
169+
} else {
170+
result = DataUtil.sort(cloneArray(collection, true), expressions, sorting, this.gridAPI.grid);
171+
}
172+
173+
return result;
174+
}
175+
}

0 commit comments

Comments
 (0)