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

InputTypeDescription
dataTreeNodeTree data structure
optionsApexTreeOptionsConfiguration options

Outputs

OutputTypeDescription
nodeClickNodeClickEventEmits when a node is clicked
graphReadyApexTreeGraphEmits after initial render
graphUpdatedApexTreeGraphEmits after data/options update

Content Templates

TemplateContextDescription
#nodeTemplate$implicit: contentCustom node HTML
#tooltipTemplate$implicit: contentCustom tooltip HTML

Component Methods

MethodParametersDescription
changeLayoutdirection: TreeDirectionChange tree direction
collapsenodeId: stringCollapse a node
expandnodeId: stringExpand a node
expandAll-Expand every node in one reflow
collapseAll-Collapse every node, leaving the root visible
expandToDepthdepth: numberShow the tree down to a depth (root = 0)
updateDatadata: NestedNodeDiff against a new dataset and spring to it
focusnodeId: stringSpotlight a node's lineage and subtree
clearFocus-Remove the spotlight
setActivePathnodeIds: string[]Flow a marching dash along the root-to-node path
clearActivePath-Clear the active-path flow
toggleCardnodeId: stringToggle a node's expanded card
zoomfactor: numberZoom by a fraction of the current scale (positive in, negative out)
centerOnNodenodeId: stringCenter 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.