Connect Diagram Shapes by Proximity While Dragging
Environment
| Product | Progress® Kendo UI® for Angular Diagram |
Description
I want to use proximity as a drop target when users rearrange a Diagram. While a shape moves, the closest eligible destination must appear highlighted. Dropping the shape nearby must connect it to that destination.
This pattern fits workflow editors, node-link builders, and topology tools where moving a node changes its relationship. Use standard Diagram dragging when the shape must retain its connections.
Solution
Handle the Diagram drag events to detach the dragged shape, identify a nearby destination, and create a new connection when the drag ends. The implementation temporarily highlights the closest eligible shape, then restores the original connections when no destination is within the configured proximity area.
The following example starts without connections and uses a 150-pixel edge-to-edge proximity threshold. Drag a shape near another shape until the destination is highlighted. Drop the shape to create a connection. Drag it near a different destination to replace the connection.
To implement proximity-based connections:
-
Bind the
dragStart,drag, anddragEndevents.html<kendo-diagram (dragStart)="onDragStart($event)" (drag)="onDrag()" (dragEnd)="onDragEnd()"> </kendo-diagram> -
Store the dragged shape and temporarily remove its connections. Filter
diagramConnectionsby thefromandtoendpoints.tspublic onDragStart(event: DiagramDragEvent): void { this.draggedShape = event.shapes[0]; this.detachedConnections = this.diagram.diagramConnections.filter( connection => connection.from === this.draggedShape || connection.to === this.draggedShape ); this.diagram.remove(this.detachedConnections); } -
During the
dragevent, find the nearest eligible shape within the proximity threshold. Usebounds()to compare the edge-to-edge distance, then update the highlight only when the destination changes.tspublic onDrag(): void { const destination = this.findClosestDestination(); if (destination !== this.highlightedShape) { this.restoreHighlightedShape(); this.highlightShape(destination); } } -
Apply the destination highlight and call
redrawVisual()to refresh the shape.tsprivate highlightShape(shape: Shape): void { this.highlightedShape = shape; this.highlightedFill = shape.options.fill; shape.options.fill = { ...shape.options.fill, color: '#ffc400' }; shape.redrawVisual(); } -
When the drag ends, restore the highlight. Use
connect()when a destination is active, or restore the detached connections when the drop occurs outside the proximity area.tspublic onDragEnd(): void { const destination = this.highlightedShape; this.restoreHighlightedShape(); if (this.draggedShape && destination) { this.diagram.connect(this.draggedShape, destination); } else { this.detachedConnections.forEach(connection => this.diagram.addConnection(connection)); } }
Change destinationDistance to adjust the proximity area. Filter diagramShapes to restrict valid destinations, and validate each relationship before calling connect() to prevent invalid links or cycles.
If the Diagram is bound to application data, apply the same connection change to the data source.