Search and Breadcrumbs
ApexTree includes a built-in search input and breadcrumb trail, plus a programmatic API for building your own search and navigation UI.
Built-in search
enableSearch shows a search input in the toolbar area. Typing filters nodes by their resolved label; matches are highlighted along with their path to the root. Pressing Enter centers the camera on the first match.
const tree = new ApexTree(document.getElementById('chart'), {
enableSearch: true,
enableToolbar: true,
})
tree.render(data)
Keyboard shortcuts (when a11y.enabled is on): / focuses the search input, Esc clears it.
Built-in breadcrumb
enableBreadcrumb shows a breadcrumb trail above the chart. It updates on node click to show the path from root to the clicked node; clicking a segment re-centers the camera on that ancestor.
const tree = new ApexTree(el, {
enableBreadcrumb: true,
})
tree.render(data)
Programmatic search
Build your own search UI with the graph API:
| Method | Description |
|---|---|
findNodesByQuery(query) | Return node ids whose resolved label contains query (case-insensitive); empty query returns none |
setSearchHighlight(matchIds) | Highlight matches and their lineage to root; pass [] to clear |
getNodeLabel(nodeId) | Resolve a node's display label |
centerOnNode(nodeId) | Center the camera on a node at the current zoom |
const graph = tree.render(data)
const input = document.getElementById('my-search')
input.addEventListener('input', () => {
const matches = graph.findNodesByQuery(input.value)
graph.setSearchHighlight(matches)
})
input.addEventListener('keydown', (e) => {
if (e.key === 'Enter') {
const matches = graph.findNodesByQuery(input.value)
if (matches.length) graph.centerOnNode(matches[0])
}
})
Custom breadcrumb
setBreadcrumbHandler(handler) registers a callback invoked with the clicked node id on every node click. Combine it with getNodeMap() to walk from the node up to the root and render your own trail:
const graph = tree.render(data)
graph.setBreadcrumbHandler((nodeId) => {
if (!nodeId) return
const map = graph.getNodeMap()
// walk up to the root
const path = []
let current = nodeId
while (current) {
path.unshift(map[current].name)
current = map[current].parent
}
document.getElementById('crumbs').textContent = path.join(' › ')
})
Pass null to setBreadcrumbHandler to unregister.
Building a jump-to-node picker
const graph = tree.render(data)
// populate a datalist with every node label
const map = graph.getNodeMap()
const list = document.getElementById('node-list')
Object.values(map).forEach((node) => {
const opt = document.createElement('option')
opt.value = node.name
list.appendChild(opt)
})
document.getElementById('jump').addEventListener('change', (e) => {
const matches = graph.findNodesByQuery(e.target.value)
if (matches.length) {
graph.setSearchHighlight(matches)
graph.centerOnNode(matches[0])
}
})
Localizing search and breadcrumb text
The search placeholder, aria-labels, match-count text, and breadcrumb label are all overridable via locale.messages. See Localization and RTL for the full TreeMessages reference.
const tree = new ApexTree(el, {
enableSearch: true,
enableBreadcrumb: true,
locale: {
messages: {
searchPlaceholder: 'Rechercher…',
searchMatchCount: (n) => `${n} résultat${n === 1 ? '' : 's'}`,
breadcrumbAriaLabel: 'Chemin',
},
},
})
React example
import { useRef, useState } from 'react'
import { ApexTreeChart } from 'react-apextree'
import type { ApexTreeRef } from 'react-apextree'
export default function SearchableTree() {
const ref = useRef<ApexTreeRef>(null)
const [query, setQuery] = useState('')
const runSearch = (q: string) => {
setQuery(q)
const graph = ref.current?.getGraph()
if (!graph) return
const matches = graph.findNodesByQuery?.(q) ?? []
graph.setSearchHighlight?.(matches)
if (q && matches.length) graph.centerOnNode?.(matches[0])
}
return (
<div>
<input
value={query}
onChange={(e) => runSearch(e.target.value)}
placeholder="Search nodes…"
/>
<ApexTreeChart
ref={ref}
data={data}
options={{ enableBreadcrumb: true }}
/>
</div>
)
}