force-graph.tsx
Overview
force-graph.tsx is a React functional component designed to render an interactive, force-directed graph visualization using the @antv/g6 graph visualization library. It takes graph data as input and displays nodes, edges, and combos (groupings of nodes) with customizable styles, behaviors, and tooltips. The graph supports user interactions such as dragging nodes and canvas, zooming, and collapsing/expanding combos, making it suitable for exploring complex relational data visually.
The component provides a dynamic, responsive container that adjusts to its parent size and toggles visibility based on props. It also leverages memoization and efficient rendering hooks to optimize performance with React.
Detailed Documentation
Component: ForceGraph
Description
ForceGraph renders a force-directed graph visualization. It processes raw input data, constructs the graph elements (nodes, edges, combos), and initializes the G6 Graph instance with configured layouts, styles, and interaction behaviors.
Props
Prop | Type | Description |
|---|---|---|
data |
| The graph data object containing nodes and edges. Expected to have at least |
show |
| Controls whether the graph visualization is visible ( |
Internal State & Refs
containerRef: A React ref pointing to the HTML container<div>where the graph is rendered.graphRef: A React ref holding the G6Graphinstance to preserve the graph state across renders.
Hooks Used
useMemo:Processes incoming
datato generate graph data with nodes, combos, and edges.Uses an imported helper
buildNodesAndCombosto prepare nodes and combos.Memoizes result to avoid unnecessary recalculations unless
datachanges.
useCallback:Defines
renderfunction that initializes or re-initializes the G6 graph instance.Configures graph behaviors, layout, styles, and tooltip plugin.
Destroys any existing graph instance before creating a new one.
Sets graph data and triggers rendering.
useEffect:Calls
renderwhendataorrenderfunction changes.Ensures graph updates when the input data changes.
Methods and Functions
render()
Purpose: Initializes and renders the force-directed graph visualization.
Parameters: None (uses closure variables
containerRef,nextData).Returns: Void.
Details:
Creates a new
Graphinstance from@antv/g6with specified options:container: The DOM node to mount the graph.autoFit,autoResize: Ensures the graph fits and resizes with container.behaviors: Enables drag, zoom, collapse/expand, and hover activation of relations.plugins: Adds a tooltip plugin with customized content based on hovered items.layout: Usescombo-combinedlayout to arrange nodes and combos with padding and spacing.node: Defines node styles including size, label text, font size, placement, and palette grouping by entity type.edge: Styles edges dynamically based on theirweightproperty.
Destroys any existing graph instance to prevent memory leaks.
Sets processed data from
nextDataand triggers graph rendering.
Important Implementation Details
Data Processing: Uses
buildNodesAndCombosutility to transform thenodesarray into a structure compatible with G6 combos (groups of nodes), enabling hierarchical grouping.Tooltip Customization: Tooltip content varies based on the element type (combo, node, edge) and available properties like
label,entity_type,weight, anddescription. Colors are mapped by element type (redfor combos,blackfor nodes,bluefor edges).Dynamic Styling:
Nodes have large sizes (150) and labels centered with font size 40.
Edges' line width scales with their weight but capped at 10.
Graph Behaviors:
Allows dragging nodes and canvas.
Enables zooming.
Supports collapsing and expanding combos.
Activates hover highlighting for relations up to degree 1.
Responsive Design: The graph container fills the parent space (
width: 100%; height: 100%) and can be toggled visible or hidden based on theshowprop.Resource Management: Ensures old graphs are destroyed before creating new instances to avoid resource leaks.
Usage Example
import React, { useState } from 'react';
import ForceGraph from './force-graph';
const sampleData = {
nodes: [
{ id: 'node1', entity_type: 'typeA', label: 'Node 1' },
{ id: 'node2', entity_type: 'typeB', label: 'Node 2' },
],
edges: [
{ source: 'node1', target: 'node2', weight: 3 },
],
};
const App = () => {
const [showGraph, setShowGraph] = useState(true);
return (
<>
<button onClick={() => setShowGraph(!showGraph)}>Toggle Graph</button>
<ForceGraph data={sampleData} show={showGraph} />
</>
);
};
export default App;
Interaction with Other Parts of the System
Data Source: Expects graph data with
nodesandedgesfrom a parent component or data fetching layer.Helper Utility: Imports
buildNodesAndCombosfrom a local./utilmodule to preprocess nodes and combos data.Styling: Uses styles from
index.lessto style the container (classforceContainer).Library Dependencies:
@antv/g6for graph visualization and interactions.lodash/isEmptyfor data validation.React hooks for lifecycle and memoization.
This file acts as the visualization layer in a broader application, likely integrated with data management and UI components that provide the raw graph data.
Visual Diagram
classDiagram
class ForceGraph {
+props: IProps
-containerRef: React.RefObject<HTMLDivElement>
-graphRef: React.RefObject<Graph | null>
-nextData: {nodes: any[], edges: any[], combos?: any[]}
+render(): void
+useEffect(): void
+useMemo(): {nodes: any[], edges: any[], combos?: any[]}
}
ForceGraph ..> Graph : uses
ForceGraph ..> buildNodesAndCombos : uses
ForceGraph ..> isEmpty : uses
Summary
The force-graph.tsx component provides a powerful, flexible force-directed graph visualization in React using @antv/g6. It handles data preprocessing, graph initialization, styling, and interactive behaviors within a responsive container. The modular design and hooks usage ensure efficient updates and smooth user experience for exploring complex graph data.