Skip to main content
Custom events enable loose coupling between Three.js canvas and React components.

Event Flow

1

User clicks node

Click detected in Three.js canvas
2

GraphEventHandler

Detects click and determines what was clicked
3

CustomEvent dispatched

window.dispatchEvent(new CustomEvent('graphNodeClick', {...}))
4

App.jsx listener

window.addEventListener('graphNodeClick', handler)
5

Handler processes

Processes click based on selectionMode

Custom Events Reference

Event NamePayloadFired When
graphNodeClick{ node, isMultiSelect, modifierKey }User clicks a node
graphBackgroundClicknoneUser clicks empty space
graphDataLoadednoneNew graph data loaded
layoutComputednoneGPU layout computation complete
graphNodeHover{ node }Mouse hovers over node

Event Payload Details

graphNodeClick

{
  node: {
    id: string,
    name: string,
    type: string,
    // ... other node properties
  },
  isMultiSelect: boolean,  // Ctrl/Cmd held
  modifierKey: 'ctrl' | 'alt' | 'shift' | null
}

graphNodeHover

{
  node: {
    id: string,
    name: string,
    type: string
  } | null  // null when hover ends
}

Listening to Events

In React components:
useEffect(() => {
  const handleNodeClick = (event) => {
    const { node, isMultiSelect, modifierKey } = event.detail;
    // Handle click based on current selectionMode
  };

  window.addEventListener('graphNodeClick', handleNodeClick);
  return () => window.removeEventListener('graphNodeClick', handleNodeClick);
}, [selectionMode]);

Firing Events

In service layer:
window.dispatchEvent(new CustomEvent('graphNodeClick', {
  detail: {
    node: clickedNode,
    isMultiSelect: event.ctrlKey || event.metaKey,
    modifierKey: getModifierKey(event)
  }
}));

Why Custom Events?

  • Loose coupling: Three.js code doesn’t need React imports
  • Testability: Easy to mock events in tests
  • Flexibility: Multiple listeners can respond to same event
  • Separation: Keeps rendering logic separate from UI logic