Google launched the UI component toolkit known as Angular Material to enable Angular developers to create contemporary apps in a structured and responsive manner. By using this library, we can vastly improve the end-user experience and increase awareness of our application.
This library contains modern, ready-to-use items that need less than no further coding when used directly.
In Angular, trees are made with the mat-tree> directive. A form of structure that has data organized hierarchically is a tree. A node in the tree displays each set of data. The Component Dev Kit Tree was replaced with the Angular Material Tree, which is an enhancement (CDK-tree). A single data node can be expanded or collapsed into multiple data nodes using a Tree structure that is presented on the user interface (UI). A JSON object is used to dynamically build the tree. Trees come in two types:
- Flat Tree
- Nested Tree
- Install Angular Material using the below command
ng add @angular/material
2. Adding Mat-tree Component
– We need to import the Flat Tree component into our component file in order to use it:
import { FlatTreeControl } from '@angular/cdk/tree';
– We need to import the Nested Tree component into our component file in order to use it:
import { NestedTreeControl } from '@angular/cdk/tree';
– We need to import the Material Tree module into the app.module.ts file in order to use it:
import {MatTreeModule} from '@angular/material/tree';
Add the MatTreeModule to the NgModule imports array as well after using the import statement.
Flat Tree
A flat tree is a tree in which each node is sequentially presented on the DOM. The resulting tree features expandable/collapsible nodes, and DOM is reduced to a single-depth list.
Syntax :
<mat-tree> <mat-tree-node> Parent node name </mat-tree-node> <mat-tree-node> Child Node 1 </mat-tree-node> <mat-tree-node> Child Node 2 </mat-tree-node> </mat-tree>
Project Structure: The project structure will look like this after successful installation
Add the Below code in flat-node-tree.component.ts
import { Component, OnInit } from "@angular/core"; import { FlatTreeControl } from "@angular/cdk/tree"; import { MatTreeFlatDataSource, MatTreeFlattener }from "@angular/material/tree"; interface Family { name: string; children?: Family[]; } const FAMILY_TREE: Family[] = [ { name: "Joyce", children: [ { name: "Mike" }, { name: "Will" }, { name: "Eleven", children: [{ name: "Hopper" }] }, { name: "Lucas" }, { name: "Dustin", children: [{ name: "Winona" }] }, ], }, { name: "Jean", children: [{ name: "Otis" }, { name: "Maeve" }], }, ]; /** Flat node with expandable and level information */ interface ExampleFlatNode { expandable: boolean; name: string; level: number; } @Component({ selector: "app-flat-node-tree", templateUrl: "./flat-node-tree.component.html", styleUrls: ["./flat-node-tree.component.css"], }) export class FlatNodeTreeComponent implements OnInit { private _transformer = (node: Family, level: number) => { return { expandable: !!node.children && node.children.length > 0, name: node.name, level: level, }; }; treeControl = new FlatTreeControl<ExampleFlatNode>( (node) => node.level, (node) => node.expandable ); treeFlattener = new MatTreeFlattener( this._transformer, (node) => node.level, (node) => node.expandable, (node) => node.children ); dataSource = new MatTreeFlatDataSource( this.treeControl, this.treeFlattener); constructor() { this.dataSource.data = FAMILY_TREE; } hasChild = (_: number, node: ExampleFlatNode) => node.expandable; ngOnInit(): void {} }
Add the Below code in flat-node-tree.component.html
<h1>The Code Hubs</h1> <h3>MatTree Example</h3> <mat-tree [dataSource]="dataSource" [treeControl]="treeControl"> <mat-tree-node *matTreeNodeDef="let node" matTreeNodePadding> <!-- Adding a disabled property to the button so as to give padding to nodes --> <button mat-icon-button disabled></button> {{node.name}} </mat-tree-node> <!-- Tree node template for expandable nodes --> <mat-tree-node *matTreeNodeDef="let node;when: hasChild" matTreeNodePadding> <button mat-icon-button matTreeNodeToggle [attr.aria-label]="'Toggle ' + node.name"> <mat-icon class="mat-icon-rtl-mirror"> {{treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right'}} </mat-icon> </button> {{node.name}} </mat-tree-node> </mat-tree>
Add the Below code in flat-node-tree.component.css
h1, h3 { color: green; font-family: "Roboto", sans-serif; text-align: center; } .mat-tree { background: transparent; } .mat-tree-node { color: black; }
Add it into app.component.html
<app-flat-node-tree></app-flat-node-tree>
Add it into app.module.ts
import { CommonModule } from "@angular/common"; import { NgModule } from "@angular/core"; import { BrowserModule } from "@angular/platform-browser"; import { AppComponent } from "./app.component"; import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; import { FlatNodeTreeComponent } from "./flat-node-tree/flat-node-tree.component"; import { MatTreeModule } from "@angular/material/tree"; import { MatIconModule } from "@angular/material/icon"; @NgModule({ declarations: [AppComponent, FlatNodeTreeComponent], exports: [AppComponent], imports: [ CommonModule, BrowserAnimationsModule, BrowserModule, MatTreeModule, MatIconModule, ], bootstrap: [AppComponent], }) export class AppModule {}
Nested Tree
In DOM, a nested tree is one in which all of the child nodes are placed inside their parent node. When we have a difficult relationship between nodes and a flat tree is incapable of providing the structure necessary, we should use nested trees. Each parent has its own output via which the child nodes are specified.
Syntax:
<mat-tree> <mat-nested-tree-node> Parent node name <mat-nested-tree-node> Child Node 1 </mat-nested-tree-node> <mat-nested-tree-node> Child Node 2 </mat-nested-tree-node> . . . <mat-nested-tree-node> Child Node N </mat-nested-tree-node> </mat-nested-tree-node> </mat-tree>
Project Structure: After successful installation, the project structure will look like the following image:
…….
Add the Below code in nested-tree-example.component.ts
import { Component, OnInit } from "@angular/core"; import { NestedTreeControl } from "@angular/cdk/tree"; import { MatTreeNestedDataSource } from "@angular/material/tree"; interface Smartphone { parent_company: string; sub_brand?: Smartphone[]; } const TREE_DATA: Smartphone[] = [ { parent_company: "Xiaomi", sub_brand: [ { parent_company: "Poco" }, { parent_company: "Redmi" }, { parent_company: "Mijia" }, ], }, { parent_company: "BBK Electronics", sub_brand: [ { parent_company: "Vivo", sub_brand: [{ parent_company: "iQoo" }], }, { parent_company: "Oppo", sub_brand: [{ parent_company: "Realme" }, { parent_company: "Dizo" }], }, ], }, ]; @Component({ selector: "app-nested-tree-example", templateUrl: "./nested-tree-example.component.html", styleUrls: ["./nested-tree-example.component.css"], }) export class NestedTreeExampleComponent implements OnInit { treeControl = new NestedTreeControl<Smartphone>((node) => node.sub_brand); dataSource = new MatTreeNestedDataSource<Smartphone>(); constructor() { this.dataSource.data = TREE_DATA; } hasChild = (_: number, node: Smartphone) => !!node.sub_brand && node.sub_brand.length > 0; ngOnInit(): void {} }
Add the Below code in nested-tree-example.component.html
<h1>The Code Hubs</h1> <h3>Nested Tree Example</h3> <mat-tree [dataSource]="dataSource" [treeControl]="treeControl" class="example-tree"> <mat-tree-node *matTreeNodeDef="let node" matTreeNodeToggle> {{node.parent_company}} </mat-tree-node> <mat-nested-tree-node *matTreeNodeDef="let node; when: hasChild"> <div class="mat-tree-node"> <button mat-icon-button matTreeNodeToggle [attr.aria-label]="'Toggle ' + node.parent_company"> <mat-icon class="mat-icon-rtl-mirror"> {{treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right'}} </mat-icon> </button> {{node.parent_company}} </div> <div [class.example-tree-invisible]="!treeControl.isExpanded(node)" role="group"> <ng-container matTreeNodeOutlet></ng-container> </div> </mat-nested-tree-node> </mat-tree>
Add the Below code in nested-tree-example.component.css
.example-tree-invisible { display: none; } .example-tree ul,.example-tree li { margin-top: 0; margin-bottom: 0; list-style-type: none; } /* This padding sets the alignment of the nested nodes. */ .example-tree .mat-nested-tree-node div[role="group"] { padding-left: 40px; } .example-tree div[role="group"] > .mat-tree-node { padding-left: 40px; } h1,h3 { color: green; font-family: "Roboto", sans-serif; text-align: left; } .mat-tree { background: transparent; } .mat-tree-node { color: black; }
Add it in app.component.cshtml
<app-nested-tree-example> </app-nested-tree-example>
Add it in app.module.ts
import { CommonModule } from "@angular/common"; import { NgModule } from "@angular/core"; import { BrowserModule } from "@angular/platform-browser"; import { AppComponent } from "./app.component"; import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; import { NestedTreeExampleComponent } from "./nested-tree-example/nested-tree-example.component"; import { MatTreeModule } from "@angular/material/tree"; import { MatIconModule } from "@angular/material/icon"; @NgModule({ declarations: [AppComponent, NestedTreeExampleComponent], exports: [AppComponent], imports: [ CommonModule, BrowserAnimationsModule, BrowserModule, MatTreeModule, MatIconModule, ], bootstrap: [AppComponent], }) export class AppModule {}