# Egonex-AI Dashboard Architecture: How React Flow and Zustand Power the Knowledge Graph Visualization

> Explore the Egonex-AI dashboard architecture. Discover how React Flow and Zustand create a performant knowledge graph visualization with dual navigation and ELK layout.

- Repository: [Egonex/Understand-Anything](https://github.com/Egonex-AI/Understand-Anything)
- Tags: architecture
- Published: 2026-06-09

---

**The Egonex-AI dashboard combines React Flow for the interactive canvas and Zustand for centralized state management, implementing a two-stage ELK layout system with dual navigation modes (overview and layer-detail) to render complex knowledge graphs performantly.**

The **Understand-Anything** repository implements a graph-first dashboard that visualizes codebases as interactive knowledge graphs. Built on top of `@xyflow/react` (React Flow) and `zustand`, the architecture cleanly separates visual rendering from state logic, enabling sophisticated graph layouts computed off the main thread. This deep dive examines the implementation in [`src/store.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/src/store.ts) and [`src/components/GraphView.tsx`](https://github.com/Egonex-AI/Understand-Anything/blob/main/src/components/GraphView.tsx), revealing how the system coordinates two navigation levels while maintaining reactive synchronization between the layout engine and the UI.

## React Flow: The Interactive Canvas Layer

React Flow provides the visual foundation for the dashboard, handling panning, zooming, mini-maps, and node interactions. The integration centers on [`src/components/GraphView.tsx`](https://github.com/Egonex-AI/Understand-Anything/blob/main/src/components/GraphView.tsx), which registers custom node components and manages the React Flow provider context.

### Custom Node Type Registration

The dashboard defines four distinct visual representations for graph entities. In [`GraphView.tsx`](https://github.com/Egonex-AI/Understand-Anything/blob/main/GraphView.tsx) (lines 57–62), the `nodeTypes` object maps type strings to React components:

```typescript
// src/components/GraphView.tsx
const nodeTypes = {
  custom: CustomNode,
  "layer-cluster": LayerClusterNode,
  portal: PortalNode,
  container: ContainerNode,
};

```

Each component receives the node’s data payload and can access the Zustand store to render contextual information. When the topology builders (`useOverviewGraph` or `useLayerDetailTopology`) generate node arrays, they specify these type keys to determine rendering behavior.

### Dual Navigation Topologies

The dashboard implements two distinct graph views: **overview** (showing clustered layers) and **layer-detail** (showing expanded file-level topology). The [`GraphView.tsx`](https://github.com/Egonex-AI/Understand-Anything/blob/main/GraphView.tsx) component switches between these modes based on the `navigationLevel` and `activeLayerId` properties from the store. 

The `useOverviewGraph` hook generates aggregated nodes and edges representing high-level architecture, while `useLayerDetailTopology` constructs the expanded view with container nodes and file-level edges. Both hooks return `Node` and `Edge` arrays that feed directly into React Flow’s `useNodesState` and `useEdgesState` hooks.

### Fit-View Coordination

Two dedicated components handle viewport synchronization: `TourFitView` and `SelectedNodeFitView` (lines 95–124). These watch the Zustand store for `tourHighlightedNodeIds` or `selectedNodeId` changes, then call React Flow’s `fitView` method with `getInternalNode` to ensure highlighted nodes remain centered. The fit-view logic polls until all target nodes are rendered, providing smooth animated transitions during tour navigation or search selection.

## Zustand: The Single Source of Truth

The global store defined in [`src/store.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/src/store.ts) holds the entire application state, from the raw knowledge graph to UI flags and layout caches. Accessed via `useDashboardStore`, it enables selectors that prevent unnecessary re-renders while maintaining reactive updates across the component tree.

### Core State Properties

The store maintains several critical data structures:

- **`graph`, `nodesById`, `nodeIdToLayerId`**: The raw knowledge graph and O(1) lookup maps built once `setGraph` initializes the data (via `buildGraphIndexes`). `GraphView` reads these via selectors like `useDashboardStore((s) => s.graph)`.

- **`navigationLevel`, `activeLayerId`**: Enums tracking whether the UI shows the *overview* or *layer-detail* view and which layer is currently active. These determine which topology hook supplies nodes to React Flow.

- **`expandedContainers`**: A Set containing IDs of container nodes the user has expanded. When populated, it triggers Stage 2 layout calculations for those specific containers.

- **`containerLayoutCache`**: A Map storing computed ELK layouts for expanded containers, preventing redundant calculations when users toggle containers open and closed.

- **`nodeTypeFilters`**: A record mapping node categories (`code`, `config`, `docs`, etc.) to boolean visibility states, driving the `NODE_TYPE_TO_CATEGORY` filtering logic (lines 70–78 of [`GraphView.tsx`](https://github.com/Egonex-AI/Understand-Anything/blob/main/GraphView.tsx)).

- **`tourHighlightedNodeIds`, `tourFitPending`**: Tour navigation state that coordinates with `TourFitView` to animate the viewport to specific nodes during guided tours.

### Actions and Cache Coherence

The store exposes action methods like `selectNode`, `drillIntoLayer`, `toggleContainer`, and `bumpStage1Tick`. These mutate state while maintaining derived cache consistency. For instance, toggling a container clears the `containerLayoutCache` for that ID (lines 27–40 of [`store.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/store.ts)), and changing filters or navigation levels resets the Stage 1 layout tick to trigger a full re-layout.

## Two-Stage ELK Layout Architecture

To prevent UI blocking on large graphs, the dashboard implements a two-stage layout strategy using the Eclipse Layout Kernel (ELK), orchestrated through [`src/utils/elk-layout.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/src/utils/elk-layout.ts).

### Stage 1: Global Layer Layout

The first stage runs on the layer level, positioning clusters, portals, and containers. It receives nodes with estimated dimensions (`containerWidth`, `containerHeight`) and produces a global coordinate system via `applyElkLayout`. The results merge back into React Flow’s node state through `mergeElkPositions`. This stage executes whenever `stage1Tick` changes in the store, which occurs after initial graph load or when filters invalidate the current layout.

### Stage 2: Lazy Container Layout

When users expand a container node, the system triggers Stage 2, which computes detailed layouts for that container’s children only. These results are cached in `containerLayoutCache` to optimize repeated toggling. If the actual rendered size deviates more than 20% from the Stage 1 estimate, the system sets a `deviated` flag (around lines 664–666) that triggers a Stage 1 re-run to prevent layout drift, while avoiding infinite re-layout loops through size threshold checks.

### Reactive Layout Dependencies

Both stages are entirely reactive, depending on store selectors like `built`, `stage1Tick`, and `expandedContainers`. The layout hooks recompute automatically when underlying data changes, ensuring the visualization remains synchronized with the application state without manual coordination.

## Wiring the Architecture Together

[`src/App.tsx`](https://github.com/Egonex-AI/Understand-Anything/blob/main/src/App.tsx) mounts the `ReactFlowProvider` at the root, wrapping the `GraphViewInner` component. Inside, store selectors determine which topology to render, while `useEffect` callbacks synchronize React Flow’s internal state with the Zustand store. Graph transformations—including container derivation in [`src/utils/edgeAggregation.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/src/utils/edgeAggregation.ts) and ELK computation—remain pure functions under `src/utils/`, keeping the UI layer thin and declarative.

## Code Examples

### Registering a Custom Node Type

Extend the graph visualization by adding a new node type to the registry:

```typescript
// src/components/GraphView.tsx
import MySpecialNode from "./MySpecialNode";

const nodeTypes = {
  custom: CustomNode,
  "layer-cluster": LayerClusterNode,
  portal: PortalNode,
  container: ContainerNode,
  "my-special": MySpecialNode,   // Register new type
};

```

Nodes emitted from `useLayerDetailTopology` with `type: "my-special"` will now render using this component.

### Toggling Container State from UI

Access the store to expand or collapse container nodes:

```typescript
import { useDashboardStore } from "../store";

function ExpandButton({ id }: { id: string }) {
  const toggle = useDashboardStore((s) => s.toggleContainer);
  return (
    <button onClick={() => toggle(id)}>
      Toggle {id}
    </button>
  );
}

```

This updates `expandedContainers` and automatically invalidates the relevant cache entries in `containerLayoutCache`.

### Synchronizing Fit View with Selection

Integrate search results with the viewport controller:

```typescript
import { useDashboardStore } from "../store";
import { useReactFlow } from "@xyflow/react";

function SearchResult({ nodeId }: { nodeId: string }) {
  const { fitView } = useReactFlow();
  const select = useDashboardStore((s) => s.selectNode);

  const handleClick = () => {
    select(nodeId);
    fitView({
      nodes: [{ id: nodeId }],
      duration: 500,
      padding: 0.3,
    });
  };

  return <div onClick={handleClick}>Focus {nodeId}</div>;
}

```

The `SelectedNodeFitView` component (lines 81–106) implements similar logic automatically when `selectedNodeId` changes, ensuring the canvas centers on selected nodes.

## Summary

- **React Flow** handles the interactive canvas in [`src/components/GraphView.tsx`](https://github.com/Egonex-AI/Understand-Anything/blob/main/src/components/GraphView.tsx), registering custom node types like `LayerClusterNode` and `ContainerNode` while providing `fitView` capabilities through helper components.
- **Zustand** centralizes state in [`src/store.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/src/store.ts), tracking graph data, navigation levels (`navigationLevel`, `activeLayerId`), expanded containers, and layout caches with reactive selectors.
- **Two-stage layout** uses ELK to compute layer-level positions (Stage 1) and lazy container details (Stage 2), caching results in `containerLayoutCache` to prevent redundant calculations.
- **Reactive coordination** ensures that state changes automatically trigger layout recomputation and viewport adjustments without imperative manual synchronization.

## Frequently Asked Questions

### How does the dashboard prevent UI blocking when laying out large graphs?

The architecture performs heavy layout computations using the ELK (Eclipse Layout Kernel) engine in [`src/utils/elk-layout.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/src/utils/elk-layout.ts) through a two-stage process. Stage 1 handles the global layer layout, while Stage 2 lazily computes detailed layouts only for expanded containers. These calculations run off the main thread where possible, and results are cached in `containerLayoutCache` to avoid recalculating positions when users toggle containers.

### What triggers a re-layout of the graph visualization?

Three primary conditions trigger re-layout: changes to `nodeTypeFilters` or navigation levels (which reset the store’s `stage1Tick`), expanding a container node (triggering Stage 2 layout for that specific container), and size deviations greater than 20% between estimated and actual container dimensions (which sets the `deviated` flag to re-run Stage 1). All triggers are reactive and managed through Zustand store updates.

### Why does the architecture use Zustand instead of React Context for state management?

Zustand provides fine-grained selector-based subscriptions that prevent unnecessary re-renders across deep component trees, which is critical when managing large graph datasets and frequent viewport updates. The store also handles complex derived state like `containerLayoutCache` and `nodesById` lookup maps that would require significant boilerplate with Context, while maintaining type safety and performance for real-time graph interactions.

### How do the overview and detail views share the same React Flow instance?

Both views use the same [`GraphView.tsx`](https://github.com/Egonex-AI/Understand-Anything/blob/main/GraphView.tsx) component but switch data sources based on the `navigationLevel` and `activeLayerId` store properties. The component calls either `useOverviewGraph` or `useLayerDetailTopology` to generate nodes and edges, then passes these to React Flow’s `useNodesState` and `useEdgesState` hooks. This unified approach allows the `ReactFlowProvider` to maintain consistent zoom and pan states during transitions between navigation levels.