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

PropTypeDefaultDescription
dataNodeDatarequiredTree data structure
widthnumber | string400Width of the container
heightnumber | string400Height of the container
direction'top' | 'bottom' | 'left' | 'right' | 'radial''top'Direction of tree growth
contentKeystring'name'Key for node content
siblingSpacingnumber50Spacing between siblings
childrenSpacingnumber50Spacing between parent and children
nodeWidthnumber50Width of nodes
nodeHeightnumber30Height of nodes
nodeTemplate(content: unknown) => string-Custom HTML template for nodes
nodeStylestring-CSS styles for nodes
nodeBGColorstring'#FFFFFF'Node background color
nodeBGColorHoverstring'#FFFFFF'Node background color on hover
borderWidthnumber1Node border width
borderStylestring'solid'Node border style
borderRadiusstring'5px'Node border radius
borderColorstring'#BCBCBC'Node border color
borderColorHoverstring'#5C6BC0'Node border color on hover
edgeWidthnumber1Edge line width
edgeColorstring'#BCBCBC'Edge line color
edgeColorHoverstring'#5C6BC0'Edge line color on hover
fontSizestring'14px'Font size
fontFamilystring-Font family
fontWeightstring'400'Font weight
fontColorstring'#000000'Font color
highlightOnHoverbooleantrueEnable highlight on hover
enableToolbarbooleanfalseShow toolbar
enableExpandCollapsebooleanfalseEnable expand/collapse buttons
enableTooltipbooleanfalseEnable tooltips
tooltipTemplate(content: unknown) => string-Custom tooltip template
groupLeafNodesbooleanfalseStack leaf nodes
onNodeClick(node: NodeData) => void-Node click handler
classNamestring-CSS class for container
styleCSSProperties-Inline styles for container
canvasStylestring-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

MethodDescription
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";

GitHub