Skip to content

fix(pivot-grid): Handle currency pivot values with count aggregator - 19.2.x #15428

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: 19.2.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1338,6 +1338,8 @@ export interface PivotGridType extends GridType {
excelStyleFilterMinHeight: string;
valueChipTemplate: TemplateRef<any>;
rowDimensionHeaderTemplate: TemplateRef<IgxColumnTemplateContext>;
/** @hidden @internal */
currencyColumnSet: Set<string>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to store the current currency columns? It doesn't seem to matter what their individual dataType is as we need to change them all anyway based on the IPivotValue's dataType and current selected aggregator.

  • pivot value with dataType = "currency" + selected aggregator with aggregatorName: "COUNT" => All columns associated with it need to set dataType = "number" (doesn't matter what their state was before that).

  • pivot value with dataType = "currency" + selected aggregator with aggregatorName: "Not COUNT"=> All columns associated with it need to set dataType = "currency" (doesn't matter what their state was before that).

Also there's a third numeric data type: GridColumnDataType.Percent which we should also consider. It should also change the column types to number for Count.

}

export interface GridSVGIcon {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -517,13 +518,51 @@ export class IgxPivotDataSelectorComponent {
* @internal
*/
public onAggregationChange(event: ISelectionEventArgs) {

if (!this.isSelected(event.newSelection.value)) {
this.value.aggregate = event.newSelection.value;

this.handleCountAggregator();

this.grid.pipeTrigger++;
this.grid.cdr.markForCheck();
}
}

private handleCountAggregator() {
const valueMember = this.value.member;
const columns = this.grid.columns;
const isCountAggregator = this.value.aggregate.key.toLowerCase() === 'count';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The key is user set and will not necessarily match with count. Would be better to check aggregatorName or the actual aggregator.

const isSingleValue = this.grid.values.length === 1;
let shouldRemoveFromSet: boolean = false;

columns.forEach(column => {
const isRelevantColumn = column.field?.includes(valueMember);
const isCurrencyColumn = column.dataType === GridColumnDataType.Currency;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't care about the individual columns dataType. Just if the value's dataType is currency or percent.

  • If it is and has count aggregator -> all column become number.
  • If it does not have a count aggregator -> all columns become currency.

No need to store and manage column state.


if (isSingleValue) {
if (isCountAggregator && isCurrencyColumn) {
column.dataType = GridColumnDataType.Number;
this.grid.currencyColumnSet.add(valueMember);
} else if (this.grid.currencyColumnSet.has(valueMember)) {
column.dataType = GridColumnDataType.Currency;
}
} else if (isRelevantColumn) {
if (isCountAggregator && isCurrencyColumn) {
column.dataType = GridColumnDataType.Number;
this.grid.currencyColumnSet.add(valueMember);
} else if (this.grid.currencyColumnSet.has(valueMember)) {
column.dataType = GridColumnDataType.Currency;
shouldRemoveFromSet = true;
}
}
});

if (shouldRemoveFromSet) {
this.grid.currencyColumnSet.delete(valueMember);
}
}

/**
* @hidden
* @internal
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ 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, IgxColumnTemplateContext, RowType } from '../common/grid.interface';
import { ColumnType, GridType, IGX_GRID_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';
Expand Down Expand Up @@ -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';
Expand Down Expand Up @@ -196,7 +196,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.
Expand Down Expand Up @@ -2275,16 +2275,25 @@ export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnIni
return hierarchy;
}

/** @hidden @internal */
public currencyColumnSet: Set<string> = new Set();
protected generateColumnHierarchy(fields: Map<string, any>, 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) {
this.currencyColumnSet.add(value.member);
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);
});
Expand All @@ -2298,9 +2307,35 @@ 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);

this.values.forEach((aggregatorValue) => {
if (col.dataType === GridColumnDataType.Currency && aggregatorValue.aggregate?.key?.toLowerCase() === 'count') {
col.dataType = GridColumnDataType.Number;
this.currencyColumnSet.add(aggregatorValue.member);
} else if (this.currencyColumnSet.has(aggregatorValue.member) && aggregatorValue.aggregate?.key?.toLowerCase() !== 'count') {
col.dataType = GridColumnDataType.Currency;
this.currencyColumnSet.delete(aggregatorValue.member);
}
})

columns.push(col);
if (this.hasMultipleValues) {
const measureChildren = this.getMeasureChildren(data, col, false, value.dimension.width);

measureChildren.forEach((child) => {
this.values.forEach((aggregatorValue) => {
if (child.field.includes(aggregatorValue.member)) {
if (child.dataType === GridColumnDataType.Currency && aggregatorValue.aggregate?.key?.toLowerCase() === 'count') {
child.dataType = GridColumnDataType.Number;
this.currencyColumnSet.add(aggregatorValue.member);
} else if (this.currencyColumnSet.has(aggregatorValue.member) && aggregatorValue.aggregate?.key?.toLowerCase() !== 'count') {
child.dataType = GridColumnDataType.Currency;
this.currencyColumnSet.delete(aggregatorValue.member);
}
}
})
})

col.children.reset(measureChildren);
columns = columns.concat(measureChildren);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';

/**
*
Expand Down Expand Up @@ -138,7 +139,7 @@ export class IgxPivotHeaderRowComponent extends IgxGridHeaderRowComponent implem
@Inject(IGX_GRID_BASE) public override grid: PivotGridType,
ref: ElementRef<HTMLElement>,
cdr: ChangeDetectorRef,
protected renderer: Renderer2,
protected renderer: Renderer2
) {
super(ref, cdr);
}
Expand Down Expand Up @@ -408,12 +409,50 @@ export class IgxPivotHeaderRowComponent extends IgxGridHeaderRowComponent implem
* @internal
*/
public onAggregationChange(event: ISelectionEventArgs) {

if (!this.isSelected(event.newSelection.value)) {
this.value.aggregate = event.newSelection.value;

this.handleCountAggregator();

this.grid.pipeTrigger++;
}
}

private handleCountAggregator() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a method with the same name and same code in the pivot selector. Perhaps set it somewhere where it can be re-used. Maybe in the pivot grid component since both should have access to it or in as a common util function?

const valueMember = this.value.member;
const columns = this.grid.columns;
const isCountAggregator = this.value.aggregate.key.toLowerCase() === 'count';
const isSingleValue = this.grid.values.length === 1;
let shouldRemoveFromSet: boolean = false;

columns.forEach(column => {
const isRelevantColumn = column.field?.includes(valueMember);
const isCurrencyColumn = column.dataType === GridColumnDataType.Currency;

if (isSingleValue) {
if (isCountAggregator && isCurrencyColumn) {
column.dataType = GridColumnDataType.Number;
this.grid.currencyColumnSet.add(valueMember);
} else if (this.grid.currencyColumnSet.has(valueMember)) {
column.dataType = GridColumnDataType.Currency;
}
} else if (isRelevantColumn) {
if (isCountAggregator && isCurrencyColumn) {
column.dataType = GridColumnDataType.Number;
this.grid.currencyColumnSet.add(valueMember);
} else if (this.grid.currencyColumnSet.has(valueMember)) {
column.dataType = GridColumnDataType.Currency;
shouldRemoveFromSet = true;
}
}
});

if (shouldRemoveFromSet) {
this.grid.currencyColumnSet.delete(valueMember);
}
}

/**
* @hidden
* @internal
Expand Down