Si tiene datos no jerárquicos y desea agruparlos por una o más columnas y completar las filas principales con valores agregados, puede usar IgxTreeGridComponent junto con la tubería treeGridGrouping y el componente UI con el selector igx-tree-grid-group-by-area.
La canalización treeGridGrouping agrupa los datos según los parámetros proporcionados y la jerarquía resultante se muestra en una columna separada. La canalización también puede calcular valores agregados para las filas principales generadas si se proporcionan agregaciones. A continuación se muestra un ejemplo de cómo utilizar la tubería en la plantilla:
groupingExpressions: una matriz de objetos IGroupingExpression que contiene información sobre los campos utilizados para generar la jerarquía y los detalles de clasificación para cada grupo.
groupKey: un valor de cadena para el nombre de la columna de jerarquía generada
childDataKey: un valor de cadena para el campo donde se almacena la colección secundaria de las filas principales generadas.
grid -IgxTreeGridComponent que se utiliza para la agrupación
agregaciones (opcional): una matriz de objetos ITreeGridAggregation que contiene información sobre las funciones de agregación
El componente de interfaz de usuario con selector igx-tree-grid-group-by-area maneja las interacciones de la interfaz de usuario relacionadas con las columnas que se utilizan para la agrupación. A continuación se muestra un ejemplo de cómo utilizar el componente en la plantilla:
grid -IgxTreeGridComponent que se utiliza para la agrupación
expresiones: una matriz de objetos IGroupingExpression que contiene los campos utilizados para generar la jerarquía
hideGroupedColumns: un valor booleano que indica si se deben ocultar las columnas mediante las cuales se realizó la agrupación
dropAreaTemplate: una plantilla para el área de colocación que se puede utilizar para anular la plantilla de área de colocación predeterminada
dropAreaMessage: una cadena que se puede utilizar para anular el mensaje predeterminado para la plantilla de área de colocación predeterminada
Para que la clasificación funcione correctamente, debe establecer la propiedad sortStrategy de IgxTreeGridComponent en una instancia de IgxGroupedTreeGridSorting.
Angular Grupo de cuadrícula de árboles por ejemplo
EXAMPLE
TS
HTML
SCSS
import { Component, ElementRef, OnInit, OnDestroy, ViewChild, HostBinding } from'@angular/core';
import { AbsoluteScrollStrategy, ConnectedPositioningStrategy, DefaultSortingStrategy, HorizontalAlignment, IGroupingExpression, IgxButtonGroupComponent, IgxGroupedTreeGridSorting, IgxOverlayOutletDirective, IgxSliderComponent, IgxTreeGridComponent, ITreeGridAggregation, OverlaySettings, PositionSettings, TreeGridFilteringStrategy, VerticalAlignment, IgxGridToolbarComponent, IgxGridToolbarActionsComponent, IgxGridToolbarPinningComponent, IgxGridToolbarHidingComponent, IgxGridToolbarExporterComponent, IgxTreeGridGroupByAreaComponent, IgxColumnComponent, IgxCellEditorTemplateDirective, IgxSelectComponent, IgxFocusDirective, IgxSelectItemComponent, IgxCellTemplateDirective, IgxIconComponent, IgxTreeGridGroupingPipe } from'igniteui-angular';
import { Contract, REGIONS } from'../data/financialData';
import { SignalRService } from'../services/signal-r.service';
import { FormsModule } from'@angular/forms';
import { NgIf, NgFor, AsyncPipe, CurrencyPipe, DatePipe } from'@angular/common';
import { IgxPreventDocumentScrollDirective } from'../directives/prevent-scroll.directive';
@Component({
providers: [SignalRService],
selector: 'app-tree-grid-finjs-sample',
styleUrls: ['./tree-grid-finjs-sample.component.scss'],
templateUrl: './tree-grid-finjs-sample.component.html',
imports: [IgxSliderComponent, FormsModule, IgxButtonGroupComponent, NgIf, IgxTreeGridComponent, IgxPreventDocumentScrollDirective, IgxGridToolbarComponent, IgxGridToolbarActionsComponent, IgxGridToolbarPinningComponent, IgxGridToolbarHidingComponent, IgxGridToolbarExporterComponent, IgxTreeGridGroupByAreaComponent, IgxColumnComponent, IgxCellEditorTemplateDirective, IgxSelectComponent, IgxFocusDirective, NgFor, IgxSelectItemComponent, IgxCellTemplateDirective, IgxIconComponent, IgxOverlayOutletDirective, AsyncPipe, CurrencyPipe, DatePipe, IgxTreeGridGroupingPipe]
})
exportclassTreeGridFinJSComponentimplementsOnDestroy, OnInit{
@ViewChild('grid1', { static: true }) public grid1!: IgxTreeGridComponent;
@ViewChild('buttonGroup1', { static: true }) public buttonGroup1!: IgxButtonGroupComponent;
@ViewChild('slider1', { static: true }) public volumeSlider!: IgxSliderComponent;
@ViewChild('slider2', { static: true }) public intervalSlider!: IgxSliderComponent;
@ViewChild(IgxOverlayOutletDirective, { static: true }) public outlet!: IgxOverlayOutletDirective;
@HostBinding('class.dark-theme')
public theme = false;
public showToolbar = true;
public selectionMode = 'multiple';
public volume = 1000;
public frequency = 500;
public data$: any;
public overlaySettings: OverlaySettings = {
modal: false
};
public controls = [
{
disabled: false,
icon: 'update',
label: 'LIVE ALL PRICES',
selected: false
},
{
disabled: true,
icon: 'stop',
label: 'Stop',
selected: false
}
];
public groupingExpressions: IGroupingExpression[] = [
{ fieldName: 'category', dir: 2, ignoreCase: true, strategy: DefaultSortingStrategy.instance() },
{ fieldName: 'type', dir: 1, ignoreCase: true, strategy: DefaultSortingStrategy.instance() },
{ fieldName: 'contract', dir: 1, ignoreCase: true, strategy: DefaultSortingStrategy.instance() }
];
public aggregations: ITreeGridAggregation[] = [
{
aggregate: (parent: any, data: any[]) => data.map((r) => r.change).reduce((ty, u) => ty + u, 0),
field: 'change'
},
{
aggregate: (parent: any, data: any[]) => data.map((r) => r.price).reduce((ty, u) => ty + u, 0),
field: 'price'
},
{
aggregate: (parent: any, data: any[]) => parent.change / (parent.price - parent.change) * 100,
field: 'changeP'
}
];
public childDataKey = 'children';
public groupColumnKey = 'categories';
public sorting = IgxGroupedTreeGridSorting.instance();
public filterStrategy = new TreeGridFilteringStrategy([this.groupColumnKey]);
public items: any[] = [{ field: 'Export native' }, { field: 'Export JS Excel' }];
public _positionSettings: PositionSettings = {
horizontalDirection: HorizontalAlignment.Left,
horizontalStartPoint: HorizontalAlignment.Right,
verticalStartPoint: VerticalAlignment.Bottom
};
public _overlaySettings: OverlaySettings = {
closeOnOutsideClick: true,
modal: false,
positionStrategy: new ConnectedPositioningStrategy(this._positionSettings),
scrollStrategy: new AbsoluteScrollStrategy()
};
public contracts = Contract;
public regions = REGIONS;
public isLoading = true;
private subscription: any;
private selectedButton: number;
private _timer: any;
constructor(private elRef: ElementRef, public dataService: SignalRService) {
this.dataService.startConnection();
this.overlaySettings.outlet = this.outlet;
this.data$ = this.dataService.data;
this.dataService.getData(0);
this.data$.subscribe((data) => {
if (data.length !== 0) {
this.isLoading = false;
};
});
}
public ngOnInit(): void {
this.overlaySettings.outlet = this.outlet;
}
public onButtonAction(event: any): void {
switch (event.index) {
case0: {
this.disableOtherButtons(event.index, true);
if (this.dataService.hasRemoteConnection) {
this.dataService.broadcastParams(this.frequency, this.volume, true);
} else {
const currData = this.grid1.filteredSortedData ?? this.grid1.data;
this._timer = setInterval(() =>this.dataService.updateAllPriceValues(currData), this.frequency);
}
break;
}
case1: {
if (this.dataService.hasRemoteConnection) {
this.dataService.stopLiveData();
} else {
this.stopFeed();
}
this.disableOtherButtons(event.index, false);
break;
}
default: break;
}
}
updateVolume(): void {
this.dataService.hasRemoteConnection ? this.dataService.broadcastParams(this.frequency, this.volume, false) :
this.dataService.getData(this.volume);
}
public stopFeed(): void {
if (this._timer) {
clearInterval(this._timer);
}
if (this.subscription) {
this.subscription.unsubscribe();
}
}
publicformatNumber(value: number) {
return value ? value.toFixed(2) : '';
}
publicpercentage(value: number) {
return value ? value.toFixed(2) + '%' : '';
}
publicformatCurrency(value: number) {
return value ? '$' + value.toFixed(3) : '';
}
/**
* the below code is needed when accessing the sample through the navigation
* it will style all the space below the sample component element, but not the navigation menu
*/publiconThemeChanged(event: any) {
const parentEl = this.parentComponentEl();
if (event.checked && parentEl.classList.contains('main')) {
parentEl.classList.add('fin-dark-theme');
} else {
parentEl.classList.remove('fin-dark-theme');
}
}
publicngOnDestroy() {
this.stopFeed();
}
publictoggleToolbar() {
this.showToolbar = !this.showToolbar;
}
private negative = (rowData: any): boolean => rowData['changeP'] < 0;
private positive = (rowData: any): boolean => rowData['changeP'] > 0;
private changeNegative = (rowData: any): boolean => rowData['changeP'] < 0 && rowData['changeP'] > -1;
private changePositive = (rowData: any): boolean => rowData['changeP'] > 0 && rowData['changeP'] < 1;
private strongPositive = (rowData: any): boolean => rowData['changeP'] >= 1;
private strongNegative = (rowData: any, key: string): boolean => rowData['changeP'] <= -1;
/* eslint-disable @typescript-eslint/member-ordering */public trends = {
changeNeg: this.changeNegative,
changePos: this.changePositive,
negative: this.negative,
positive: this.positive,
strongNegative: this.strongNegative,
strongPositive: this.strongPositive
};
public trendsChange = {
changeNeg2: this.changeNegative,
changePos2: this.changePositive,
strongNegative2: this.strongNegative,
strongPositive2: this.strongPositive
};
/* eslint-enable @typescript-eslint/member-ordering */privatedisableOtherButtons(ind: number, disableButtons: boolean) {
if (this.subscription) {
this.subscription.unsubscribe();
}
this.volumeSlider.disabled = disableButtons;
this.intervalSlider.disabled = disableButtons;
this.selectedButton = ind;
this.buttonGroup1.buttons.forEach((button, index) => {
if (index === 1) { button.disabled = !disableButtons; } else {
button.disabled = disableButtons;
}
});
}
/**
* returns the main div container of the Index Component,
* if path is /samples/sample-url, or the appRoot, if path is /sample-url
*/privateparentComponentEl() {
returnthis.elRef.nativeElement.parentElement.parentElement;
}
getbuttonSelected(): number {
returnthis.selectedButton || this.selectedButton === 0 ? this.selectedButton : -1;
}
}
ts
¿Te gusta esta muestra? Obtenga acceso a nuestro kit de herramientas de Ignite UI for Angular completo y comience a crear sus propias aplicaciones en minutos. Descárgalo gratis.
Implementación
En este ejemplo, utilizamos la canalización treeGridGrouping y el componente UI con el selector igx-tree-grid-group-by-area para la agrupación. Los datos están agrupados por los campos "categoría", "tipo" y "contrato". La jerarquía resultante se muestra en la columna "categorías" recién creada. La tubería también calcula valores agregados para las filas principales generadas para las columnas "precio", "cambio" y "cambioP".
En este ejemplo, los datos se cargan en porciones. Inicialmente, solo se muestran las categorías de nivel superior; luego, los datos secundarios se entregan una vez que se expande una fila principal. Para obtener más información sobre este enfoque, consulte el tema Carga según demanda de la red de árboles. Los datos se agrupan por los campos "ShipCountry", "ShipCity" y "Discontinued" y la jerarquía resultante se muestra en una columna separada. La agrupación se realiza en un servicio remoto: los datos se modifican y se asignan las claves secundarias y principales correspondientes que se utilizan para mostrar los datos finales en una vista jerárquica. Para obtener más información sobre cómo funciona este servicio, puede consultar la clase TreeGridGroupingLoadOnDemandService en el archivo remoteService.ts.
A continuación se muestra un ejemplo de cómo utilizar la carga bajo demanda:
Para cargar las filas secundarias cuando el usuario expande una fila, Tree Grid proporciona la propiedad de entrada de devolución de llamada loadChildrenOnDemand: los datos secundarios se recuperan del servidor y se asignan a la fila principal solicitada según los parámetros de agrupación.