Angular Agrupar cuadrícula por
Un comportamiento de Group by en una tabla Ignite UI for Angular o una cuadrícula UI crea filas de datos agrupadas basadas en los valores de las columnas. El Agrupar por enigxGrid permite visualizar los grupos en una estructura jerárquica. Las filas de datos agrupadas pueden expandirse o colapsarse y el orden de agrupación puede cambiarse a través de la interfaz o API. Cuando la selección de filas está activada, se renderiza un selector de Agrupar por fila en el área más a la izquierda de la fila de grupo. En caso de que larowSelection propiedad esté configurada como simple, las casillas de verificación están desactivadas y solo sirven como indicación para el grupo donde se coloca la selección. Si larowSelection propiedad está configurada como múltiple, al hacer clic en el selector Agrupar por filas se seleccionan todos los registros que pertenecen a este grupo.
Angular Grid Group By Example
Este ejemplo presenta las capacidades de agrupación de una gran cantidad de datos. Arrastrar los encabezados de las columnas a la parte superior (área de agrupación) permite a los usuarios ver los datos de la columna seleccionada en una estructura jerárquica. Pueden agrupar en varios campos arrastrando más encabezados de columna a la parte superior. Estas opciones de agrupación resultan útiles cuando tienes tablas con numerosas filas y columnas donde los usuarios quieren presentar los datos de una manera mucho más rápida y visualmente aceptable.
Initial Grouping State
Es posible definir el agrupamiento inicial de la cuadrícula asignando un array de expresiones a lagroupingExpressions propiedad de la cuadrija.
public ngOnInit() {
grid.groupingExpressions = [
{ fieldName: 'ProductName', dir: SortingDirection.Desc },
{ fieldName: 'Released', dir: SortingDirection.Desc }
];
}
Agrupar expresiones implementa laISortingExpression interfaz.
Group By API
Grouping API
El agrupamiento está disponible a través de la interfaz y mediante una API robusta expuesta por el componente de cuadra. Los desarrolladores pueden permitir que los usuarios finales agrupen los datos de la cuadrícula por ciertas columnas, estableciendo la propiedad degroupable cada columna entrue.
<igx-grid [data]="data">
<igx-column *ngFor="let c of columns" [field]="c.field" [groupable]="true">
</igx-column>
</igx-grid>
public ngOnInit() {
grid.columns.forEach((column) => {
column.groupable = true;
});
}
Durante el tiempo de ejecución, las expresiones son obtenibles y establecibles desde lagroupingExpressions propiedad. Si necesitas añadir o cambiar una expresión existente, también puedes usar elgroupBy método con una sola o una matriz deISortingExpression.
grid.groupBy({ fieldName: 'ProductName', dir: SortingDirection.Desc, ignoreCase: true });
Note
Hasta ahora, la agrupación/clasificación funcionaba en conjunto. En la versión 13.2, se introduce un nuevo comportamiento que desacopla la agrupación de la ordenación. Por ejemplo, al borrar la agrupación, no se borrarán las expresiones de ordenación en la cuadrícula o viceversa. Aun así, si una columna está ordenada y agrupada, las expresiones agrupadas tienen prioridad.
Expand/Collapse API
Además de agrupar expresiones, también puedes controlar los estados de expansión de las filas de grupo. Se almacenan en una propiedad separada deligxGrid componentegroupingExpansionState. Una fila de grupo se identifica de forma única según el nombre del campo para el que se crea y el valor que representa para cada nivel de agrupación. Esto significa que la firma de una interfaz de estado de expansión es la siguiente:
export interface IGroupByKey {
fieldName: string;
value: any;
}
export interface IGroupByExpandState {
hierarchy: Array<IGroupByKey>;
expanded: boolean;
}
Como ocurre congroupingExpressions establecer una lista deIGroupByExpandState directamente a lagroupingExpansionState expansión que cambia en consecuencia. AdemásigxGrid, expone un método que alterna un grupo por la instancia de registro de grupo.
const groupRow = this.grid.groupsRecords.find(r => r.value === "France");
const groupRow = this.grid.getRowByIndex(0).groupRow;
grid.toggleGroup(groupRow);
groupRow.expanded = false;
Los grupos pueden crearse, expandidos (por defecto) o colapsados, y los estados de expansión generalmente solo contendrían el estado opuesto al comportamiento por defecto. Puedes controlar si los grupos deben expandirse o no a través de lagroupsExpanded propiedad.
Select/Deselect all rows in a group API
Seleccionar/Deseleccionar todas las filas de un grupo está disponible a través de losselectRowsInGroup métodos de la API de YdeselectRowsInGroup.
El fragmento de código que aparece a continuación puede usarse para seleccionar todas las filas dentro de un grupo usando el método de instanciaselectRowsInGroup de registro de grupo. Además, el segundo parámetro de este método es una propiedad booleana mediante la cual puedes elegir si la selección de fila anterior se limpia o no. La selección anterior se conserva por defecto.
const groupRow = this.grid.groupsRecords.find(r => r.value === "France");
const groupRow = this.grid.getRowByIndex(0).groupRow;
grid.selectRowsInGroup(groupRow);
Si necesitas deseleccionar todas las filas de un grupo programáticamente, puedes usar eldeselectRowsInGroup método.
const groupRow = this.grid.groupsRecords.find(r => r.value === "France");
const groupRow = this.grid.getRowByIndex(0).groupRow;
grid.deselectRowsInGroup(groupRow);
Templating
Group Row Templates
La fila del grupo, excepto la interfaz de usuario para expandir/contraer, es totalmente adaptable a plantillas. De forma predeterminada, muestra un icono de agrupación y muestra el nombre del campo y el valor que representa. La plantilla de registro de agrupación con la que se presenta tiene la siguiente firma:
export interface IGroupByRecord {
expression: ISortingExpression;
level: number;
records: GroupedRecords;
value: any;
groupParent: IGroupByRecord;
groups?: IGroupByRecord[];
}
Como ejemplo, la siguiente plantilla haría que el resumen de filas del grupo fuera más detallado:
<ng-template igxGroupByRow let-groupRow>
<span>Total items with value: {{ groupRow.value }} are {{ groupRow.records.length }}</span>
</ng-template>
Group Row Selector Templates
Como se mencionó antes, la fila de grupo, salvo la interfaz de expansión/colapso, es totalmente templacionable. Para crear una plantilla personalizada de selector Group by row dentro de la cuadrícula, declara una<ng-template> directiva withigxGroupByRowSelector. Desde la plantilla, puedes acceder a la variable de contexto proporcionada implícitamente, con propiedades que te dan información sobre el estado de Group by row.
LaselectedCount propiedad muestra cuántos de los registros del grupo están seleccionados actualmente mientrastotalCount que cuántos registros pertenecen al grupo.
<ng-template igxGroupByRowSelector let-groupByRowContext>
{{ groupByRowContext.selectedCount }} / {{ groupByRowContext.totalCount }}
</ng-template>
LagroupRow propiedad devuelve una referencia a la fila del grupo.
<ng-template igxGroupByRowSelector let-groupByRowContext>
<div (click)="handleGroupByRowSelectorClick($event, groupByRowContext.groupRow)">Handle groupRow</div>
</ng-template>
LasselectedCount propiedades ytotalCount pueden usarse para determinar si el selector Agrupar por fila debe estar marcado o indeterminado (parcialmente seleccionado).
<igx-grid #grid [data]="gridData" primaryKey="ProductID" rowSelection="multiple">
<!-- ... -->
<ng-template igxGroupByRowSelector let-context>
<igx-checkbox
[checked]=" context.selectedCount > 0 && context.selectedCount === context.totalCount"
[indeterminate]="context.selectedCount > 0 && context.selectedCount !== context.totalCount">
</igx-checkbox>
</ng-template>
</igx-grid>
Angular Grid Group By with Paging
Las filas de grupo participan en el proceso de paginación junto con las filas de datos. Cuentan para el tamaño de página de cada página. Las filas contraídas no se incluyen en el proceso de paginación. Cualquier operación de expandir o contraer obliga a Paging a recalcular el recuento de páginas y ajustar el índice de páginas si es necesario. Los grupos que abarcan varias páginas se dividen entre ellos. La fila del grupo es visible solo en la página en la que comienza y no se repite en las páginas siguientes. La información de resumen de las filas del grupo se calcula en función de todo el grupo y no se ve afectada por la paginación.
Angular group by with paging example
Group By with Summaries
La integración entre Agrupar por y Resúmenes se describe en el tema Resúmenes.
Keyboard Navigation
La interfaz de usuario de agrupación admite las siguientes interacciones de teclado:
Para filas de grupo (el foco debe estar en la fila o en la celda expandir/contraer)
- ALT + DERECHA: expande el grupo
- ALT + IZQUIERDA: colapsa el grupo
- ESPACIO: selecciona todas las filas del grupo, si la propiedad RowSelection está establecida en múltiples
Para los componentes del grupo
igxChipen el grupo por área (el enfoque debe estar en el chip)- MAYÚS + IZQUIERDA: mueve el chip enfocado hacia la izquierda, cambiando el orden de agrupación, si es posible
- MAYÚS + DERECHA: mueve el chip enfocado hacia la derecha, cambiando el orden de agrupación, si es posible
- ESPACIO: cambia la dirección de clasificación
- ELIMINAR: desagrupa el campo
- Los elementos separados del chip también se pueden enfocar y se puede interactuar con ellos mediante la ENTER llave.
Angular Grid Custom Group By
igxGrid permite definir agrupaciones personalizadas por columna o por expresión de agrupación, lo que proporciona agrupaciones basadas en una condición personalizada. Esto es útil cuando necesita agrupar por objetos complejos o para otros escenarios específicos de aplicaciones.
Note
Para implementar agrupaciones personalizadas, primero los datos deben ordenarse adecuadamente. Por ello, también puede que necesites aplicar una estrategia de clasificación personalizada que amplíe la baseDefaultSortingStrategy. Una vez ordenados los datos, los grupos personalizados pueden determinarse especificando agroupingComparer para la columna o para la expresión de agrupación específica.
La muestra siguiente muestra agrupación personalizada porDate, donde los valores de fecha se ordenan y agrupan por Día, Semana, Mes o Año según el modo de agrupación seleccionado por el usuario.
Angular custom group by example
El ejemplo define estrategias de ordenación personalizadas para las diferentes condiciones de fecha. Cada estrategia personalizada extiende la baseDefaultSortingStrategy y define elcompareValues método, que es la función de comparación personalizada utilizada al ordenar los valores. Además, extrae los valores de la fecha necesaria para la comparación.
class BaseSortingStrategy extends DefaultSortingStrategy {
public getParsedDate(date: any) {
return {
day: date.getDay(),
month: date.getMonth() + 1,
year: date.getFullYear()
};
}
compareValues(a: any, b: any) {
const dateA = this.getParsedDate(a);
const dateB = this.getParsedDate(b);
return dateA.year < dateB.year ?
-1 : dateA.year > dateB.year ?
1 : dateA.month < dateB.month ?
-1 : dateA.month > dateB.month ?
1 : 0;
}
}
class DaySortingStrategy extends BaseSortingStrategy {
compareValues(a: any, b: any) {
const dateA = this.getParsedDate(a);
const dateB = this.getParsedDate(b);
return dateA.year < dateB.year ?
-1 : dateA.year > dateB.year ?
1 : dateA.month < dateB.month ?
-1 : dateA.month > dateB.month ?
1 : dateA.day < dateB.day ?
-1 : dateA.day > dateB.day ?
1 : 0;
}
}
class WeekSortingStrategy extends BaseSortingStrategy {
public getWeekOfDate(a: any) {
return parseInt(new DatePipe("en-US").transform(a, 'w'), 10);
}
compareValues(a: any, b: any) {
const dateA = this.getParsedDate(a);
const dateB = this.getParsedDate(b);
const weekA = this.getWeekOfDate(a);
const weekB = this.getWeekOfDate(b);
return dateA.year < dateB.year ?
-1 : dateA.year > dateB.year ?
1 : weekA < weekB ?
-1 : weekA > weekB ?
1 : 0;
}
}
Se define unagroupingComparer función para las expresiones de agrupamiento, que determina los elementos que pertenecen al mismo grupo en función del modo de agrupación seleccionado. Los valores en los datos ordenados para los que esta función devuelve 0 se marcan como parte del mismo grupo.
groupingComparer: (a, b) => {
const dateA = this.sortingStrategy.getParsedDate(a);
const dateB = this.sortingStrategy.getParsedDate(b);
if (this.groupByMode === 'Month') {
return dateA.month === dateB.month ? 0 : -1;
} else if (this.groupByMode === "Year") {
return dateA.year === dateB.year ? 0 : -1;
} else if (this.groupByMode === "Week") {
return this.sortingStrategy.getWeekOfDate(a) === this.sortingStrategy.getWeekOfDate(b) ? 0 : -1;
}
return dateA.day === dateB.day && dateA.month === dateB.month ? 0 : -1;
}
Desde la versión 15.1.0, también puedes usar la estrategiaGroupMemberCountSortingStrategy de ordenación integrada para ordenar los elementos según el número de miembros.
public sortByGroup() {
const expressions = this.grid1.groupingExpressions;
if (expressions.length) {
const fieldName = expressions[0].fieldName;
const dir = expressions[0].dir === SortingDirection.Asc ? SortingDirection.Desc : SortingDirection.Asc;
this.grid1.groupBy({ fieldName, dir, ignoreCase: false, strategy: GroupMemberCountSortingStrategy.instance() });
}
}
Estilismo
El igxGrid permite estilizar a través de laIgnite UI for Angular Theme Library. La cuadrículagrid-theme expone una amplia variedad de propiedades, que permiten la personalización de todas las características de la cuadrícula.
En los pasos siguientes, veremos los pasos para personalizar el estilo Agrupar por de la cuadrícula.
Importing global theme
Para comenzar la personalización de la función de Agrupar por Grupo, necesitas importar elindex archivo, donde están todas las funciones de estilo y los mixins.
@use "igniteui-angular/theming" as *;
// IMPORTANT: Prior to Ignite UI for Angular version 13 use:
// @import '~igniteui-angular/lib/core/styles/themes/index';
Defining custom theme
A continuación, crea un nuevo tema que extienda ygrid-theme acepte los parámetros necesarios para personalizar el Grupo By según se desee. También necesitas ampliarlochip-theme, porque se usa en la función de Agrupar por.
$custom-theme: grid-theme(
$group-row-background: #494949,
$group-row-selected-background: #383838,
$group-label-column-name-text: #f8f8f8,
$group-label-icon: #ffcd0f,
$group-label-text: #f8f8f8,
$group-count-background: #ffcd0f,
$group-count-text-color: #000,
$expand-icon-color: #ffcd0f,
$expand-icon-hover-color: rgb(223, 181, 13),
$cell-active-border-color: #ffcd0f,
$row-selected-background: #fff6d3,
$row-selected-text-color: #000,
$drop-indicator-color: #ffcd0f
);
/* Chip theme will style the chips in the Group By area */
$custom-chips-theme: chip-theme(
$background: #494949,
$text-color: #f8f8f8,
$hover-text-color: #e7e7e7
);
Defining a custom color palette
En el enfoque que describimos arriba, los valores de color estaban codificados de forma fija. Alternativamente, puedes lograr mayor flexibilidad utilizando laspalette funciones ycolor.palette genera una paleta de colores basada en los colores primario, secundario y de superficie proporcionados.
$black-color: #292826;
$yellow-color: #ffcd0f;
$grey-color: #efefef;
$custom-palette: palette(
$primary: $black-color,
$secondary: $yellow-color,
$surface: $grey-color
);
Después de generar una paleta personalizada, lacolor función puede usarse para obtener diferentes variedades de los colores primario y secundario.
$custom-theme: grid-theme(
$group-row-background: color($custom-palette, "primary", 300),
$group-row-selected-background: color($custom-palette, "primary", 400),
$group-label-column-name-text:contrast-color($custom-palette, "primary", 500),
$group-label-icon: color($custom-palette, "secondary", 600),
$group-label-text:contrast-color($custom-palette, "primary", 500),
$group-count-background: color($custom-palette, "secondary", 600),
$group-count-text-color: color($custom-palette, "primary", 400),
$expand-icon-color: color($custom-palette, "secondary", 600),
$expand-icon-hover-color: color($custom-palette, "secondary", 300),
$cell-active-border-color: color($custom-palette, "secondary", 600)
);
$custom-chips-theme: chip-theme(
$background: color($custom-palette, "primary", 300),
$text-color:contrast-color($custom-palette, "primary", 500),
$hover-text-color:contrast-color($custom-palette, "primary", 600)
);
Defining custom schemas
Puedes ir aún más lejos y construir una estructura flexible que tenga todos los beneficios de un esquema. El esquema es la receta de un tema. Extiende uno de los dos esquemas predefinidos que se proporcionan para cada componente. En nuestro caso, nosotros usaríamoslight-grid.
$custom-grid-schema: extend(
map.get('grid', $light-material-schema),
(
group-row-background: (color:('secondary', 100)),
group-row-selected-background: (color:('primary', 400)),
group-label-column-name-text: (color:('primary', 600)),
group-label-icon: (color:('primary', 600)),
group-label-text: (color:('secondary', 700)),
group-count-background: (color:('primary', 600)),
group-count-text-color: (color:('secondary', 400)),
expand-icon-color: (color:('primary', 600)),
expand-icon-hover-color: (color:('primary', 400))
)
);
Para que se aplique el esquema personalizado, es necesario extender los globales (lighto biendark). Todo el proceso consiste en suministrar un componente con un esquema personalizado y añadirlo al tema correspondiente del componente después.
$my-custom-schema: extend(
$light-material-schema,
(
grid: $custom-grid-schema
)
);
$custom-theme: grid-theme(
$palette: $custom-palette,
$schema: $my-custom-schema
);
Applying the custom theme
La forma más sencilla de aplicar tu tema es con unasass @include instrucción en el archivo de estilos globales:
@include css-vars($custom-theme);
@include css-vars($custom-chips-theme);
Scoped component theme
Para que el tema personalizado afecte solo a un componente específico, puedes mover todos los estilos que acabas de definir del archivo de estilos globales al archivo de estilo del componente personalizado (incluyendo la importación delindex archivo).
De esta manera, debido a Angular ViewEncapsulation, los estilos solo se aplicarán al componente personalizado.
Note
Si el componente utiliza unaEmulated ViewEncapsulation, es necesario penetrar esta encapsulación para::ng-deep estilizar los componentes que están dentro de la cuadrícula.
En nuestro ejemplo, necesitamos usar::ng-deep para nuestro tema de chip:
@include css-vars($custom-theme);
:host {
::ng-deep {
@include chip($custom-chips-theme);
}
}
Demo
Note
La muestra no se verá afectada por el tema global seleccionado deChange Theme.
Known Limitations
| Limitación | Descripción |
|---|---|
| La cantidad máxima de columnas agrupadas es 10. | Si se agrupan más de 10 columnas, se genera un error. |
API References
- Componente IgxGrid
- Grupo IgxPorFila
- Estilos de componentes IgxGrid
- ISortingExpression
- ComponenteColumnaIgx
- IGroupByExpandState
- Componente IgxChip
- Estilos de componentes IgxChip
Additional Resources
- Descripción general de la cuadrícula
- Virtualización y rendimiento
- Paginación
- Filtración
- Clasificación
- Columna en movimiento
- resúmenes
- Cambio de tamaño de columna
- Selección