Skip to content

@memberjunction/ng-hierarchy-tree

A modern, high-performance, interactive visual hierarchy and organizational chart component for Angular and MemberJunction applications.

Built on top of D3 layout engines, --mj-* design tokens, and MemberJunction’s metadata layer, this component visualizes any self-referencing entity hierarchy with smooth pan/zoom, collapsible sub-branches, live path search, subtree focus, drag-and-drop reparenting, and cancelable before/after lifecycle events.


  • Metadata Driven: Automatically binds to any MemberJunction entity with a self-referencing foreign key (ParentID, ParentCategoryID, ParentAccountID, etc.) and seamlessly handles single and composite primary keys.
  • Interactive Canvas: Smooth D3-powered pan and zoom, mousewheel scaling, auto-fit to container, and compact toolbar controls.
  • Collapsible Subtrees: Interactive [+] / [-] badges displaying both direct child counts and total descendant subtree volume.
  • Instant Search & Path Expansion: Real-time keyword filter that matches node titles and subtitles, highlights matching cards, and automatically expands all ancestor branches up to the root.
  • Subtree Focus: Isolate any node as a temporary root to inspect deep or complex branches with 1-click return to the full hierarchy.
  • Cancelable Before/After Event System: Full programmatic control with BeforeNodeExpand, AfterNodeExpand, BeforeNodeCollapse, AfterNodeCollapse, BeforeReparent, and AfterReparent.
  • Theme Reactive: Styled with standard --mj-* CSS design tokens for dark and light modes.
  • Direct Record Navigation: Integrates with RecordNavigationEvent for opening detail records in MemberJunction Explorer tabs.

Import HierarchyTreeComponent (standalone) or HierarchyTreeModule into your Angular component:

import { Component } from '@angular/core';
import { HierarchyTreeComponent, HierarchyTreeConfig, HierarchyNodeEvent } from '@memberjunction/ng-hierarchy-tree';
import { FormNavigationEvent } from '@memberjunction/ng-base-forms';
@Component({
selector: 'app-org-chart',
standalone: true,
imports: [HierarchyTreeComponent],
template: `
<mj-hierarchy-tree
[Config]="treeConfig"
(NodeClick)="onNodeClick($event)"
(Navigate)="onNavigate($event)">
</mj-hierarchy-tree>
`
})
export class OrgChartComponent {
public treeConfig: HierarchyTreeConfig = {
EntityName: 'MJ_BizApps_Common: Organizations',
ParentField: 'ParentID',
SubtitleField: 'OrganizationType',
DefaultIcon: 'fa-solid fa-building',
DefaultColor: 'var(--mj-brand-primary)',
Height: '600px'
};
public onNodeClick(event: HierarchyNodeEvent): void {
console.log('Node selected:', event.Node.Name);
}
public onNavigate(event: FormNavigationEvent): void {
// Forward to NavigationService or Explorer FormComponent
}
}

⚙️ Configuration Reference (HierarchyTreeConfig)

Section titled “⚙️ Configuration Reference (HierarchyTreeConfig)”
PropertyTypeDefaultDescription
EntityNamestring(Required)The MemberJunction entity name to visualize (e.g. 'MJ_BizApps_Orders: Product Categories').
ParentFieldstring'ParentID'Foreign key field pointing to the parent record. Auto-detected from metadata if omitted.
NameFieldstringEntity NameFieldField to use for the main card title.
SubtitleFieldstringundefinedOptional field for the secondary metadata tag or subtitle.
IconFieldstringundefinedOptional field containing a dynamic Font Awesome icon class or image URL.
DefaultIconstring'fa-solid fa-sitemap'Fallback icon when node does not specify one.
ColorFieldstringundefinedOptional field for a dynamic accent color — a design token is preferred over a hex literal.
DefaultColorstring'var(--mj-brand-primary, #38bdf8)'Fallback accent color. Bound to an inline style, so a var() token resolves at paint time and follows the active theme.
ExtraFilterstringundefinedSQL-like filter string applied to the RunView query (e.g. 'IsActive = 1').
OrderBystring'Name ASC'Sort order for sibling nodes.
FocusRecordIDstringundefinedInitial record ID to focus as subtree root.
Orientation'top-to-bottom' | 'left-to-right''top-to-bottom'Layout direction.
ShowSearchbooleantrueWhether to display the live search input.
ShowToolbarbooleantrueWhether to display the zoom and expansion controls toolbar.
Heightstring'560px'Total container height.

// Cancelable Event Example: Prevent collapsing root nodes
onBeforeNodeCollapse(event: CancelableHierarchyNodeEvent) {
if (event.Node.Depth === 0) {
event.Cancel('Root node must remain expanded');
}
}
  • NodeClick: EventEmitter<HierarchyNodeEvent>
  • NodeDoubleClick: EventEmitter<HierarchyNodeEvent>
  • NodeSelect: EventEmitter<HierarchyNodeEvent>
  • BeforeNodeExpand: EventEmitter<CancelableHierarchyNodeEvent>
  • AfterNodeExpand: EventEmitter<HierarchyNodeEvent>
  • BeforeNodeCollapse: EventEmitter<CancelableHierarchyNodeEvent>
  • AfterNodeCollapse: EventEmitter<HierarchyNodeEvent>
  • BeforeReparent: EventEmitter<CancelableReparentEvent>
  • AfterReparent: EventEmitter<ReparentEvent>
  • NodeAction: EventEmitter<NodeActionEvent>
  • Navigate: EventEmitter<FormNavigationEvent>

Call public methods on HierarchyTreeComponent via @ViewChild:

@ViewChild(HierarchyTreeComponent) treeComponent!: HierarchyTreeComponent;
// Expansion
this.treeComponent.expandAll();
this.treeComponent.collapseAll();
// Navigation & Canvas
this.treeComponent.fitToScreen();
this.treeComponent.zoomIn();
this.treeComponent.zoomOut();
this.treeComponent.resetZoom();
// Focus & Subtrees
this.treeComponent.setFocusRoot('ORG-1234');
this.treeComponent.resetFocus();
// Export
const svgContent = this.treeComponent.exportAsSVG();

This component consumes standard --mj-* design tokens:

  • --mj-bg-surface-sunken: Canvas background
  • --mj-bg-surface-card: Node card background
  • --mj-border-default: Node borders & link curves
  • --mj-text-primary: Node title text
  • --mj-text-secondary: Subtitles & badges
  • --mj-brand-primary: Focus indicators & search match highlights