Skip to content

Commit 30f1bbb

Browse files
authored
Merge pull request #10814 from IgniteUI/mkirova/autoSize-RowDimension
feat(igxPivot): Add API to auto-size the row dimension header cells b…
2 parents d2ad25b + 9af80c8 commit 30f1bbb

10 files changed

+116
-23
lines changed

projects/igniteui-angular/src/lib/grids/columns/column.component.ts

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2312,23 +2312,7 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy
23122312
* Returns the width and padding of a header cell.
23132313
*/
23142314
public getHeaderCellWidths() {
2315-
const range = this.grid.document.createRange();
2316-
2317-
// We do not cover cases where there are children with width 100% and etc,
2318-
// because then we try to get new column size, based on header content, which is sized based on column size...
2319-
const headerWidth = this.platform.getNodeSizeViaRange(range,
2320-
this.headerCell.nativeElement,
2321-
this.headerGroup.nativeElement);
2322-
2323-
const headerStyle = this.grid.document.defaultView.getComputedStyle(this.headerCell.nativeElement);
2324-
const headerPadding = parseFloat(headerStyle.paddingLeft) + parseFloat(headerStyle.paddingRight) +
2325-
parseFloat(headerStyle.borderRightWidth);
2326-
2327-
// Take into consideration the header group element, since column pinning applies borders to it if its not a columnGroup.
2328-
const headerGroupStyle = this.grid.document.defaultView.getComputedStyle(this.headerGroup.nativeElement);
2329-
const borderSize = !this.parent ? parseFloat(headerGroupStyle.borderRightWidth) + parseFloat(headerGroupStyle.borderLeftWidth) : 0;
2330-
2331-
return { width: Math.ceil(headerWidth), padding: Math.ceil(headerPadding + borderSize) };
2315+
return this.grid.getHeaderCellWidth(this.headerCell.nativeElement);
23322316
}
23332317

