Draggable Edges
In addition to connectable ports, it is useful to provide functionality for modifying existing edges.
To enable draggable edges, call the enableUserDraggableEdges method on a CanvasBuilder instance:
const element = document.getElementById("canvas");
const canvas = new CanvasBuilder(element)
.enableUserDraggableEdges()
.build();
It is crucial for the port to have a “grabable” area large enough to actually be grabbed by the user, as shown in the example below.
The enableUserDraggableEdges method accepts optional configuration.
Configuration Parameters
| Name | Type | Description | Required | Default |
|---|---|---|---|---|
draggingEdgeResolver | (portId) => Identifier | null | Resolves edge ID which will be dragged based on provided grabbed port ID. null means do not initiate dragging process. | no | Latest adjacent edge |
connectionAllowedVerifier | (request: { from: Identifier, to: Identifier }) => boolean | Verifies if connection between specified ports is allowed. | no | (request) => true |
dragPortDirection | DragPortDirection | Direction of dragging port | no | "inherit" |
connectionPreprocessor | (request: AddEdgeRequest) => AddEdgeRequest | Applies modification to the edge about to be reattached. | no | (request) => request |
grabbedPortIdResolver | (portIds: Identifier[]) => Identifier | null | Resolves ID of a port being grabbed when there’s ambiguity. See PortIdResolver | no | First added port |
releasedPortIdResolver | (portIds: Identifier[]) => Identifier | null | Resolves ID of a port being released when there’s ambiguity. See PortIdResolver | no | First added port |
mouseDownEventVerifier | (event) => boolean | Function to verify if mouse event should initiate connection dragging process | no | (event) => event.button === 0 |
mouseUpEventVerifier | (event) => boolean | Function to verify if mouse event should reattach connection | no | (event) => event.button === 0 |
draggingEdgeShape | EdgeShapeConfig | The shape of a dragging edge | no | Same as the edge being dragged |
events | EventsConfig | Handlers for available events | no | {} |
As for the connection allowed verifier, you can start with one that forbids duplicated connections:
const connectionAllowedVerifier = (request) => {
const existingEdge = canvas.graph.getAllEdgeIds().find((edgeId) => {
const edge = canvas.graph.getEdge(edgeId);
return edge.from === request.from && edge.to === request.to;
});
return existingEdge === undefined;
};
DragPortDirection
| Name | Type | Description |
|---|---|---|
| Constant | number | Fixed radian angle for the dragging port direction |
| Nearest Connectable Port | "nearest-connectable-port" | Direction matches the direction of the nearest connectable port |
| Inherit | "inherit" | Direction matches the original direction of the port being grabbed |
PortIdResolver
The same element can be marked as multiple different ports. When user interacts with such element,
it’s not clear which port should be interacted with, for example when grabbed or released.
PortIdResolver function allows to configure such behavior.
There are good examples of such functions:
const grabbedPortIdResolver = (portIds) => {
return portIds.find((portId) => portId.endsWith("-out")) ?? null;
}
const releasedPortIdResolver = (portIds) => {
return portIds.find((portId) => portId.endsWith("-in")) ?? null;
}
EventsConfig
| Name | Type | Description | Required | Default |
|---|---|---|---|---|
onAfterEdgeReattached | (edgeId) => void | Function called after an edge has been reattached | no | () => void |
onEdgeReattachInterrupted | (edge: DraggingEdgePayload) => void | Function called when edge reattach is interrupted in the process | no | () => void |
onEdgeReattachPrevented | (edge: DraggingEdgePayload) => void | Function called when an attempt to reattach edge is prevented | no | () => void |
You might also be interested in the Edges with Remove Button tutorial.