Node collision detection and constraint
Node Dragging with Collision Detection
Demonstrates advanced node dragging with collision detection, visual feedback through color coding, overlap prevention, and automatic connection creation when nodes are dropped on valid targets.
Node Dragging with Collision Detection
Functional Overview
This example demonstrates advanced node dragging capabilities including collision detection, overlap prevention, and dynamic connection creation. When dragging nodes over other nodes, the system provides visual feedback through color changes and can automatically create connections between nodes upon release.
Implementation of Key Features
Drag Event Handlers
const onNodeDragging = (node: RGNode, newX: number, newY: number, buffX: number, buffY: number, e: RGUserEvent) => {
let rejectOverlaped = false;
let limitedPosition: RGCoordinate | undefined;
const allNodes = graphInstance.getNodes();
for (const n of allNodes) {
if (node.id === n.id) continue;
// Check for overlap
const overlap = MyRelationGraphUtils.shapesOverlap(nodeBox, n, shapeA, shapeB);
if (overlap) {
// Color coding for different behaviors
let newColor = n.data!.allowDrop ? 'rgba(212,252,189,0.82)' : 'rgba(252,189,189,0.82)';
if (n.data.disallowDroppingNodesInside) {
rejectOverlaped = true;
limitedPosition = MyRelationGraphUtils.getNoOverlapLimitedPosition(node, newX, newY, n);
newColor = 'rgba(214,165,246,0.82)';
}
graphInstance.updateNode(n, { color: newColor });
}
}
if (rejectOverlaped) {
return limitedPosition; // Prevent overlap
}
};
Drag Start and End Handlers
const onNodeDragStart = (nodeObject: RGNode) => {
graphInstance.updateNodeData(nodeObject, {
startX: nodeObject.x,
startY: nodeObject.y
});
};
const onNodeDragEnd = (nodeObject: RGNode) => {
const allNodes = graphInstance.getNodes();
for (const n of allNodes) {
if (nodeObject.id === n.id) continue;
const overlap = MyRelationGraphUtils.shapesOverlap(nodeObject, n, nodeObject.nodeShape, n.nodeShape);
if (overlap) {
updateNodeAsChildren(nodeObject, n);
break;
}
}
};
Connection Creation
const updateNodeAsChildren = (node: RGNode, parentNode: RGNode) => {
// Restore position
graphInstance.updateNodePosition(node, node.data!.startX, node.data!.startY);
// Add connection line
graphInstance.addLines([{
id: `new_l_${Date.now()}`,
from: parentNode.id,
to: node.id,
text: 'New Relationship',
color: 'rgba(214,165,246,0.82)',
lineWidth: 3
}]);
};
Configuration UI
<SimpleUIBoolean
label="Disallow Dropping Nodes Inside"
currentValue={node.data.disallowDroppingNodesInside}
onChange={(newValue) => {
graphInstance.updateNodeData(node, {disallowDroppingNodesInside: newValue})
}}
/>
Creative Use Cases
Workflow Designers: Drag tasks onto swimlanes or categories to automatically assign them. Visual feedback shows valid drop targets in green, invalid ones in red.
Database Schema Designers: Drag tables onto other tables to create foreign key relationships. Overlap prevention maintains layout integrity while connection creation establishes relationships.
Mind Mapping: Drag concepts onto categories to organize them automatically. Nodes can be configured to accept or reject certain types of content.
Kanban Boards: Drag cards between columns or onto specific team members. Collision detection prevents cards from being placed in invalid positions.
Organization Charts: Drag employees onto departments to reassign them. Visual feedback indicates valid department transfers.
Project Planning: Drag milestones onto phases to schedule them. Overlap rejection prevents scheduling conflicts, while valid drops create hierarchical relationships.
Game Level Editors: Drag game objects onto layers or zones. Different colors indicate valid placement areas for different object types.
Circuit Design: Drag components onto boards or subcircuits. Collision detection prevents component overlap, while valid placements create electrical connections.