23342318
/**

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,7 @@ export interface GridType extends IGridDataBindable {
404404
hasColumnGroups: boolean;
405405
hasEditableColumns: boolean;
406406
uniqueColumnValuesStrategy: (column: ColumnType, tree: FilteringExpressionsTree, done: (values: any[]) => void) => void;
407+
getHeaderCellWidth: (element: HTMLElement) => ISizeInfo;
407408

408409
cdr: ChangeDetectorRef;
409410
document: Document;
@@ -643,3 +644,8 @@ export interface GridSVGIcon {
643644
name: string;
644645
value: string;
645646
}
647+
648+
export interface ISizeInfo {
649+
width: number,
650+
padding: number
651+
}

projects/igniteui-angular/src/lib/grids/grid-base.directive.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ import {
123123
IPinColumnCancellableEventArgs
124124
} from './common/events';
125125
import { IgxAdvancedFilteringDialogComponent } from './filtering/advanced-filtering/advanced-filtering-dialog.component';
126-
import { ColumnType, GridServiceType, GridType, IGX_GRID_SERVICE_BASE, RowType } from './common/grid.interface';
126+
import { ColumnType, GridServiceType, GridType, IGX_GRID_SERVICE_BASE, ISizeInfo, RowType } from './common/grid.interface';
127127
import { DropPosition } from './moving/moving.service';
128128
import { IgxHeadSelectorDirective, IgxRowSelectorDirective } from './selection/row-selectors';
129129
import { IgxColumnComponent } from './columns/column.component';
@@ -3883,6 +3883,26 @@ export abstract class IgxGridBaseDirective extends DisplayDensityBase implements
38833883
return this.width === null || diff >= 0;
38843884
}
38853885

3886+
/**
3887+
* @hidden @internal
3888+
* Gets the header cell inner width for auto-sizing.
3889+
*/
3890+
public getHeaderCellWidth(element: HTMLElement): ISizeInfo {
3891+
const range = this.document.createRange();
3892+
const headerWidth = this.platform.getNodeSizeViaRange(range,
3893+
element,
3894+
element.parentElement);
3895+
3896+
const headerStyle = this.document.defaultView.getComputedStyle(element);
3897+
const headerPadding = parseFloat(headerStyle.paddingLeft) + parseFloat(headerStyle.paddingRight) +
3898+
parseFloat(headerStyle.borderRightWidth);
3899+
3900+
// Take into consideration the header group element, since column pinning applies borders to it if its not a columnGroup.
3901+
const headerGroupStyle = this.document.defaultView.getComputedStyle(element.parentElement);
3902+
const borderSize = parseFloat(headerGroupStyle.borderRightWidth) + parseFloat(headerGroupStyle.borderLeftWidth);
3903+
return { width: Math.ceil(headerWidth), padding: Math.ceil(headerPadding + borderSize) };
3904+
}
3905+
38863906
/**
38873907
* @hidden @internal
38883908
* Gets the combined width of the columns that are specific to the enabled grid features. They are fixed.

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

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ import {
2323
ViewContainerRef,
2424
Injector,
2525
NgModuleRef,
26-
ApplicationRef
26+
ApplicationRef,
27+
ContentChildren
2728
} from '@angular/core';
2829
import { IgxGridBaseDirective } from '../grid-base.directive';
2930
import { IgxFilteringService } from '../filtering/grid-filtering.service';
@@ -62,6 +63,8 @@ import { IgxGridTransaction } from '../common/types';
6263
import { SortingDirection } from '../../data-operations/sorting-strategy';
6364
import { GridBaseAPIService } from '../api.service';
6465
import { IgxGridForOfDirective } from '../../directives/for-of/for_of.directive';
66+
import { IgxPivotRowDimensionContentComponent } from './pivot-row-dimension-content.component';
67+
import { flatten } from '@angular/compiler';
6568

6669
let NEXT_ID = 0;
6770
const MINIMUM_COLUMN_WIDTH = 200;
@@ -993,6 +996,58 @@ export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnIni
993996
super.setupColumns();
994997
}
995998

999+
/**
1000+
* Auto-sizes row dimension cells.
1001+
*
1002+
* @remarks
1003+
* Only sizes based on the dimension cells in view.
1004+
* @example
1005+
* ```typescript
1006+
* this.grid.autoSizeRowDimension(dimension);
1007+
* ```
1008+
* @param dimension The row dimension to size.
1009+
*/
1010+
public autoSizeRowDimension(dimension: IPivotDimension) {
1011+
if (this.getDimensionType(dimension) === PivotDimensionType.Row) {
1012+
const relatedDims = PivotUtil.flatten([dimension]).map(x => x.memberName);
1013+
const content = this.rowDimensionContentCollection.filter(x => relatedDims.indexOf(x.dimension.memberName) !== -1);
1014+
const headers = flatten(content.map(x => x.headerGroups.toArray())).map(x => x.header.refInstance);
1015+
const autoWidth = this.getLargesContentWidth(headers);
1016+
dimension.width = autoWidth;
1017+
this.pipeTrigger++;
1018+
this.cdr.detectChanges();
1019+
}
1020+
}
1021+
1022+
@ViewChildren(IgxPivotRowDimensionContentComponent)
1023+
protected rowDimensionContentCollection: QueryList<IgxPivotRowDimensionContentComponent>;
1024+
1025+
protected getDimensionType(dimension: IPivotDimension): PivotDimensionType {
1026+
return PivotUtil.flatten(this.rowDimensions).indexOf(dimension) !== -1 ? PivotDimensionType.Row :
1027+
PivotUtil.flatten(this.columnDimensions).indexOf(dimension) !== -1 ? PivotDimensionType.Column : PivotDimensionType.Filter;
1028+
}
1029+
1030+
protected getLargesContentWidth(contents: ElementRef[]): string {
1031+
const largest = new Map<number, number>();
1032+
if (contents.length > 0) {
1033+
const cellsContentWidths = [];
1034+
contents.forEach((elem) => cellsContentWidths.push(this.getHeaderCellWidth(elem.nativeElement).width));
1035+
const index = cellsContentWidths.indexOf(Math.max(...cellsContentWidths));
1036+
const cellStyle = this.document.defaultView.getComputedStyle(contents[index].nativeElement);
1037+
const cellPadding = parseFloat(cellStyle.paddingLeft) + parseFloat(cellStyle.paddingRight) +
1038+
parseFloat(cellStyle.borderLeftWidth) + parseFloat(cellStyle.borderRightWidth);
1039+
largest.set(Math.max(...cellsContentWidths), cellPadding);
1040+
}
1041+
const largestCell = Math.max(...Array.from(largest.keys()));
1042+
const width = Math.ceil(largestCell + largest.get(largestCell));
1043+
1044+
if (Number.isNaN(width)) {
1045+
return null;
1046+
} else {
1047+
return width + 'px';
1048+
}
1049+
}
1050+
9961051
protected resolveToggle(groupColumn: IgxColumnComponent, state: boolean) {
9971052
groupColumn.hidden = state;
9981053
this.columnGroupStates.set(groupColumn.field, state);
@@ -1042,12 +1097,12 @@ export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnIni
10421097
/**
10431098
* @hidden @internal
10441099
*/
1045-
@ViewChildren('verticalRowDimScrollContainer', { read: IgxGridForOfDirective})
1100+
@ViewChildren('verticalRowDimScrollContainer', { read: IgxGridForOfDirective })
10461101
public verticalRowDimScrollContainers: QueryList<IgxGridForOfDirective<any>>;
10471102

10481103
protected verticalScrollHandler(event) {
10491104
super.verticalScrollHandler(event);
1050-
this.verticalRowDimScrollContainers.forEach(x => {
1105+
this.verticalRowDimScrollContainers.forEach(x => {
10511106
x.onScroll(event);
10521107
x.cdr.detectChanges();
10531108
});

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -812,6 +812,17 @@ describe('Basic IgxPivotGrid #pivotGrid', () => {
812812
expect((rowChip1.nativeElement.previousElementSibling as any).style.visibility).toBe('hidden');
813813
expect((rowChip1.nativeElement.nextElementSibling as any).style.visibility).toBe('hidden');
814814
});
815+
816+
it('should auto-size row dimension via the API.', () => {
817+
const pivotGrid = fixture.componentInstance.pivotGrid;
818+
const rowDimension = pivotGrid.pivotConfiguration.rows[0];
819+
expect(rowDimension.width).toBeUndefined();
820+
expect(pivotGrid.resolveRowDimensionWidth(rowDimension)).toBe(200);
821+
pivotGrid.autoSizeRowDimension(rowDimension);
822+
fixture.detectChanges();
823+
expect(rowDimension.width).toBe('186px');
824+
expect(pivotGrid.resolveRowDimensionWidth(rowDimension)).toBe(186);
825+
});
815826
});
816827
});
817828

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,15 @@ import {
33
ChangeDetectorRef,
44
Component,
55
ComponentFactoryResolver,
6+
ContentChildren,
67
ElementRef,
78
Inject,
89
Input,
10+
QueryList,
911
SimpleChanges,
1012
TemplateRef,
1113
ViewChild,
14+
ViewChildren,
1215
ViewContainerRef
1316
} from '@angular/core';
1417
import { IgxColumnGroupComponent } from '../columns/column-group.component';
@@ -18,6 +21,7 @@ import { IGX_GRID_BASE, PivotGridType } from '../common/grid.interface';
1821
import { IgxGridHeaderRowComponent } from '../headers/grid-header-row.component';
1922
import { IgxRowDirective } from '../row.directive';
2023
import { IPivotDimension, IPivotDimensionData } from './pivot-grid.interface';
24+
import { IgxPivotRowDimensionHeaderGroupComponent } from './pivot-row-dimension-header-group.component';
2125
import { PivotUtil } from './pivot-util';
2226

