Expand and Collapse Nodes in Angular Diagram Component
29 Aug 202518 minutes to read
The Angular Diagram component provides built-in support for expanding and collapsing nodes, enabling users to create hierarchical views where child nodes can be hidden or shown dynamically. This functionality is particularly useful for organizational charts, mind maps, and tree structures where managing visual complexity is essential.
The expand and collapse feature allows users to:
- Compress hierarchical views to show only root elements
- Toggle visibility of child nodes interactively
- Customize the appearance of expand and collapse icons
- Control the initial state of nodes programmatically
Key properties
The following properties control the expand and collapse behavior of nodes:
- expandIcon - Defines the icon displayed when a node can be expanded
- collapseIcon - Defines the icon displayed when a node can be collapsed
- isExpanded - Determines whether the node is currently expanded or collapsed
NOTE
Icons are only created when the node has outgoing edges (outEdges).
For detailed API information, refer to expandIcon and collapseIcon.
Customizing expand and collapse icons
Size and shape configuration
Define the size of icons using the width and height properties.
The shape property of expandIcon and collapseIcon allows customization of the icon appearance.
The following code example demonstrates how to create icons with various shapes:
import {
DiagramModule,
HierarchicalTreeService,
DataBindingService,
LayoutAnimationService,
DiagramComponent,
Diagram,
NodeModel,
ConnectorModel,
SelectorModel,
SelectorConstraints,
SnapSettingsModel,
LayoutModel,
DataSourceModel,
DecoratorModel,
ShapeStyleModel,
TreeInfo,
} from '@syncfusion/ej2-angular-diagrams';
import { Component, ViewEncapsulation, ViewChild } from '@angular/core';
import { DataManager, Query } from '@syncfusion/ej2-data';
@Component({
imports: [DiagramModule],
providers: [
HierarchicalTreeService,
DataBindingService,
LayoutAnimationService,
],
standalone: true,
selector: 'app-container',
template: `<ejs-diagram #diagram id="diagram" width="100%" height="580px" [getNodeDefaults]="getNodeDefaults" [getConnectorDefaults]="getConnectorDefaults" [snapSettings]="snapSettings" [selectedItems]="selectedItems" [layout]="layout" [dataSourceSettings]="dataSourceSettings">
</ejs-diagram>`,
encapsulation: ViewEncapsulation.None,
})
export class AppComponent {
@ViewChild('diagram')
public diagram?: DiagramComponent;
public selectedItems?: SelectorModel;
public snapSettings?: SnapSettingsModel;
public items?: DataManager;
public layout?: LayoutModel;
public dataSourceSettings?: DataSourceModel;
//Initializes data source
public data: object[] = [
{
Id: 'parent1',
Name: 'Maria ',
Designation: 'Managing Director',
RatingColor: '#C34444',
},
{
Id: 'parent',
Name: ' sam',
Designation: 'Managing Director',
ReportingPerson: 'parent1',
RatingColor: '#C34444',
},
];
//Sets the default properties for all the Nodes
public getNodeDefaults(obj: NodeModel | any, diagram: Diagram): NodeModel {
(obj.height = 40),
(obj.width = 100),
(obj.expandIcon = {
height: 15,
width: 15,
shape: 'Minus',
fill: 'lightgray',
offset: {
x: 0.5,
y: 0.85,
},
});
obj.collapseIcon.offset = {
x: 0.5,
y: 0.85,
};
obj.collapseIcon.height = 15;
obj.collapseIcon.width = 15;
obj.collapseIcon.shape = 'Plus';
obj.borderColor = 'white';
obj.backgroundColor = '#6BA5D7';
obj.borderWidth = 1;
obj.style = {
fill: 'transparent',
strokeWidth: 2,
};
return obj;
}
//Sets the default properties for all the connectors
public getConnectorDefaults(
connector: ConnectorModel,
diagram: Diagram
): ConnectorModel {
connector.style = {
strokeColor: '#6BA5D7',
strokeWidth: 2,
};
(
((connector as ConnectorModel).targetDecorator as DecoratorModel)
.style as ShapeStyleModel
).fill = '#6BA5D7';
(
((connector as ConnectorModel).targetDecorator as DecoratorModel)
.style as ShapeStyleModel
).strokeColor = '#6BA5D7';
((connector as ConnectorModel).targetDecorator as DecoratorModel).shape =
'None';
connector.type = 'Orthogonal';
return connector;
}
ngOnInit(): void {
this.selectedItems = {
constraints: ~SelectorConstraints.ResizeAll,
};
this.snapSettings = {
constraints: 0,
};
this.items = new DataManager(this.data as JSON[], new Query().take(7));
//Uses layout to auto-arrange nodes on the Diagram page
this.layout = {
// set enableAnimation as true
enableAnimation: true,
type: 'HierarchicalTree',
margin: {
top: 20,
}, // define the getLayoutInfo
getLayoutInfo: (node: Node, tree: TreeInfo | any) => {
if (!tree.hasSubTree) {
tree.orientation = 'vertical';
tree.type = 'alternate';
}
},
};
//Configures data source for Diagram
this.dataSourceSettings = {
id: 'Id',
parentId: 'ReportingPerson',
dataSource: this.items,
};
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Styling and appearance
Customize the visual appearance of icons using the following properties:
-
borderColor- Sets the border color -
borderWidth- Defines the border thickness -
fill- Sets the background color -
cornerRadius- Rounds the corners of the icon -
iconColor- Sets the stroke color of the icon
Icons can be precisely positioned relative to node boundaries using margin, offset, horizontalAlignment, and verticalAlignment settings. While combining all four alignment properties provides maximum control, it requires careful consideration of their interactions.
The following code example illustrates comprehensive icon customization:
import {
DiagramModule,
HierarchicalTreeService,
DataBindingService,
LayoutAnimationService,
DiagramComponent,
Diagram,
NodeModel,
ConnectorModel,
SelectorModel,
SelectorConstraints,
SnapSettingsModel,
LayoutModel,
DataSourceModel,
DecoratorModel,
ShapeStyleModel,
TreeInfo,
} from '@syncfusion/ej2-angular-diagrams';
import { Component, OnInit, ViewEncapsulation, ViewChild } from '@angular/core';
import { DataManager, Query } from '@syncfusion/ej2-data';
@Component({
imports: [DiagramModule],
providers: [
HierarchicalTreeService,
DataBindingService,
LayoutAnimationService,
],
standalone: true,
selector: 'app-container',
template: `<ejs-diagram #diagram id="diagram" width="100%" height="580px" [getNodeDefaults]="getNodeDefaults" [getConnectorDefaults]="getConnectorDefaults" [snapSettings]="snapSettings" [selectedItems]="selectedItems" [layout]="layout" [dataSourceSettings]="dataSourceSettings">
</ejs-diagram>`,
encapsulation: ViewEncapsulation.None,
})
export class AppComponent {
@ViewChild('diagram')
public diagram?: DiagramComponent;
public selectedItems?: SelectorModel;
public snapSettings?: SnapSettingsModel;
public items?: DataManager;
public layout?: LayoutModel;
public dataSourceSettings?: DataSourceModel;
//Initializes data source
public data: object[] = [
{
Id: 'parent1',
Name: 'Maria ',
Designation: 'Managing Director',
RatingColor: '#C34444',
},
{
Id: 'parent',
Name: ' sam',
Designation: 'Managing Director',
ReportingPerson: 'parent1',
RatingColor: '#C34444',
},
];
//Sets the default properties for all the Nodes
public getNodeDefaults(obj: NodeModel | any, diagram: Diagram): NodeModel {
(obj.height = 40),
(obj.width = 100),
(obj.expandIcon = {
shape: 'ArrowUp',
width: 20,
height: 20,
fill: 'red',
borderColor: 'blue',
iconColor: 'white',
cornerRadius: 7,
borderWidth: 2.5,
offset: {
x: 0.5,
y: 0.85,
},
});
obj.collapseIcon = {
offset: {
x: 0.5,
y: 0.85,
},
shape: 'ArrowDown',
width: 20,
height: 20,
fill: 'green',
borderColor: 'blue',
iconColor: 'white',
cornerRadius: 7,
borderWidth: 2.5,
};
obj.collapseIcon.height = 15;
obj.collapseIcon.width = 15;
obj.borderColor = 'white';
obj.backgroundColor = '#6BA5D7';
obj.borderWidth = 1;
obj.style = {
fill: 'transparent',
strokeWidth: 2,
};
return obj;
}
//Sets the default properties for all the connectors
public getConnectorDefaults(
connector: ConnectorModel,
diagram: Diagram
): ConnectorModel {
connector.style = {
strokeColor: '#6BA5D7',
strokeWidth: 2,
};
(
((connector as ConnectorModel).targetDecorator as DecoratorModel)
.style as ShapeStyleModel
).fill = '#6BA5D7';
(
((connector as ConnectorModel).targetDecorator as DecoratorModel)
.style as ShapeStyleModel
).strokeColor = '#6BA5D7';
((connector as ConnectorModel).targetDecorator as DecoratorModel).shape =
'None';
connector.type = 'Orthogonal';
return connector;
}
ngOnInit(): void {
this.selectedItems = {
constraints: ~SelectorConstraints.ResizeAll,
};
this.snapSettings = {
constraints: 0,
};
this.items = new DataManager(this.data as JSON[], new Query().take(7));
//Uses layout to auto-arrange nodes on the Diagram page
this.layout = {
// set enableAnimation as true
enableAnimation: true,
type: 'HierarchicalTree',
margin: {
top: 20,
}, // define the getLayoutInfo
getLayoutInfo: (node: Node, tree: TreeInfo | any) => {
if (!tree.hasSubTree) {
tree.orientation = 'vertical';
tree.type = 'alternate';
}
},
};
//Configures data source for Diagram
this.dataSourceSettings = {
id: 'Id',
parentId: 'ReportingPerson',
dataSource: this.items,
};
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Managing node expansion state
The isExpanded property controls whether a node displays its child nodes. When set to true, child nodes are visible; when false, they are hidden.
Default value: true
The following example demonstrates how to configure the expansion state of nodes:
export class AppComponent {
@ViewChild("diagram")
public diagram: DiagramComponent;
public nodes: NodeModel[] = [
{
id: 'parentNode',
width: 140,
height: 50,
offsetX: 300,
offsetY: 50,
// Set initial state to collapsed
isExpanded: false,
expandIcon: {
shape: 'ArrowDown',
width: 20,
height: 15
},
collapseIcon: {
shape: 'ArrowUp',
width: 20,
height: 15
}
}
];
}