Connectable Ports
In some use cases, providing users with interactive graph modification functionality is essential. Part of this functionality is the ability to add new connections to the graph.
To enable ports that are connectable via dragging, call the enableUserConnectablePorts method on a CanvasBuilder instance:
const element = document.getElementById("canvas");
const canvas = new CanvasBuilder(element)
.enableUserConnectablePorts()
.build();
It is crucial for a port to have a “grabable” area large enough to actually be grabbed by the user, as shown in the example below.
The enableUserConnectablePorts method accepts optional configuration.
Configuration Parameters
| Name | Type | Description | Required | Default |
|---|---|---|---|---|
connectionTypeResolver | (portId) => "direct" | "reverse" | null | Resolves connection type when edge creation has been initiated. null means that connection is disallowed | no | () => "direct" |
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 | undefined |
connectionPreprocessor | (request: AddEdgeRequest) => AddEdgeRequest | Applies modifications to the edge about to be created. | no | (request) => request |
mouseDownEventVerifier | (event) => boolean | Function to verify if mouse event should initiate connection creation process | no | (event) => event.button === 0 |
mouseUpEventVerifier | (event) => boolean | Function to verify if mouse event should create connection | no | (event) => event.button === 0 |
edgeShape | EdgeShapeConfig | Default edge shape configuration while port is in the process of dragging | no | Same as for canvas |
events | EventsConfig | Handlers for available events | no | {} |
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 |
| Undefined | undefined | Direction matches the original direction of the port being grabbed |
EventsConfig
| Name | Type | Description | Required | Default |
|---|---|---|---|---|
onAfterEdgeCreated | (edgeId) => void | Function called after a new edge has been added | no | () => void |
onEdgeCreationInterrupted | (params: { staticPortId, isDirect: boolean}) => void | Function called when edge creation is interrupted in the process | no | () => void |
onEdgeCreationPrevented | (request: AddEdgeRequest) => void | Function called when an attempt to create edge is prevented | no | () => void |
Here’s a good example of a reasonable connection type resolver, which resolves direct connection when an “out” port gets grabbed, and reverses connection when an “in” port gets grabbed:
const connectionTypeResolver = (portId) => {
return portId.endsWith("-out") ? "direct" : "reverse";
};
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;
};
You might also be interested in the Edges with Remove Button tutorial.