2327
/**
@@ -59,6 +63,9 @@ export class IgxPivotRowDimensionContentComponent extends IgxGridHeaderRowCompon
5963
@ViewChild('headerDefaultTemplate', { read: TemplateRef, static: true })
6064
public headerTemplateDefault: TemplateRef<any>;
6165

66+
@ViewChildren(IgxPivotRowDimensionHeaderGroupComponent)
67+
public headerGroups: QueryList<IgxPivotRowDimensionHeaderGroupComponent>
68+
6269
constructor(
6370
@Inject(IGX_GRID_BASE) public grid: PivotGridType,
6471
protected ref: ElementRef<HTMLElement>,

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, HostBinding, HostListener, Inject, Input } from '@angular/core';
1+
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, HostBinding, HostListener, Inject, Input, ViewChild, ViewChildren } from '@angular/core';
22
import { PlatformUtil } from '../../core/utils';
33
import { IgxColumnComponent } from '../columns/column.component';
44
import { IGX_GRID_BASE, PivotGridType } from '../common/grid.interface';
@@ -7,6 +7,7 @@ import { IgxGridHeaderGroupComponent } from '../headers/grid-header-group.compon
77
import { IgxColumnResizingService } from '../resizing/resizing.service';
88
import { IgxRowDirective } from '../row.directive';
99
import { IPivotDimension } from './pivot-grid.interface';
10+
import { IgxPivotRowDimensionHeaderComponent } from './pivot-row-dimension-header.component';
1011

1112
/**
1213
* @hidden
@@ -41,6 +42,9 @@ export class IgxPivotRowDimensionHeaderGroupComponent extends IgxGridHeaderGroup
4142
@Input()
4243
public parent: any;
4344

45+
@ViewChild(IgxPivotRowDimensionHeaderComponent)
46+
public header: IgxPivotRowDimensionHeaderComponent;
47+
4448
@HostBinding('attr.id')
4549
public get headerID() {
4650
return `${this.grid.id}_-2_${this.rowIndex}_${this.visibleIndex}`;

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export class IgxPivotRowDimensionHeaderComponent extends IgxGridHeaderComponent
1919
@Inject(IGX_GRID_BASE) public grid: GridType,
2020
public colResizingService: IgxColumnResizingService,
2121
public cdr: ChangeDetectorRef,
22-
private refInstance: ElementRef<HTMLElement>
22+
public refInstance: ElementRef<HTMLElement>
2323
) {
2424
super(grid, colResizingService, cdr, refInstance);
2525
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
<button igxButton [disabled]="grid1.displayDensity === compact" (click)="setDensity('compact')">Compact</button>
1111
</igx-buttongroup>
1212
</div>
13+
<button (click)='autoSizeRow(0)'>AutoSize Row 0</button>
14+
<button (click)='autoSizeRow(1)'>AutoSize Row 1</button>
1315
</div>
1416

1517
<igx-pivot-grid #grid1 [data]="origData" [width]="'100%'" [height]="'100%'" [defaultExpandState]='true'

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,4 +222,8 @@ export class PivotGridSampleComponent {
222222
public setDensity(density: DisplayDensity) {
223223
this.grid1.displayDensity = density;
224224
}
225+
226+
public autoSizeRow(ind) {
227+
this.grid1.autoSizeRowDimension(this.pivotConfigHierarchy.rows[ind]);
228+
}
225229
}

0 commit comments

Comments
 (0)