Angular Tree Grid Component Overview
The Ignite UI for Angular Tree Grid is used to display and manipulate hierarchical or flat self-referencing data. Quickly bind your data with very little code or use a variety of events to customize different behaviors. This component provides a rich set of features like data selection, excel style filtering, sorting, paging, grouping, templating, column moving, column pinning, export to Excel and CSV, and more.
Angular Tree Grid Example
In this example, you can see how users can display hierarchical data. We have included filtering and sorting options, pinning and hiding, row selection, export to excel and csv, and cell templating that uses our Sparkline component. In addition, you can see an example of custom pagination with Angular Pagination.
Getting Started with Ignite UI for Angular Tree Grid
To get started with the Ignite UI for Angular Tree Grid component, first you need to install Ignite UI for Angular. In an existing Angular application, type the following command:
ng add igniteui-angular
For a complete introduction to the Ignite UI for Angular, read the getting started topic.
The next step is to import the IgxTreeGridModule
in your app.module.ts file.
// app.module.ts
import { IgxTreeGridModule } from 'igniteui-angular';
// import { IgxTreeGridModule } from '@infragistics/igniteui-angular'; for licensed package
@NgModule({
imports: [
...
IgxTreeGridModule,
...
]
})
export class AppModule {}
Alternatively, as of 16.0.0
you can import the IgxTreeGridComponent
as a standalone dependency, or use the IGX_TREE_GRID_DIRECTIVES
token to import the component and all of its supporting components and directives.
// home.component.ts
import { IGX_TREE_GRID_DIRECTIVES } from 'igniteui-angular';
// import { IGX_TREE_GRID_DIRECTIVES } from '@infragistics/igniteui-angular'; for licensed package
@Component({
selector: 'app-home',
template: '<igx-tree-grid [data]="data"></igx-tree-grid>',
styleUrls: ['home.component.scss'],
standalone: true,
imports: [IGX_TREE_GRID_DIRECTIVES]
/* or imports: [IgxTreeGridComponent] */
})
export class HomeComponent {
public data: Employee [];
}
Now that you have the Ignite UI for Angular Tree Grid module or directives imported, you can start using the igx-tree-grid
component.
Using the Angular Tree Grid
Note
This component can utilize the HammerModule
optionally. It can be imported in the root module of the application in order for touch interactions to work as expected..
The IgxTreeGridComponent
shares a lot of features with the IgxGridComponent
, but it also adds the ability to display its data hierarchically.
In order to achieve this, the IgxTreeGridComponent
provides us with a couple of ways to define the relations among our data objects - by using a child collection for every data object or by using primary and foreign keys for every data object.
Tree Cells
Regardless of which option is used for building the tree grid's hierarchy (child collection or primary and foreign keys), the tree grid's rows are constructed of two types of cells:
IgxGridCell
- Ordinary cell that contains a value.IgxGridCell
- Tree cell that contains a value, an expand/collapse indicator and an indentation div element, which is based on the level of the cell's row. The level of a row component can be accessed through thelevel
property of its innertreeRow
.
Note
Each row can have only one tree cell, but it can have multiple (or none) ordinary cells.
Initial Expansion Depth
Initially the tree grid will expand all node levels and show them. This behavior can be configured using the expansionDepth
property. By default its value is Infinity which means all node levels will be expanded. You may control the initial expansion depth by setting this property to a numeric value. For example 0 will show only root level nodes, 1 will show root level nodes and their child nodes and so on.
Child Collection
When we are using the child collection option, every data object contains a child collection, that is populated with items of the same type as the parent data object. This way every record in our tree grid will have a direct reference to any of its children. In this case the data
property of our tree grid that contains the original data source will be a hierarchically defined collection.
For this sample, let's use the following collection structure:
// Sample Employee Data
export const EMPLOYEE_DATA = [
{
Name: "Johnathan Winchester",
ID: 1,
HireDate: new Date(2008, 3, 20),
Age: 55,
Employees: [
{
Name: "Michael Burke",
ID: 3,
HireDate: new Date(2011, 6, 3),
Age: 43,
Employees: []
},
{
Name: "Thomas Anderson"
ID: 2,
HireDate: new Date(2009, 6, 19),
Age: 29,
Employees: []
},
...
]
},
...
]
Now let's start by importing our data collection and binding it to the data
input of our tree grid.
<!--treeGridSample.component.html-->
<igx-tree-grid #treeGrid [data]="localData">
</igx-tree-grid>
In order for the IgxTreeGridComponent to build the hierarchy, we will have to set its childDataKey
property to the name of the child collection that is used in each of our data objects. In our case that will be the Employees collection.
In addition, we will disable the automatic column generation and define them manually by matching them to the actual properties of our data objects. (The Employees collection will be automatically used for the hierarchy, so there is no need to include it in the columns' definitions.)
<!--treeGridSample.component.html-->
<igx-tree-grid #treeGrid [data]="localData" childDataKey="Employees"
[autoGenerate]="false">
<igx-column field="Name" dataType="string"></igx-column>
<igx-column field="HireDate" dataType="date"></igx-column>
<igx-column field="Age" dataType="number"></igx-column>
</igx-tree-grid>
We will now enable the row selection and paging features of the tree grid by using the rowSelection
and the paging
properties.
We will also enable the summaries feature on the first column and the filtering, sorting, editing, moving and resizing features for each of our columns.
<!--treeGridSample.component.html-->
<igx-tree-grid #treeGrid [data]="localData" childDataKey="Employees"
[autoGenerate]="false" [rowSelection]="'multiple'" [allowFiltering]="true" [moving]="true">
<igx-column field="Name" dataType="string" [sortable]="true" [editable]="true" [resizable]="true"
[hasSummary]="true"></igx-column>
<igx-column field="HireDate" dataType="date" [sortable]="true" [editable]="true" [resizable]="true"></igx-column>
<igx-column field="Age" dataType="number" [sortable]="true" [editable]="true" [resizable]="true"></igx-column>
<igx-paginator>
</igx-paginator>
</igx-tree-grid>
Finally, we will enable the toolbar of our tree grid, along with the column hiding, column pinning and exporting features by using the IgxGridToolbarComponent
, IgxGridToolbarHidingComponent
, IgxGridToolbarPinningComponent
and IgxGridToolbarExporterComponent
respectively.
<!--treeGridSample.component.html-->
<igx-tree-grid #treeGrid [data]="localData" childDataKey="Employees"
[autoGenerate]="false" [rowSelection]="'multiple'" [allowFiltering]="true" [moving]="true">
<igx-grid-toolbar>
<igx-grid-toolbar-title>Employees</igx-grid-toolbar-title>
<igx-grid-toolbar-actions>
<igx-grid-toolbar-hiding></igx-grid-toolbar-hiding>
<igx-grid-toolbar-pinning></igx-grid-toolbar-pinning>
<igx-grid-toolbar-exporter></igx-grid-toolbar-exporter>
</igx-grid-toolbar-actions>
</igx-grid-toolbar>
<igx-column field="Name" dataType="string" [sortable]="true" [editable]="true" [resizable]="true"></igx-column>
<igx-column field="HireDate" dataType="date" [sortable]="true" [editable]="true" [resizable]="true"></igx-column>
<igx-column field="Age" dataType="number" [sortable]="true" [editable]="true" [resizable]="true"></igx-column>
<igx-paginator [perPage]="6">
</igx-paginator>
</igx-tree-grid>
You can see the result of the code from above at the beginning of this article in the Angular Tree Grid Example section.
Primary and Foreign keys
When we are using the primary and foreign keys option, every data object contains a primary key and a foreign key. The primary key is the unique identifier of the current data object and the foreign key is the unique identifier of its parent. In this case the data
property of our tree grid that contains the original data source will be a flat collection.
The following is an example of a component which contains a flat collection defined with primary and foreign keys relation:
// treeGridSample.component.ts
@Component({...})
export class MyComponent implements OnInit {
public data: any[];
constructor() { }
public ngOnInit() {
// Primary and Foreign keys sample data
this.data = [
{ ID: 1, ParentID: -1, Name: "Casey Houston", JobTitle: "Vice President", Age: 32 },
{ ID: 2, ParentID: 1, Name: "Gilberto Todd", JobTitle: "Director", Age: 41 },
{ ID: 3, ParentID: 2, Name: "Tanya Bennett", JobTitle: "Director", Age: 29 },
{ ID: 4, ParentID: 2, Name: "Jack Simon", JobTitle: "Software Developer", Age: 33 },
{ ID: 5, ParentID: 8, Name: "Celia Martinez", JobTitle: "Senior Software Developer", Age: 44 },
{ ID: 6, ParentID: -1, Name: "Erma Walsh", JobTitle: "CEO", Age: 52 },
{ ID: 7, ParentID: 2, Name: "Debra Morton", JobTitle: "Associate Software Developer", Age: 35 },
{ ID: 8, ParentID: 10, Name: "Erika Wells", JobTitle: "Software Development Team Lead", Age: 50 },
{ ID: 9, ParentID: 8, Name: "Leslie Hansen", JobTitle: "Associate Software Developer", Age: 28 },
{ ID: 10, ParentID: -1, Name: "Eduardo Ramirez", JobTitle: "Development Manager", Age: 53 }
];
}
}
In the sample data above, all records have an ID, a ParentID and some additional properties like Name, JobTitle and Age. As mentioned previously, the ID of the records must be unique. The ParentID contains the ID of the parent node. If a row has a ParentID that does not match any row in the tree grid, then that means this row is a root row.
The parent-child relation is configured using the tree grid's primaryKey
and foreignKey
properties.
Here is the template of the component which demonstrates how to configure the tree grid to display the data defined in the above flat collection:
<!--treeGridSample.component.html-->
<igx-tree-grid #treeGrid [data]="data" primaryKey="ID" foreignKey="ParentID"
[autoGenerate]="false">
<igx-column field="Name" dataType="string"></igx-column>
<igx-column field="JobTitle" dataType="string"></igx-column>
<igx-column field="Age" dataType="number"></igx-column>
</igx-tree-grid>
In addition we will enable the row selection feature of the tree grid by using the rowSelection
property and also the filtering, sorting, editing, moving and resizing features for each of our columns.
<!--treeGridSample.component.html-->
<igx-tree-grid #treeGrid [data]="data" primaryKey="ID" foreignKey="ParentID"
[autoGenerate]="false" [rowSelection]="'multiple'" [allowFiltering]="true" [moving]="true">
<igx-column field="Name" dataType="string" [sortable]="true" [editable]="true" [resizable]="true"></igx-column>
<igx-column field="JobTitle" dataType="string" [sortable]="true" [editable]="true" [resizable]="true"></igx-column>
<igx-column field="Age" dataType="number" [sortable]="true" [editable]="true" [resizable]="true"></igx-column>
</igx-tree-grid>
And here is the final result:
Persistence and Integration
The indentation of the tree cells persists across other tree grid features like filtering, sorting and paging.
- When sorting is applied on a column, the data rows get sorted by levels. This means that the root level rows will be sorted independently from their respective children. Their respective children collections will each be sorted independently as well and so on.
- The first column (the one that has a
visibleIndex
of 0) is always the tree column. - The column that ends up with a
visibleIndex
of 0 after operations like column pinning, column hiding and column moving becomes the tree column. - Exported Excel worksheets reflect the hierarchy by grouping the records as they are grouped in the tree grid itself. All records expanded states would also be persisted and reflected.
- When exporting to CSV, levels and expanded states are ignored and all data is exported as flat.
Angular Tree Grid Sizing
See the Grid Sizing topic.
Angular Tree Grid Styling
The Tree Grid allows styling through the Ignite UI for Angular Theme Library. The tree grid's theme exposes a wide variety of properties, which allows the customization of all the tree grid's features.
To get started with styling the Tree Grid, we need to import the index
file, where all the theme functions and component mixins live:
@import '~igniteui-angular/lib/core/styles/themes/index';
Following the simplest approach, we create a new theme that extends the grid-theme
and accepts the parameters, required to customize the tree grid as desired.
Note
There is no specific sass
tree grid function.
$custom-theme: grid-theme(
$cell-active-border-color: #FFCD0F,
$cell-selected-background: #6F6F6F,
$row-hover-background: #F8E495,
$row-selected-background: #8D8D8D,
$header-background: #494949,
$header-text-color: #FFF,
$expand-icon-color: #FFCD0F,
$expand-icon-hover-color: #E0B710,
$resize-line-color: #FFCD0F,
$row-highlight: #FFCD0F
);
The last step is to include the component theme in our application.
@include grid($custom-theme);
Note
If the component is using an Emulated
ViewEncapsulation, it is necessary to penetrate
this encapsulation using ::ng-deep
:
:host {
::ng-deep {
@include grid($custom-theme);
}
}
Defining a Color Palette
Instead of hardcoding the color values like we just did, we can achieve greater flexibility in terms of colors by using the igx-palette
and igx-color
functions.
igx-palette
generates a color palette based on the primary and secondary colors that are passed:
$yellow-color: #FFCD0F;
$black-color: #494949;
$custom-palette: palette($primary: $black-color, $secondary: $yellow-color);
And then with igx-color
we can easily retrieve color from the palette.
$custom-theme: grid-theme(
$cell-active-border-color: color($custom-palette, "secondary", 500),
$cell-selected-background: color($custom-palette, "primary", 300),
$row-hover-background: color($custom-palette, "secondary", 100),
$row-selected-background: color($custom-palette, "primary", 100),
$header-background: color($custom-palette, "primary", 500),
$header-text-color:contrast-color($custom-palette, "primary", 500),
$expand-icon-color: color($custom-palette, "secondary", 500),
$expand-icon-hover-color: color($custom-palette, "secondary", 600),
$resize-line-color: color($custom-palette, "secondary", 500),
$row-highlight: color($custom-palette, "secondary", 500)
);
Using Schemas
Going further with the theming engine, you can build a robust and flexible structure that benefits from schemas. A schema is a recipe of a theme.
Extend one of the two predefined schemas, that are provided for every component, in this case - light-grid
schema:
// Extending the light tree grid schema
$custom-grid-schema: extend($_light-grid, (
cell-active-border-color: (igx-color:('secondary', 500)),
cell-selected-background: (igx-color:('primary', 300)),
row-hover-background: (igx-color:('secondary', 100)),
row-selected-background: (igx-color:('primary', 100)),
header-background: (igx-color:('primary', 500)),
header-text-color: (igx-contrast-color:('primary', 500)),
expand-icon-color: (igx-color:('secondary', 500)),
expand-icon-hover-color: (igx-color:('secondary', 600)),
resize-line-color: (igx-color:('secondary', 500)),
row-highlight: (igx-color:('secondary', 500))
));
In order to apply our custom schemas we have to extend one of the globals (light
or dark
), which is basically pointing out the components with a custom schema, and after that add it to the respective component themes:
// Extending the global light-schema
$my-custom-schema: extend($light-schema, (
igx-grid: $custom-grid-schema
));
// Defining grid-theme with the global light schema
$custom-theme: grid-theme(
$palette: $custom-palette,
$schema: $my-custom-schema
);
Don't forget to include the themes in the same way as it was demonstrated above.
Angular Tree Grid Styling Demo
Note
The sample will not be affected by the selected global theme from Change Theme
.
Performance (Experimental)
The igxTreeGrid
's design allows it to take advantage of the Event Coalescing feature that has Angular introduced. This feature allows for improved performance with roughly around 20%
in terms of interactions and responsiveness. This feature can be enabled on application level by simply setting the ngZoneEventCoalescing
and ngZoneRunCoalescing
properties to true
in the bootstrapModule
method:
platformBrowserDynamic()
.bootstrapModule(AppModule, { ngZoneEventCoalescing: true, ngZoneRunCoalescing: true })
.catch(err => console.error(err));
Note
This is still in experimental feature for the igxTreeGrid
. This means that there might be some unexpected behaviors in the Tree Grid. In case of encountering any such behavior, please contact us on our Github page.
Note
Enabling it can affects other parts of an Angular application that the igxTreeGrid
is not related to.
Known Limitations
Limitation | Description |
---|---|
Templating Tree Cells | When templating a tree cell, content that spans outside the boundaries of the cell will not be shown unless positioned in an overlay. |
Group By | Group By feature is not supported, because it is inherent to the tree grid. |
Note
The tree grid has a depth limit of 25 levels. Supporting more levels requires adding custom CSS classes in the application. You may see an example of such CSS class below:
.igx-grid__tree-cell--padding-level-26 {
padding-left: 39rem;
}
Note
igxTreeGrid
uses igxForOf
directive internally hence all igxForOf
limitations are valid for igxTreeGrid
. For more details see igxForOf Known Issues section.
API References
- IgxTreeGridComponent
- IgxGridCell
- IgxTreeGridRow
- IgxGridComponent
- IgxGridComponent Styles
- IgxBaseTransactionService
Theming Dependencies
- IgxIcon Theme
- IgxInputGroup Theme
- IgxChip Theme
- IgxRipple Theme
- IgxButton Theme
- IgxOverlay Theme
- IgxDropDown Theme
- IgxCalendar Theme
- IgxSnackBar Theme
- IgxBadge Theme