React ApexTree
Installation
npm install react-apextree apextree
Note: apextree is a peer dependency and must be installed alongside react-apextree.
Demo
View Demo Project created using react-apextree
Basic Usage
import { ApexTreeChart } from "react-apextree";
const data = {
id: "1",
name: "CEO",
children: [
{
id: "2",
name: "CTO",
children: [
{ id: "3", name: "Dev Lead" },
{ id: "4", name: "QA Lead" },
],
},
{
id: "5",
name: "CFO",
},
],
};
function App() {
return (
<ApexTreeChart
data={data}
width={800}
height={600}
direction="top"
nodeWidth={120}
nodeHeight={80}
/>
);
}
Setting License Key
If you have a commercial license, set it once at app initialization:
import { setApexTreeLicense } from 'react-apextree';
// call at app initialization before rendering any charts
setApexTreeLicense('your-license-key-here');
Using Imperative Methods
Access methods like changeLayout, collapse, expand, and fitScreen via ref:
import { useRef } from "react";
import { ApexTreeChart, ApexTreeRef } from "react-apextree";
function App() {
const treeRef = useRef<ApexTreeRef>(null);
const handleChangeLayout = () => {
treeRef.current?.changeLayout("left");
};
const handleCollapse = (nodeId: string) => {
treeRef.current?.collapse(nodeId);
};
const handleExpand = (nodeId: string) => {
treeRef.current?.expand(nodeId);
};
const handleFitScreen = () => {
treeRef.current?.fitScreen();
};
return (
<div>
<button onClick={handleChangeLayout}>Change Layout</button>
<button onClick={handleFitScreen}>Fit Screen</button>
<ApexTreeChart ref={treeRef} data={data} width={800} height={600} />
</div>
);
}
Custom Node Templates
<ApexTreeChart
data={data}
width={800}
height={600}
contentKey="data"
nodeWidth={150}
nodeHeight={100}
nodeTemplate={(content) => `
<div style="display: flex; flex-direction: column; align-items: center; height: 100%;">
<img
src="${content.imageURL}"
style="width: 50px; height: 50px; border-radius: 50%;"
/>
<div style="font-weight: bold;">${content.name}</div>
</div>
`}
/>
Props
| Prop | Type | Default | Description |
|---|---|---|---|
data | NodeData | required | Tree data structure |
width | number | string | 400 | Width of the container |
height | number | string | 400 | Height of the container |
direction | 'top' | 'bottom' | 'left' | 'right' | 'radial' | 'top' | Direction of tree growth |
contentKey | string | 'name' | Key for node content |
siblingSpacing | number | 50 | Spacing between siblings |
childrenSpacing | number | 50 | Spacing between parent and children |
nodeWidth | number | 50 | Width of nodes |
nodeHeight | number | 30 | Height of nodes |
nodeTemplate | (content: unknown) => string | - | Custom HTML template for nodes |
nodeStyle | string | - | CSS styles for nodes |
nodeBGColor | string | '#FFFFFF' | Node background color |
nodeBGColorHover | string | '#FFFFFF' | Node background color on hover |
borderWidth | number | 1 | Node border width |
borderStyle | string | 'solid' | Node border style |
borderRadius | string | '5px' | Node border radius |
borderColor | string | '#BCBCBC' | Node border color |
borderColorHover | string | '#5C6BC0' | Node border color on hover |
edgeWidth | number | 1 | Edge line width |
edgeColor | string | '#BCBCBC' | Edge line color |
edgeColorHover | string | '#5C6BC0' | Edge line color on hover |
fontSize | string | '14px' | Font size |
fontFamily | string | - | Font family |
fontWeight | string | '400' | Font weight |
fontColor | string | '#000000' | Font color |
highlightOnHover | boolean | true | Enable highlight on hover |
enableToolbar | boolean | false | Show toolbar |
enableExpandCollapse | boolean | false | Enable expand/collapse buttons |
enableTooltip | boolean | false | Enable tooltips |
tooltipTemplate | (content: unknown) => string | - | Custom tooltip template |
groupLeafNodes | boolean | false | Stack leaf nodes |
onNodeClick | (node: NodeData) => void | - | Node click handler |
className | string | - | CSS class for container |
style | CSSProperties | - | Inline styles for container |
canvasStyle | string | - | CSS styles for canvas |
Updating data
A change to the data prop is reconciled into the live tree rather than rebuilding it. Surviving nodes spring to their new positions, new ids grow in, and departed ones retract, while collapse state, selection, focus and expanded cards all survive.
const [org, setOrg] = useState(initialOrg)
// animates into the new shape; does not tear the chart down
useEffect(() => {
socket.on('org:changed', setOrg)
}, [])
return <ApexTreeChart data={org} options={options} />
A change to the options prop rebuilds the instance, since options are read at construction. Keep options referentially stable (a module constant, or useMemo) so an unrelated re-render does not remount the chart.
See Live Data Updates.
Ref Methods
| Method | Description |
|---|---|
changeLayout(direction?) | Change tree direction |
collapse(nodeId) | Collapse a node |
expand(nodeId) | Expand a node |
expandAll() | Expand every node in one reflow |
collapseAll() | Collapse every node, leaving the root visible |
expandToDepth(depth) | Show the tree down to a depth (root = 0) |
updateData(data) | Diff against a new dataset and spring to it |
focus(nodeId) | Spotlight a node's lineage and subtree |
clearFocus() | Remove the spotlight |
setActivePath(nodeIds) | Flow a marching dash along the root-to-node path |
clearActivePath() | Clear the active-path flow |
toggleCard(nodeId) | Toggle a node's expanded card |
zoom(factor) | Zoom by a fraction of the current scale (positive in, negative out) |
centerOnNode(nodeId) | Center the camera on a node |
fitScreen() | Fit tree to screen |
getGraph() | Get the underlying graph instance for the full API |
getGraph() returns the core Graph, so anything not on the ref handle (expandSubtree, getExpandedCards, getActivePath, exportToSvg, selection and search) is reachable through it. See Methods.
Data Structure
interface NodeData<T = unknown> {
id: string; // unique identifier
name?: string; // display name (or use contentKey)
data?: T; // custom data for templates
options?: NodeOptions; // per-node styling
children?: NodeData<T>[];
}
interface NodeOptions {
nodeBGColor?: string;
nodeBGColorHover?: string;
borderColor?: string;
borderColorHover?: string;
fontSize?: string;
fontFamily?: string;
fontWeight?: string | number;
fontColor?: string;
}
TypeScript Support
Full TypeScript support with exported types:
import type {
ApexTreeProps,
ApexTreeRef,
NodeData,
NodeOptions,
TreeDirection,
GraphInstance,
} from "react-apextree";