Angular ApexTree
Installation
npm install ngx-apextree apextree
Demo
View Demo Project created using ngx-apextree
Usage
Basic Example
// app.component.ts
import { Component } from '@angular/core';
import { NgxApextreeComponent, TreeNode, ApexTreeOptions } from 'ngx-apextree';
@Component({
selector: 'app-root',
standalone: true,
imports: [NgxApextreeComponent],
template: `
<ngx-apextree
="treeData"
="treeOptions"
(nodeClick)="onNodeClick($event)"
(graphReady)="onGraphReady($event)"
>
</ngx-apextree>
`,
})
export class AppComponent {
treeData: TreeNode = {
id: '1',
name: 'CEO',
children: [
{
id: '2',
name: 'CTO',
children: [
{ id: '3', name: 'Dev Lead' },
{ id: '4', name: 'QA Lead' },
],
},
{
id: '5',
name: 'CFO',
},
],
};
treeOptions: ApexTreeOptions = {
width: 800,
height: 600,
nodeWidth: 150,
nodeHeight: 60,
direction: 'top',
childrenSpacing: 80,
siblingSpacing: 30,
};
onNodeClick(event: any) {
console.log('Node clicked:', event.node);
}
onGraphReady(graph: any) {
console.log('Graph ready:', graph);
}
}
Custom Node Template
Use Angular's ng-template for custom node rendering:
@Component({
selector: 'app-root',
standalone: true,
imports: [NgxApextreeComponent],
template: `
<ngx-apextree ="treeData" ="treeOptions">
<ng-template #nodeTemplate let-content>
<div class="custom-node">
<img ="content.imageURL" alt="" />
<span>{{ content.name }}</span>
</div>
</ng-template>
</ngx-apextree>
`,
styles: [
`
.custom-node {
display: flex;
align-items: center;
gap: 8px;
height: 100%;
padding: 0 10px;
}
.custom-node img {
width: 40px;
height: 40px;
border-radius: 50%;
}
`,
],
})
export class AppComponent {
treeData: TreeNode = {
id: '1',
data: {
name: 'John Doe',
imageURL: 'https://i.pravatar.cc/300?img=68',
},
children: [
{
id: '2',
data: {
name: 'Jane Smith',
imageURL: 'https://i.pravatar.cc/300?img=69',
},
},
],
};
treeOptions: ApexTreeOptions = {
contentKey: 'data',
width: 800,
height: 600,
nodeWidth: 180,
nodeHeight: 60,
};
}
Custom Tooltip Template
You can provide a custom tooltip using the tooltipTemplate option:
@Component({
selector: 'app-root',
standalone: true,
imports: [NgxApextreeComponent],
template: ` <ngx-apextree ="treeData" ="treeOptions"></ngx-apextree> `,
})
export class AppComponent {
treeData: TreeNode = {
id: '1',
data: {
name: 'John Doe',
role: 'CEO',
email: 'john@company.com',
},
children: [
{
id: '2',
data: {
name: 'Jane Smith',
role: 'CTO',
email: 'jane@company.com',
},
},
],
};
treeOptions: ApexTreeOptions = {
contentKey: 'data',
width: 800,
height: 600,
enableTooltip: true,
tooltipTemplate: (content: any) => {
return `
<div style="padding: 10px;">
<strong>${content.name}</strong>
<p>${content.role}</p>
<p>${content.email}</p>
</div>
`;
},
};
}
Alternatively, use Angular's ng-template for tooltip rendering:
<ngx-apextree ="treeData" ="{ enableTooltip: true }">
<ng-template #tooltipTemplate let-content>
<div class="custom-tooltip">
<strong>{{ content.name }}</strong>
<p>{{ content.description }}</p>
</div>
</ng-template>
</ngx-apextree>
Graph Methods
Access graph methods through component reference or the emitted graph instance:
@Component({
template: `
<ngx-apextree
#tree
="treeData"
="treeOptions"
(graphReady)="onGraphReady($event)"
>
</ngx-apextree>
<button (click)="changeDirection()">Change Direction</button>
<button (click)="fit()">Fit Screen</button>
`,
})
export class AppComponent {
@ViewChild('tree') tree!: NgxApextreeComponent;
private graph: any;
onGraphReady(graph: any) {
this.graph = graph;
}
changeDirection() {
// using component method
this.tree.changeLayout('left');
// or using graph instance directly
// this.graph.changeLayout('left');
}
fit() {
this.tree.fitScreen();
}
}
License Setup
If you have a commercial license, set it once at app initialization.
Option 1: Angular Provider (Recommended)
Standalone App:
// app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideApexTreeLicense } from 'ngx-apextree';
export const appConfig: ApplicationConfig = {
providers: [provideApexTreeLicense('your-license-key-here')],
};
Module-based App:
// app.module.ts
import { NgModule } from '@angular/core';
import { provideApexTreeLicense } from 'ngx-apextree';
@NgModule({
providers: [provideApexTreeLicense('your-license-key-here')],
})
export class AppModule {}
Option 2: Static Method
// main.ts
import { bootstrapApplication } from '@angular/platform-browser';
import { setApexTreeLicense } from 'ngx-apextree';
import { AppComponent } from './app/app.component';
import { appConfig } from './app/app.config';
// set license before bootstrapping
setApexTreeLicense('your-license-key-here');
bootstrapApplication(AppComponent, appConfig);
API
Inputs
| Input | Type | Description |
|---|---|---|
data | TreeNode | Tree data structure |
options | ApexTreeOptions | Configuration options |
Outputs
| Output | Type | Description |
|---|---|---|
nodeClick | NodeClickEvent | Emits when a node is clicked |
graphReady | ApexTreeGraph | Emits after initial render |
graphUpdated | ApexTreeGraph | Emits after data/options update |
Content Templates
| Template | Context | Description |
|---|---|---|
#nodeTemplate | $implicit: content | Custom node HTML |
#tooltipTemplate | $implicit: content | Custom tooltip HTML |
Component Methods
| Method | Parameters | Description |
|---|---|---|
changeLayout | direction: TreeDirection | Change tree direction |
collapse | nodeId: string | Collapse a node |
expand | nodeId: string | Expand a node |
expandAll | - | Expand every node in one reflow |
collapseAll | - | Collapse every node, leaving the root visible |
expandToDepth | depth: number | Show the tree down to a depth (root = 0) |
updateData | data: NestedNode | Diff against a new dataset and spring to it |
focus | nodeId: string | Spotlight a node's lineage and subtree |
clearFocus | - | Remove the spotlight |
setActivePath | nodeIds: string[] | Flow a marching dash along the root-to-node path |
clearActivePath | - | Clear the active-path flow |
toggleCard | nodeId: string | Toggle a node's expanded card |
zoom | factor: number | Zoom by a fraction of the current scale (positive in, negative out) |
centerOnNode | nodeId: string | Center the camera on a node |
fitScreen | - | Fit graph to screen |
getGraph | - | Get graph instance for the full API |
render | - | Manually re-render |
A change to the data input reconciles into the live tree instead of rebuilding it, so surviving nodes spring to their new positions while collapse state, selection, focus and expanded cards survive. A change to the options input rebuilds the instance, since options are read at construction. See Live Data Updates.