Skip to main content
The selection system provides Photoshop-inspired selection tools with modal behavior.

Selection Modes

ModeBehavior
newClick replaces entire selection with clicked node
addClick adds node to existing selection
subtractClick removes node from existing selection
intersectKeep only nodes in both current and new selection

Keyboard Shortcuts

ShortcutAction
NSwitch to ‘new’ mode
ASwitch to ‘add’ mode
SSwitch to ‘subtract’ mode
ISwitch to ‘intersect’ mode
Ctrl+ClickTemporary ‘add’ mode
Alt+ClickTemporary ‘subtract’ mode
Ctrl+ZUndo selection
Ctrl+Shift+ZRedo selection
EscapeClear selection

Selection Depth (BFS Expansion)

Selection depth controls how many “hops” from selected nodes are included in the visible set:
DepthVisible Nodes
1Selected nodes + direct neighbors
2Depth 1 + neighbors of neighbors
3+And so on…

Example

        [C]───[D]

Selected[A]───[B]───[E]

        [F]

Depth 1: A, B, C, F (direct neighbors)
Depth 2: A, B, C, D, E, F (neighbors of neighbors)

Selection History (Undo/Redo)

Managed by SelectionHistoryManager:
  • Push: Each selection change creates a snapshot
  • Undo: Move to previous snapshot, restore that state
  • Redo: Move to next snapshot, restore that state
  • Truncate: New action after undo removes the redo stack
Each snapshot stores:
{
  selectedNodeIds: Set<string>,
  selectionDepth: number
}
During undo/redo, a flag prevents the recording useEffect from pushing the restored state as a new entry (which would wipe the redo stack).

Selection Persistence

When selectionPersistent = true:
  • Clicking background does NOT clear selection
  • Must explicitly click “Clear” button
  • Allows exploring graph while keeping selection

Selection State Flow

1

User clicks node

Click detected in Three.js canvas
2

Event fired

GraphEventHandler fires graphNodeClick event
3

App.jsx handles

Handler determines mode and updates AppContext
4

useGraph3D syncs

useEffect detects change, syncs to GraphStateManager
5

History recorded

SelectionHistoryManager.push() saves snapshot
6

Filter applied

OverlayFilterService.applyUnifiedFilter() updates visibility