Switch layout
Automatic Layout Switching - Cycle through multiple layouts with timed transitions
Automatic Layout Switching Animation
Functional Overview
This example demonstrates automatic cycling through different layout algorithms with timed transitions. The graph continuously switches between center, tree, circle, and force layouts every 2 seconds, creating an animated showcase of how different algorithms arrange the same graph data. Users can start and stop the automatic switching with play/stop controls, making it ideal for demonstrating layout capabilities or finding the best layout for a dataset.
Implementation of Key Features
Layout Cycle Configuration
Defines an array of layouts to cycle through:
const exampleLayouts: { label: string, layoutOptions: RGLayoutOptions }[] = [
{
label: 'Center',
layoutOptions: {
layoutName: 'center'
}
},
{
label: 'Tree',
layoutOptions: {
layoutName: 'tree',
from: 'left'
}
},
{
label: 'Circle',
layoutOptions: {
layoutName: 'circle'
}
},
{
label: 'Force',
layoutOptions: {
layoutName: 'force'
}
}
];
Key aspects:
- Label field: Human-readable names for each layout
- Layout options: Complete configuration object for each algorithm
- Easy extension: Add more layouts by adding to array
Play State Management
Uses state and refs to control animation cycle:
const [playing, setPlaying] = useState(false);
const currentLayoutIndexRef = useRef(0);
const playNextLayoutTimer = useRef();
Key aspects:
- State for UI:
playingstate controls button display - Ref for index:
currentLayoutIndexRefmaintains position in cycle - Timer ref: Stores setTimeout ID for cleanup
Layout Switching Logic
The switchToNextLayout function performs the actual layout change:
const switchToNextLayout = async () => {
// Reset to start if past end
if (currentLayoutIndexRef.current > exampleLayouts.length - 1) {
currentLayoutIndexRef.current = 0;
}
// Update layout options
graphInstance.updateOptions({
layout: exampleLayouts[currentLayoutIndexRef.current].layoutOptions
});
// Recalculate positions
await graphInstance.doLayout();
// Adjust view
graphInstance.moveToCenter();
graphInstance.zoomToFit();
// Schedule next switch
playNextLayoutTimer.current = setTimeout(() => {
currentLayoutIndexRef.current++;
switchToNextLayout();
}, 2000); // 2 second delay
};
Key aspects:
- Index wrapping: Resets to 0 when reaching end of array
- Options update: Uses
updateOptionsto change layout algorithm - Relayout: Calls
doLayoutto recalculate node positions - View adjustment: Recenters and zooms after each layout
- Recursive scheduling: setTimeout for next iteration
Play Control Functions
Simple start/stop controls:
const play = () => {
switchToNextLayout();
};
const stop = () => {
clearTimeout(playNextLayoutTimer.current);
};
Effect-Based State Management
Handles play state changes and cleanup:
useEffect(() => {
initializeGraph();
return () => {
stop(); // Cleanup on unmount
};
}, []);
useEffect(() => {
if (playing) {
play();
} else {
stop();
}
}, [playing]);
Key aspects:
- Initialization: Loads graph on mount
- Cleanup: Clears timer on component unmount
- Play state effect: Starts/stops animation when
playingchanges
UI Controls with Icons
Uses Lucide icons for play/stop buttons:
<RelationGraph options={graphOptions} />
<DraggableWindow>
{!playing ? (
<button
className="border rounded-lg px-3 py-1 flex place-items-center justify-center gap-2 bg-white"
onClick={() => setPlaying(true)}
>
<Play size={16} />
<span>Play Auto Switch</span>
</button>
) : (
<button
className="border rounded-lg px-3 py-1 flex place-items-center justify-center gap-2 bg-green-400"
onClick={() => setPlaying(false)}
>
<Loader2Icon className="animate-spin" size={16} />
<span>Stop Auto Switch</span>
</button>
)}
</DraggableWindow>
Key aspects:
- Visual feedback: Different styles and icons for play/stop states
- Loading indicator: Spinning icon when playing
- Draggable window: Controls float above graph
Graph Data
Uses a simple tree-structured dataset:
const myJsonData: RGJsonData = {
rootId: 'a',
nodes: [
{ id: 'a', text: 'a' },
{ id: 'b', text: 'b' },
{ id: 'b1', text: 'b1' },
// ... more nodes
],
lines: [
{ id: 'l1', from: 'a', to: 'b' },
{ id: 'l2', from: 'b', to: 'b1' },
// ... more lines
]
};
Rectangle Node Shape
Uses rectangular nodes for clear hierarchy visualization:
const graphOptions: RGOptions = {
debug: false,
defaultNodeShape: RGNodeShape.rect,
layout: exampleLayouts[0].layoutOptions
};
Creative Use Cases
Layout Algorithm Showcase: Demonstrate different graph visualization algorithms to stakeholders. Automatically cycle through layouts to let viewers compare how each algorithm interprets the same data.
Dataset Exploration: Load unknown datasets and cycle through layouts to quickly identify which algorithm best reveals the data’s structure. Stop when you find the most informative arrangement.
Visual Benchmarking: Record performance of different layout algorithms on the same graph. Use automatic cycling to capture screenshots or measure rendering times.
Interactive Demos: Create engaging presentations where graphs dynamically reconfigure themselves. Use in educational settings to show how layout algorithms work.
Ambient Data Visualization: Display relationship graphs in public spaces with automatic layout changes. Creates dynamic, living visualizations that catch attention and reveal different perspectives.
Layout Selection Tool: Help users choose the best layout for their data by showing all options automatically. Users can stop on the layout that best suits their needs.