removeNode method
Removes a node from the graph along with all its connections.
This method will:
- Remove the node from the graph
- Remove it from the selection if selected
- Remove all connections involving this node
- Remove the node from any group annotations
- Delete empty group annotations that no longer contain any nodes
Triggers the onNodeDeleted callback after successful removal.
Implementation
void removeNode(String nodeId) {
final nodeToDelete = _nodes[nodeId]; // Capture before deletion
if (nodeToDelete == null) return;
// Capture connections to emit events for
final connectionsToRemove = _connections
.where((c) => c.sourceNodeId == nodeId || c.targetNodeId == nodeId)
.toList();
runInAction(() {
// Detach context for nodes with GroupableMixin before removal
// This disposes MobX reactions and cleans up the context
if (nodeToDelete is GroupableMixin<T>) {
nodeToDelete.detachContext();
}
_nodes.remove(nodeId);
_selectedNodeIds.remove(nodeId);
// Remove from spatial index
_spatialIndex.removeNode(nodeId);
// Remove connections involving this node from spatial index first
for (final connection in connectionsToRemove) {
_spatialIndex.removeConnection(connection.id);
// Also remove from path cache to prevent stale rendering
_connectionPainter?.removeConnectionFromCache(connection.id);
}
// Then remove from connections list
_connections.removeWhere(
(c) => c.sourceNodeId == nodeId || c.targetNodeId == nodeId,
);
// Note: Groupable nodes (like GroupNode) are notified of deletions via MobX reaction
// in _setupNodeMonitoringReactions that watches _nodes.keys for additions/deletions
});
// Fire event after successful removal
events.node?.onDeleted?.call(nodeToDelete);
// Emit extension events for removed connections first
for (final connection in connectionsToRemove) {
_emitEvent(ConnectionRemoved(connection));
}
// Emit extension event for removed node
_emitEvent(NodeRemoved<T>(nodeToDelete));
}