The selection system provides Photoshop-inspired selection tools with modal behavior.
Selection Modes
| Mode | Behavior |
|---|
| new | Click replaces entire selection with clicked node |
| add | Click adds node to existing selection |
| subtract | Click removes node from existing selection |
| intersect | Keep only nodes in both current and new selection |
Keyboard Shortcuts
| Shortcut | Action |
|---|
N | Switch to ‘new’ mode |
A | Switch to ‘add’ mode |
S | Switch to ‘subtract’ mode |
I | Switch to ‘intersect’ mode |
Ctrl+Click | Temporary ‘add’ mode |
Alt+Click | Temporary ‘subtract’ mode |
Ctrl+Z | Undo selection |
Ctrl+Shift+Z | Redo selection |
Escape | Clear selection |
Selection Depth (BFS Expansion)
Selection depth controls how many “hops” from selected nodes are included in the visible set:
| Depth | Visible Nodes |
|---|
| 1 | Selected nodes + direct neighbors |
| 2 | Depth 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
User clicks node
Click detected in Three.js canvas
Event fired
GraphEventHandler fires graphNodeClick event
App.jsx handles
Handler determines mode and updates AppContext
useGraph3D syncs
useEffect detects change, syncs to GraphStateManager
History recorded
SelectionHistoryManager.push() saves snapshot
Filter applied
OverlayFilterService.applyUnifiedFilter() updates visibility