Vue ApexTree

Installation

npm install vue-apextree apextree

Note: apextree is a peer dependency and must be installed alongside vue-apextree.

Demo

View Demo Project created using vue-apextree

Basic Usage

<script setup lang="ts">
import { ApexTreeChart, type NodeData } from 'vue-apextree';

const data: NodeData = {
  id: '1',
  name: 'CEO',
  children: [
    {
      id: '2',
      name: 'CTO',
      children: [
        { id: '3', name: 'Dev Lead' },
        { id: '4', name: 'QA Lead' },
      ],
    },
    {
      id: '5',
      name: 'CFO',
    },
  ],
};
</script>

<template>
  <ApexTreeChart
    :data="data"
    :width="800"
    :height="600"
    direction="top"
    :node-width="120"
    :node-height="80"
  />
</template>

Setting License Key

If you have a commercial license, set it once at app initialization:

// main.ts
import { setApexTreeLicense } from 'vue-apextree';

setApexTreeLicense('your-license-key');

Using Template Ref Methods

Access methods like changeLayout, collapse, expand, and fitScreen via template ref:

<script setup lang="ts">
import { ref } from 'vue';
import { ApexTreeChart, type ApexTreeExpose } from 'vue-apextree';

const treeRef = ref<ApexTreeExpose | null>(null);

const handleChangeLayout = () => {
  treeRef.value?.changeLayout('left');
};

const handleCollapse = (nodeId: string) => {
  treeRef.value?.collapse(nodeId);
};

const handleExpand = (nodeId: string) => {
  treeRef.value?.expand(nodeId);
};

const handleFitScreen = () => {
  treeRef.value?.fitScreen();
};
</script>

<template>
  <div>
    <button @click="handleChangeLayout">Change Layout</button>
    <button @click="handleFitScreen">Fit Screen</button>

    <ApexTreeChart
      ref="treeRef"
      :data="data"
      :width="800"
      :height="600"
    />
  </div>
</template>

Custom Node Templates

<script setup lang="ts">
import { ApexTreeChart } from 'vue-apextree';

interface PersonData {
  name: string;
  imageURL: string;
}

const nodeTemplate = (content: unknown): string => {
  const person = content as PersonData;
  return `
    <div style="display: flex; flex-direction: column; align-items: center; height: 100%;">
      <img 
        src="${person.imageURL}" 
        style="width: 50px; height: 50px; border-radius: 50%;" 
      />
      <div style="font-weight: bold;">${person.name}</div>
    </div>
  `;
};
</script>

<template>
  <ApexTreeChart
    :data="data"
    :width="800"
    :height="600"
    content-key="data"
    :node-width="150"
    :node-height="100"
    :node-template="nodeTemplate"
  />
</template>

Reactivity

The component automatically re-renders when props change, including deep changes to the data object:

<script setup lang="ts">
import { ref } from 'vue';
import { ApexTreeChart, type NodeData } from 'vue-apextree';

const data = ref<NodeData>({
  id: '1',
  name: 'Root',
  children: [],
});

// this will trigger a re-render
const addChild = () => {
  data.value.children?.push({
    id: String(Date.now()),
    name: 'New Node',
  });
};
</script>

<template>
  <button @click="addChild">Add Child</button>
  <ApexTreeChart :data="data" :width="800" :height="600" />
</template>

Events

<script setup lang="ts">
import { ApexTreeChart, type NodeData } from 'vue-apextree';

const handleNodeClick = (node: NodeData) => {
  console.log('Node clicked:', node);
};
</script>

<template>
  <ApexTreeChart
    :data="data"
    :width="800"
    :height="600"
    @node-click="handleNodeClick"
  />
</template>

Props

PropTypeDefaultDescription
dataNodeDatarequiredTree data structure
widthnumber | string400Width of the container
heightnumber | string400Height of the container
direction'top' | 'bottom' | 'left' | 'right''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

Events

EventPayloadDescription
node-clickNodeDataEmitted when a node is clicked

Exposed Methods

MethodDescription
changeLayout(direction?)Change tree direction
collapse(nodeId)Collapse a node
expand(nodeId)Expand a node
fitScreen()Fit tree to screen
getGraph()Get the underlying graph instance

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,
  ApexTreeExpose,
  NodeData,
  NodeOptions,
  TreeDirection,
  GraphInstance,
} from 'vue-apextree';