diff --git a/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-data-selector.component.ts b/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-data-selector.component.ts index e72a2b1b52c..52ce5e82670 100644 --- a/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-data-selector.component.ts +++ b/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-data-selector.component.ts @@ -47,6 +47,7 @@ import { IgxIconComponent } from "../../icon/icon.component"; import { IgxInputGroupComponent } from "../../input-group/input-group.component"; import { fadeIn, fadeOut } from 'igniteui-angular/animations'; import { Size } from '../common/enums'; +import { GridColumnDataType } from '../../data-operations/data-util'; interface IDataSelectorPanel { name: string; @@ -541,8 +542,13 @@ export class IgxPivotDataSelectorComponent { * @internal */ public onAggregationChange(event: ISelectionEventArgs) { + if (!this.isSelected(event.newSelection.value)) { this.value.aggregate = event.newSelection.value; + const isSingleValue = this.grid.values.length === 1; + + PivotUtil.updateColumnTypeByAggregator(this.grid.columns, this.value, isSingleValue); + this.grid.pipeTrigger++; this.grid.cdr.markForCheck(); } diff --git a/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-grid.component.ts b/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-grid.component.ts index 5eb3a803e22..7c7d2d2aab2 100644 --- a/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-grid.component.ts +++ b/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-grid.component.ts @@ -31,12 +31,12 @@ import { } from '@angular/core'; import { DOCUMENT, NgTemplateOutlet, NgClass, NgStyle } from '@angular/common'; -import { first, take, takeUntil} from 'rxjs/operators'; +import { first, take, takeUntil } from 'rxjs/operators'; import { IgxGridBaseDirective } from '../grid-base.directive'; import { IgxFilteringService } from '../filtering/grid-filtering.service'; import { IgxGridSelectionService } from '../selection/selection.service'; import { IgxForOfSyncService, IgxForOfScrollSyncService } from '../../directives/for-of/for_of.sync.service'; -import { ColumnType, GridType, IGX_GRID_BASE, IGX_GRID_SERVICE_BASE, IgxColumnTemplateContext, RowType } from '../common/grid.interface'; +import { ColumnType, GridType, IGX_GRID_BASE, IGX_GRID_SERVICE_BASE, IgxColumnTemplateContext, PivotGridType, RowType } from '../common/grid.interface'; import { IgxGridCRUDService } from '../common/crud.service'; import { IgxGridSummaryService } from '../summaries/grid-summary.service'; import { DEFAULT_PIVOT_KEYS, IDimensionsChange, IgxPivotGridValueTemplateContext, IPivotConfiguration, IPivotConfigurationChangedEventArgs, IPivotDimension, IPivotValue, IValuesChange, PivotDimensionType, IPivotUISettings, PivotRowLayoutType, PivotSummaryPosition } from './pivot-grid.interface'; @@ -71,7 +71,7 @@ import { IgxPivotColumnResizingService } from '../resizing/pivot-grid/pivot-resi import { IgxFlatTransactionFactory, IgxOverlayService, State, Transaction, TransactionService } from '../../services/public_api'; import { cloneArray, PlatformUtil, resizeObservable } from '../../core/utils'; import { IgxPivotFilteringService } from './pivot-filtering.service'; -import { DataUtil } from '../../data-operations/data-util'; +import { DataUtil, GridColumnDataType } from '../../data-operations/data-util'; import { IFilteringExpressionsTree } from '../../data-operations/filtering-expressions-tree'; import { IgxGridTransaction } from '../common/types'; import { GridBaseAPIService } from '../api.service'; @@ -197,7 +197,7 @@ const MINIMUM_COLUMN_WIDTH_SUPER_COMPACT = 104; schemas: [CUSTOM_ELEMENTS_SCHEMA] }) export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnInit, AfterContentInit, - GridType, AfterViewInit, OnChanges { + PivotGridType, AfterViewInit, OnChanges { /** * Emitted when the dimension collection is changed via the grid chip area. @@ -1665,7 +1665,7 @@ export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnIni public autoSizeRowDimension(dimension: IPivotDimension) { if (this.getDimensionType(dimension) === PivotDimensionType.Row) { const relatedDims: string[] = PivotUtil.flatten([dimension]).map((x: IPivotDimension) => x.memberName); - const contentCollection = this.getContentCollection(dimension); + const contentCollection = this.getContentCollection(dimension); const content = contentCollection.filter(x => relatedDims.indexOf(x.dimension.memberName) !== -1); const headers = content.map(x => x.headerGroups.toArray()).flat().map(x => x.header && x.header.refInstance); if (this.pivotUI.showRowHeaders) { @@ -1939,8 +1939,8 @@ export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnIni */ public getRowDimensionByName(memberName: string) { const visibleRows = this.pivotUI.rowLayout === PivotRowLayoutType.Vertical ? - this.pivotConfiguration.rows : - PivotUtil.flatten(this.pivotConfiguration.rows); + this.pivotConfiguration.rows : + PivotUtil.flatten(this.pivotConfiguration.rows); const dimIndex = visibleRows.findIndex((target) => target.memberName === memberName); const dim = visibleRows[dimIndex]; return dim; @@ -2264,7 +2264,7 @@ export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnIni const separator = this.pivotKeys.columnDimensionSeparator; const dataArr = fields.map(x => x.split(separator)).sort(x => x.length); const hierarchy = new Map(); - const columnDimensions = PivotUtil.flatten(this.columnDimensions); + const columnDimensions = PivotUtil.flatten(this.columnDimensions); dataArr.forEach(arr => { let currentHierarchy = hierarchy; const path = []; @@ -2284,17 +2284,22 @@ export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnIni }); return hierarchy; } - protected generateColumnHierarchy(fields: Map, data, parent = null): IgxColumnComponent[] { let columns = []; if (fields.size === 0) { this.values.forEach((value) => { const ref = createComponent(IgxColumnComponent, { environmentInjector: this.envInjector, elementInjector: this.injector }); + let columnDataType = value.dataType || this.resolveDataTypes(data.length ? data[0][value.member] : null); + + if (value.aggregate?.key?.toLowerCase() === 'count' && (columnDataType === GridColumnDataType.Currency || columnDataType == GridColumnDataType.Percent)) { + columnDataType = GridColumnDataType.Number; + } + ref.instance.header = value.displayName; ref.instance.field = value.member; ref.instance.parent = parent; ref.instance.sortable = true; - ref.instance.dataType = value.dataType || this.resolveDataTypes(data.length ? data[0][value.member] : null); + ref.instance.dataType = columnDataType; ref.instance.formatter = value.formatter; columns.push(ref.instance); }); @@ -2308,9 +2313,20 @@ export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnIni } if (shouldGenerate && (value.children == null || value.children.length === 0 || value.children.size === 0)) { const col = this.createColumnForDimension(value, data, parent, this.hasMultipleValues); + + if (!this.hasMultipleValues && this.values.length > 0) { + PivotUtil.updateColumnTypeByAggregator([col], this.values[0], true); + } + columns.push(col); if (this.hasMultipleValues) { const measureChildren = this.getMeasureChildren(data, col, false, value.dimension.width); + + measureChildren.forEach((child, index) => { + const pivotValue = this.values[index]; + PivotUtil.updateColumnTypeByAggregator([child], pivotValue, this.values.length === 1); + }); + col.children.reset(measureChildren); columns = columns.concat(measureChildren); } @@ -2380,20 +2396,20 @@ export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnIni }; values.push(value); break; - } - case "date": - { - const dimension: IPivotDimension = new IgxPivotDateDimension( + } + case "date": { - memberName: field, - enabled: isFirstDate, - dataType: dataType + const dimension: IPivotDimension = new IgxPivotDateDimension( + { + memberName: field, + enabled: isFirstDate, + dataType: dataType + } + ) + rowDimensions.push(dimension); + isFirstDate = false; + break; } - ) - rowDimensions.push(dimension); - isFirstDate = false; - break; - } default: { const dimension: IPivotDimension = { memberName: field, diff --git a/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-header-row.component.ts b/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-header-row.component.ts index c59f905be90..d2510db1ac2 100644 --- a/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-header-row.component.ts +++ b/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-header-row.component.ts @@ -38,6 +38,7 @@ import { IgxDropDirective } from '../../directives/drag-drop/drag-drop.directive import { NgTemplateOutlet, NgClass, NgStyle } from '@angular/common'; import { IgxPivotRowHeaderGroupComponent } from './pivot-row-header-group.component'; import { IgxPivotRowDimensionHeaderGroupComponent } from './pivot-row-dimension-header-group.component'; +import { GridColumnDataType } from '../../data-operations/data-util'; /** * @@ -137,7 +138,7 @@ export class IgxPivotHeaderRowComponent extends IgxGridHeaderRowComponent implem @Inject(IGX_GRID_BASE) public override grid: PivotGridType, ref: ElementRef, cdr: ChangeDetectorRef, - protected renderer: Renderer2, + protected renderer: Renderer2 ) { super(ref, cdr); } @@ -407,8 +408,13 @@ export class IgxPivotHeaderRowComponent extends IgxGridHeaderRowComponent implem * @internal */ public onAggregationChange(event: ISelectionEventArgs) { + if (!this.isSelected(event.newSelection.value)) { this.value.aggregate = event.newSelection.value; + const isSingleValue = this.grid.values.length === 1; + + PivotUtil.updateColumnTypeByAggregator(this.grid.columns, this.value, isSingleValue); + this.grid.pipeTrigger++; } } diff --git a/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-util.ts b/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-util.ts index e4624251ca2..cd73c2360ed 100644 --- a/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-util.ts +++ b/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-util.ts @@ -3,7 +3,7 @@ import { DataUtil, GridColumnDataType } from '../../data-operations/data-util'; import { FilteringLogic } from '../../data-operations/filtering-expression.interface'; import { FilteringExpressionsTree } from '../../data-operations/filtering-expressions-tree'; import { ISortingExpression } from '../../data-operations/sorting-strategy'; -import { PivotGridType } from '../common/grid.interface'; +import { ColumnType, PivotGridType } from '../common/grid.interface'; import { IGridSortingStrategy, IgxSorting } from '../common/strategy'; import { IgxPivotAggregate, IgxPivotDateAggregate, IgxPivotNumericAggregate, IgxPivotTimeAggregate } from './pivot-grid-aggregate'; import { IPivotAggregator, IPivotConfiguration, IPivotDimension, IPivotGridRecord, IPivotKeys, IPivotValue, PivotDimensionType, PivotSummaryPosition } from './pivot-grid.interface'; @@ -88,13 +88,13 @@ export class PivotUtil { } public static flattenGroupsHorizontally(data: IPivotGridRecord[], - dimension: IPivotDimension, - expansionStates, - defaultExpand: boolean, - visibleDimensions: IPivotDimension[], - summariesPosition: PivotSummaryPosition, - parent?: IPivotDimension, - parentRec?: IPivotGridRecord) { + dimension: IPivotDimension, + expansionStates, + defaultExpand: boolean, + visibleDimensions: IPivotDimension[], + summariesPosition: PivotSummaryPosition, + parent?: IPivotDimension, + parentRec?: IPivotGridRecord) { for (let i = 0; i < data.length; i++) { const rec = data[i]; const field = dimension.memberName; @@ -316,7 +316,7 @@ export class PivotUtil { const aggregationKey = groupName ? groupName + pivotKeys.columnDimensionSeparator + key : key; rec.aggregationValues.set(aggregationKey, aggregationData[key]); }); - } else if (aggregationKeys.length === 1) { + } else if (aggregationKeys.length === 1) { const aggregationKey = aggregationKeys[0]; rec.aggregationValues.set(groupName || aggregationKey, aggregationData[aggregationKey]); } @@ -508,5 +508,24 @@ export class PivotUtil { } } + public static updateColumnTypeByAggregator(columns: any[], value: IPivotValue, isSingleValue: boolean): void { + const targetColumnType = PivotUtil.getColumnDataTypeForValue(value); + columns.forEach(column => { + if ((column.field?.includes(value.member) || isSingleValue) && targetColumnType !== undefined) { + column.dataType = targetColumnType; + } + }) + } + + private static getColumnDataTypeForValue(value: IPivotValue): GridColumnDataType { + const isCountAggregator = value.aggregate.aggregator?.name?.toLowerCase() === 'count' || value.aggregate.aggregatorName?.toLowerCase() === 'count'; + if ((value.dataType === GridColumnDataType.Currency || value.dataType === GridColumnDataType.Percent) && isCountAggregator) { + return GridColumnDataType.Number; + } else if (value.dataType === GridColumnDataType.Currency && !isCountAggregator) { + return GridColumnDataType.Currency; + } else if (value.dataType === GridColumnDataType.Percent && !isCountAggregator) { + return GridColumnDataType.Percent; + } + } }