HTMLGraph logo HTMLGraph

Connectable Ports

In some 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.

Connectable ports

The enableUserConnectablePorts method accepts optional configuration.

Configuration Parameters

NameTypeDescriptionRequiredDefault
edgeShapeEdgeShapeConfigDefault edge shape configuration while port is in the process of draggingnoSame as for canvas
connectionTypeResolver(portId) => "direct" | "reverse" | nullResolves connection type when edge creation has been initiated. null means that connection is disallowedno() => "direct"
connectionPreprocessor(request: AddEdgeRequest) => AddEdgeRequest | nullApplies modifications to the edge about to be created. null means that connection is disallowed.no(request) => request
mouseDownEventVerifier(event) => booleanFunction to verify if mouse event should initiate connection creation processno(event) => event.button === 0
mouseUpEventVerifier(event) => booleanFunction to verify if mouse event should create connectionno(event) => event.button === 0
dragPortDirectionnumber | undefinedDirection of dragging portnoundefined
eventsEventsConfigHandlers for available eventsno{}

Events Configuration

NameTypeDescriptionRequiredDefault
onAfterEdgeCreated(edgeId) => voidFunction called after a new edge has been addedno() => void
onEdgeCreationInterrupted(params: { staticPortId, isDirect: boolean}) => voidFunction called when edge creation is interrupted in the processno() => void
onEdgeCreationPrevented(addEdgeRequest: [AddEdgeRequest](/canvas/#add-edge)) => voidFunction called when an attempt to create edge is preventedno() => 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 preprocessor, you can start with one that forbids duplicated connections:

    
const connectionPreprocessor = (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 ? request : null;
};