JavaScript is required

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: playing state controls button display
  • Ref for index: currentLayoutIndexRef maintains 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 updateOptions to change layout algorithm
  • Relayout: Calls doLayout to 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 playing changes

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.