igniteui-angular-sovn
Version:
Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps
191 lines (167 loc) • 7.95 kB
text/typescript
import { ColumnType, PivotGridType } from '../grids/common/grid.interface';
import { DEFAULT_PIVOT_KEYS, IPivotDimension, IPivotDimensionStrategy, IPivotGridRecord, IPivotKeys, IPivotValue, PivotDimensionType } from '../grids/pivot-grid/pivot-grid.interface';
import { PivotUtil } from '../grids/pivot-grid/pivot-util';
import { FilteringStrategy, IgxFilterItem } from './filtering-strategy';
import { cloneArray } from '../core/utils';
import { IFilteringExpressionsTree } from './filtering-expressions-tree';
import { IDataCloneStrategy } from './data-clone-strategy';
export class NoopPivotDimensionsStrategy implements IPivotDimensionStrategy {
private static _instance: NoopPivotDimensionsStrategy = null;
public static instance() {
return this._instance || (this._instance = new NoopPivotDimensionsStrategy());
}
public process(collection: any[], _: IPivotDimension[], __: IPivotValue[]): any[] {
return collection;
}
}
export class PivotRowDimensionsStrategy implements IPivotDimensionStrategy {
private static _instance: PivotRowDimensionsStrategy = null;
public static instance() {
return this._instance || (this._instance = new PivotRowDimensionsStrategy());
}
public process(
collection: any,
rows: IPivotDimension[],
values: IPivotValue[],
cloneStrategy: IDataCloneStrategy,
pivotKeys: IPivotKeys = DEFAULT_PIVOT_KEYS,
): IPivotGridRecord[] {
let hierarchies;
let data: IPivotGridRecord[];
const prevRowDims = [];
const currRows = cloneArray(rows, true);
PivotUtil.assignLevels(currRows);
if (currRows.length === 0) {
hierarchies = PivotUtil.getFieldsHierarchy(collection, [{ memberName: '', enabled: true }], PivotDimensionType.Row, pivotKeys, cloneStrategy);
// generate flat data from the hierarchies
data = PivotUtil.processHierarchy(hierarchies, pivotKeys, 0, true);
return data;
}
for (const row of currRows) {
if (!data) {
// build hierarchies - groups and subgroups
hierarchies = PivotUtil.getFieldsHierarchy(collection, [row], PivotDimensionType.Row, pivotKeys, cloneStrategy);
// generate flat data from the hierarchies
data = PivotUtil.processHierarchy(hierarchies, pivotKeys, 0, true);
prevRowDims.push(row);
} else {
PivotUtil.processGroups(data, row, pivotKeys, cloneStrategy);
}
}
return data;
}
}
export class PivotColumnDimensionsStrategy implements IPivotDimensionStrategy {
private static _instance: PivotRowDimensionsStrategy = null;
public static instance() {
return this._instance || (this._instance = new PivotColumnDimensionsStrategy());
}
public process(
collection: IPivotGridRecord[],
columns: IPivotDimension[],
values: IPivotValue[],
cloneStrategy: IDataCloneStrategy,
pivotKeys: IPivotKeys = DEFAULT_PIVOT_KEYS
): any[] {
const res = this.processHierarchy(collection, columns, values, pivotKeys, cloneStrategy);
return res;
}
private processHierarchy(collection: IPivotGridRecord[], columns: IPivotDimension[], values, pivotKeys, cloneStrategy) {
const result: IPivotGridRecord[] = [];
collection.forEach(rec => {
// apply aggregations based on the created groups and generate column fields based on the hierarchies
this.groupColumns(rec, columns, values, pivotKeys, cloneStrategy);
result.push(rec);
});
return result;
}
private groupColumns(rec: IPivotGridRecord, columns, values, pivotKeys, cloneStrategy) {
const children = rec.children;
if (children && children.size > 0) {
children.forEach((childRecs) => {
if (childRecs) {
childRecs.forEach(child => {
this.groupColumns(child, columns, values, pivotKeys, cloneStrategy);
})
}
});
}
this.applyAggregates(rec, columns, values, pivotKeys, cloneStrategy);
}
private applyAggregates(rec, columns, values, pivotKeys, cloneStrategy) {
const leafRecords = this.getLeafs(rec.records, pivotKeys);
const hierarchy = PivotUtil.getFieldsHierarchy(leafRecords, columns, PivotDimensionType.Column, pivotKeys, cloneStrategy);
PivotUtil.applyAggregations(rec, hierarchy, values, pivotKeys)
}
private getLeafs(records, pivotKeys) {
let leafs = [];
for (const rec of records) {
if (rec[pivotKeys.records]) {
leafs = leafs.concat(this.getLeafs(rec[pivotKeys.records], pivotKeys));
} else {
leafs.push(rec);
}
}
return leafs;
}
}
export class DimensionValuesFilteringStrategy extends FilteringStrategy {
/**
* Creates a new instance of FormattedValuesFilteringStrategy.
*
* @param fields An array of column field names that should be formatted.
* If omitted the values of all columns which has formatter will be formatted.
*/
constructor(private fields?: string[]) {
super();
}
protected override getFieldValue(rec: any, fieldName: string, _isDate = false, _isTime = false,
grid?: PivotGridType): any {
const allDimensions = grid.allDimensions;
const enabledDimensions = allDimensions.filter(x => x && x.enabled);
const dim :IPivotDimension = PivotUtil.flatten(enabledDimensions).find(x => x.memberName === fieldName);
const value = dim.childLevel ? this._getDimensionValueHierarchy(dim, rec).map(x => `[` + x +`]`).join('.') : PivotUtil.extractValueFromDimension(dim, rec);
return value;
}
public override getFilterItems(column: ColumnType, tree: IFilteringExpressionsTree): Promise<IgxFilterItem[]> {
const grid = (column.grid as any);
const enabledDimensions = grid.allDimensions.filter(x => x && x.enabled);
const data = column.grid.gridAPI.filterDataByExpressions(tree);
const dim = enabledDimensions.find(x => x.memberName === column.field);
const allValuesHierarchy = PivotUtil.getFieldsHierarchy(
data,
[dim],
PivotDimensionType.Column,
grid.pivotKeys,
grid.pivotValueCloneStrategy
);
const isNoop = grid.pivotConfiguration.columnStrategy instanceof NoopPivotDimensionsStrategy || grid.pivotConfiguration.rowStrategy instanceof NoopPivotDimensionsStrategy;
const items: IgxFilterItem[] = !isNoop ? this._getFilterItems(allValuesHierarchy, grid.pivotKeys) : [{value : ''}];
return Promise.resolve(items);
}
private _getFilterItems(hierarchy: Map<string, any>, pivotKeys: IPivotKeys) : IgxFilterItem[] {
const items: IgxFilterItem[] = [];
hierarchy.forEach((value) => {
const val = value.value;
const path = val.split(pivotKeys.columnDimensionSeparator);
const hierarchicalValue = path.length > 1 ? path.map(x => `[` + x +`]`).join('.') : val;
const text = path[path.length -1];
items.push({
value: hierarchicalValue,
label: text,
children: this._getFilterItems(value.children, pivotKeys)
});
});
return items;
}
private _getDimensionValueHierarchy(dim: IPivotDimension, rec: any) : string[] {
let path = [];
const value = PivotUtil.extractValueFromDimension(dim, rec);
path.push(value);
if (dim.childLevel) {
const childVals = this._getDimensionValueHierarchy(dim.childLevel, rec);
path = path.concat(childVals);
}
return path;
}
}