indented-tree.tsx
Overview
The indented-tree.tsx file implements a customizable, interactive indented tree visualization component using React and the AntV G6 graph visualization library. It provides a horizontally laid-out tree structure where nodes are visually indented according to their depth, and supports user interactions such as node collapse/expand, selection, and hover effects.
Key features include:
Custom node (
IndentedNode) and edge (IndentedEdge) definitions tailored for an indented tree layout.A behavior (
CollapseExpandTree) to manage collapse and expand interactions with animated graph updates.A React component (
IndentedTree) that renders the tree graph within a container, handling data updates and theming.Integration with AntV G6 for graph rendering and layout, and React Error Boundary for robust error handling.
This file is intended for use in applications needing a visually clear, interactive tree visualization with collapsible nodes and smooth user experience.
Classes and Components
1. IndentedNode (extends BaseNode)
Custom node class representing a single node in the indented tree.
Properties
static defaultStyleProps: Default style properties including port positions (inon right-bottom,outon left-bottom).childrenData: Getter returning child nodes data from the context model.Other inherited properties from
BaseNode.
Key Methods
constructor(options: any)
Initializes node with default style props merged into options.
getKeyStyle(attributes: any): object
Returns style for the key shape (invisible rectangle covering the node).
Combines base key style with node size and transparent fill.
drawKeyShape(attributes: any, container: any): Rect
Draws or updates the key shape using
Rect.
getLabelStyle(attributes: any): object | false
Returns label style if label should be shown, otherwise
false.
drawIconArea(attributes: any, container: any): Rect
Draws an invisible rectangular area under the node to capture interaction events.
forwardEvent(target: any, type: any, listener: any): void
Adds event listener on a target element if not already bound.
getCountStyle(attributes: any): object | false
Returns style for a badge showing the count of children when node is collapsed.
Returns
falseif node is expanded.
drawCountShape(attributes: any, container: any): Badge
Draws the badge showing number of collapsed children and attaches click event to expand node.
isShowCollapse(attributes: any): boolean
Returns true if node is expanded and has children to show the collapse icon.
getCollapseStyle(attributes: any): object | false
Returns style for the collapse/expand icon badge when node is expanded.
drawCollapseShape(attributes: any, container: any): Badge
Draws the collapse/expand icon badge and attaches click event to toggle collapse state.
getAddStyle(attributes: any): object | false
Returns style for an "add" icon (not fully used in this code).
render(attributes: any = this.parsedAttributes, container: any = this): void
Renders the node by calling base render, and drawing count badge, icon area, and collapse shape.
Usage Example
const node = new IndentedNode({
id: 'node1',
style: { color: '#5B8FF9', labelText: 'Node 1' },
});
node.render();
2. IndentedEdge (extends Polyline)
Custom edge class for edges in the indented tree.
Methods
getControlPoints(attributes, sourcePoint, targetPoint): Point[]
Overrides control points to create a vertical then horizontal elbow connector.
Control points: horizontal coordinate from source, vertical coordinate from target, creating an L-shape edge.
Usage Example
Edges connecting nodes will be instances of IndentedEdge with smooth elbow curves.
3. CollapseExpandTree (extends BaseBehavior)
Behavior class managing collapse/expand interactions on tree nodes.
Constructor
constructor(context: any, options: any)
Initializes the behavior and binds event listeners.
Methods
update(options: any): void
Rebinds event listeners on update.
bindEvents(): void
Binds graph events:
NodeEvent.POINTER_ENTER: show collapse/expand icons on hover.NodeEvent.POINTER_LEAVE: hide icons on mouse leave.TreeEvent.COLLAPSE_EXPAND: handle collapse/expand action.
unbindEvents(): void
Removes bound event listeners.
showIcon(event: any): void
Shows collapse/expand icon for the target node.
hideIcon(event: any): void
Hides collapse/expand icon for the target node.
setIcon(event: any, show: boolean): void
Updates node style to show or hide icon.
Prevents action if behavior is busy processing.
onCollapseExpand(event: any): Promise
Handles collapse/expand event by calling graph's collapse/expand methods asynchronously.
Sets internal status to prevent race conditions.
Usage
Automatically registered as a graph behavior and used internally by the IndentedTree component.
4. IndentedTree (React Functional Component)
Main React component rendering the indented tree graph.
Props (IProps)
Prop | Type | Description |
|---|---|---|
data |
| Tree data structure to visualize. |
show |
| Controls visibility of the tree container. |
style |
| Additional CSS styles for the container. |
Internal Logic
Uses
useRefto hold container div andGraphinstance.assignIdsrecursively assigns unique IDs to tree nodes if not present (default root ID:'root').renderfunction initializes and configures a newGraphinstance with:Custom node, edge, layout, and behaviors.
Styling that assigns colors based on node depth.
Event behaviors for scrolling, collapse/expand, and selection.
React effect hook calls
renderwhendatachanges and is not empty.Wrapped in an
ErrorBoundaryto catch and display rendering errors gracefully.Uses a custom hook
useIsDarkThemeto adapt colors to dark mode.
Usage Example
<IndentedTree data={treeData} show={true} style={{ height: '600px' }} />
Important Implementation Details
Custom Node & Edge Types:
The file definesIndentedNodeandIndentedEdgeclasses registered with G6 under the'indented'type, enabling the graph to render nodes and edges with specific shapes, styles, and interaction areas.Collapse/Expand Behavior:
TheCollapseExpandTreebehavior listens to node hover and click events to toggle collapse state, updating node styles and triggering graph layout updates.Tree Layout Algorithm:
Uses G6's'indented'layout which lays out nodes horizontally with indentation proportional to depth, producing a nested visual tree.Dynamic Styling Based on Depth:
Node and edge colors are dynamically assigned from a predefined color palette cycling by node depth.React Integration:
The graph lifecycle (creation, destruction) is managed inside React hooks, ensuring proper resource cleanup and re-rendering on data changes.Error Handling:
React Error Boundary wraps the visualization container to catch render errors and display user-friendly messages.
System Interaction
AntV G6 Library:
Core graph rendering, node/edge drawing, layout computation, and event handling.React Application:
This component can be embedded anywhere in a React app, controlled via props.Theme Provider (
useIsDarkTheme):
Adapts visual styles based on application theme (light/dark).Error Boundary:
Ensures UI robustness by catching errors in rendering.Data Flow:
Accepts hierarchicalTreeDataand converts it to graph data usingtreeToGraphDatahelper from G6.Event Emission:
Nodes emit custom events on collapse/expand interaction, which the behavior listens to for graph updates.
Visual Diagram
classDiagram
class IndentedNode {
+childrenData
+getKeyStyle(attributes)
+drawKeyShape(attributes, container)
+getLabelStyle(attributes)
+drawIconArea(attributes, container)
+forwardEvent(target, type, listener)
+getCountStyle(attributes)
+drawCountShape(attributes, container)
+isShowCollapse(attributes)
+getCollapseStyle(attributes)
+drawCollapseShape(attributes, container)
+getAddStyle(attributes)
+render(attributes, container)
}
class IndentedEdge {
+getControlPoints(attributes, sourcePoint, targetPoint)
}
class CollapseExpandTree {
-status: string
+constructor(context, options)
+update(options)
+bindEvents()
+unbindEvents()
+showIcon(event)
+hideIcon(event)
+setIcon(event, show)
+onCollapseExpand(event)
}
class IndentedTree {
+data: TreeData
+show: boolean
+style?: React.CSSProperties
+assignIds(node, parentId, index)
+render(data)
}
IndentedTree "1" *-- "1" CollapseExpandTree : uses
IndentedTree "1" *-- "many" IndentedNode : renders
IndentedTree "1" *-- "many" IndentedEdge : renders
CollapseExpandTree "1" o-- IndentedNode : controls
Summary
The indented-tree.tsx file delivers a sophisticated React component for rendering and interacting with indented tree graphs. It leverages AntV G6's extensibility to define custom nodes and edges, handles user interactions for collapsing and expanding nodes, and integrates seamlessly into React applications with theming and error boundaries. This makes it a powerful and flexible tool for visualizing hierarchical data in a clear and user-friendly manner.