UI / Connectors

Connectors are the lines that actually join elements of the UI. In the Toolkit edition, a connector is the visual representation of an edge.

The connectors that ship with jsPlumb core are:

The default, if you do not provide a value, is to use the Bezier connector.

Note that from version 4.x onwards the Flowchart connector will be renamed to Orthogonal, and the StateMachine connector will be folded in to the Bezier connector (which will take as an optional argument the number of control points to use).

From version 2.0.0 the Toolkit also offers three connectors that allow the user to modify the path. These are:

These are included in the jsplumbtoolkit-editable-connectors.tgz package, and discussed on this page and also here.

Connectors are defined using the syntax described in Connector, Endpoint, Anchor & Overlay Definitions. Allowed constructor values for each Connector type are described below.


Provides a cubic Bezier path between the two Endpoints. It supports a single constructor argument:

  • curviness - Optional; defaults to 150. This defines the distance in pixels that the Bezier's control points are situated from the anchor points. This does not mean that your Connector will pass through a point at this distance from your curve. It is a hint to how you want the curve to travel. Rather than discuss Bezier curves at length here, we refer you to Wikipedia.
{ "renderParams":{ "layout":{ "type":"Absolute" }, "jsPlumb":{ "Anchor":"AutoDefault", "Endpoint":"Blank", "Connector":"Bezier" }, "zoomToFit":true }, "data":{ "nodes":[ { "id":"1", "left":50, "top":50 }, { "id":"2", "left":150, "top":250 } ], "edges":[ { "source":"1", "target":"2" } ] } }

Draws a straight line between the two endpoints. Two constructor arguments are supported:

  • stub - Optional, defaults to 0. Any positive value for this parameter will result in a stub of that length emanating from the Endpoint before the straight segment connecting to the other end of the connection.
  • gap - Optional, defaults to 0. A gap between the endpoint and either the start of the stub or the segment connecting to the other endpoint.
{ "renderParams":{ "layout":{ "type":"Absolute" }, "jsPlumb":{ "Anchor":"AutoDefault", "Endpoint":"Blank", "Connector":"Straight" }, "zoomToFit":true }, "data":{ "nodes":[ { "id":"1", "left":50, "top":50 }, { "id":"2", "left":150, "top":250 } ], "edges":[ { "source":"1", "target":"2" } ] } }
{ "renderParams":{ "layout":{ "type":"Absolute" }, "jsPlumb":{ "Anchor":"AutoDefault", "Endpoint":"Blank", "Connector":["Straight", { stub:25}] }, "zoomToFit":true }, "data":{ "nodes":[ { "id":"1", "left":50, "top":50 }, { "id":"2", "left":150, "top":250 } ], "edges":[ { "source":"1", "target":"2" } ] } }

Draws a connection that consists of a series of vertical or horizontal segments - the classic flowchart look. Four constructor arguments are supported:

  • stub - this is the minimum length, in pixels, of the initial stub that emanates from an Endpoint. This is an optional parameter, and can be either an integer, which specifies the stub for each end of the Connector, or an array of two integers, specifying the stub for the [source, target] endpoints in the Connection. Defaults to an integer with value 30 pixels.
  • alwaysRespectStubs - optional, defaults to false. This parameter instructs jsPlumb to always paint a line of the specified stub length out of each Endpoint, instead of reducing the stubs automatically if the two elements are closer than the sum of the two stubs.
  • gap - optional, defaults to 0 pixels. Lets you specify a gap between the end of the Connector and the elements to which it is attached.
  • midpoint - optional, defaults to 0.5. This is the distance between the two elements that the longest section of the flowchart connector will be drawn at. This parameter is useful for those cases where you have programmatic control of the drawing and perhaps want to avoid some other element on the page.
  • cornerRadius Defaults to 0. A positive value for this parameter will result in curved corner segments.

This Connector supports Connections that start and end on the same element ("loopback" connections).

{ "renderParams":{ "layout":{ "type":"Absolute" }, "jsPlumb":{ "Anchor":"AutoDefault", "Endpoint":"Blank", "Connector":"Flowchart" }, "zoomToFit":true }, "data":{ "nodes":[ { "id":"1", "left":50, "top":50 }, { "id":"2", "left":150, "top":250 } ], "edges":[ { "source":"1", "target":"2" } ] } }
{ "renderParams":{ "layout":{ "type":"Absolute" }, "jsPlumb":{ "Anchor":"AutoDefault", "Endpoint":"Blank", "Connector":["Flowchart", {cornerRadius:5}] }, "zoomToFit":true }, "data":{ "nodes":[ { "id":"1", "left":50, "top":50 }, { "id":"2", "left":150, "top":250 } ], "edges":[ { "source":"1", "target":"2" } ] } }

Draws slightly curved lines (they are actually quadratic Bezier curves), similar to the State Machine connectors you may have seen in software like GraphViz. Connections in which some element is both the source and the target ("loopback") are supported by these Connectors (as they are with Flowchart Connectors); in this case you get a circle. Supported constructor parameters are:

  • margin - Optional; defaults to 5. Defines the distance from the element that the Connector begins/ends.
  • curviness - Optional, defaults to 10. This has a similar effect to the curviness parameter on Bezier curves.
  • proximityLimit - Optional, defaults to 80. The minimum distance between the two ends of the Connector before it paints itself as a straight line rather than a quadratic Bezier curve.
{ "renderParams":{ "layout":{ "type":"Absolute" }, "jsPlumb":{ "Anchor":"AutoDefault", "Endpoint":"Blank", "Connector":"StateMachine" }, "zoomToFit":true }, "data":{ "nodes":[ { "id":"1", "left":50, "top":50 }, { "id":"2", "left":150, "top":250 } ], "edges":[ { "source":"1", "target":"2" } ] } }

%toolkit


This is an extension of the Flowchart connector that allows users to manipulate the path travelled. Supported parameters are as shown for the Flowchart connector above.

The EditableFlowchart ships in a separate package from the Toolkit core - jsplumbtoolkit-editable-connectors. To declare it as a dependency:

"dependencies:{
 ...
 "jsplumbtoolkit-editable-connectors":"file:./path/to/jsplumbtoolkit-editable-connectors.tgz"
 ...
}

The package ships with three files:

  • js/jsplumbtoolkit-editable-connectors.js
  • css/jsplumbtoolkit-editable-connectors.css
  • types/jsplumbtoolkit-editable-connectors.d.ts

To use these in a "traditional" setup you just need to import the JS file and the CSS file. The CSS is not essential but it contains sane defaults for the connectors - they add artifacts to the UI, and without any accompanying styles you will not see these artifacts. You can use the jsPlumb defaults for these visual artifacts if you choose, but it is a simple matter to provide your own styles.

To use the connectors in ES6/Typescript (including React, Angular and Vue) you need to ensure you import the entire package, in order to be certain that tree shaking will not discard any of the code:

import "jsplumbtoolkit-editable-connectors";
{ "renderParams":{ "layout":{ "type":"Absolute" }, "jsPlumb":{ "Anchor":"AutoDefault", "Endpoint":"Blank", "Connector":"EditableFlowchart" }, "zoomToFit":true }, "data":{ "nodes":[ { "id":"1", "left":30, "top":50 }, { "id":"2", "left":350, "top":250 } ], "edges":[ { "source":"1", "target":"2", "data":{"id":"1"} } ] }, "onload":function(surface) { var e = surface.getToolkit().getEdge("1"); surface.startEditing(e); } }

In the example above, each segment of the connector has a circle with a four-way arrow on it. Segments can be dragged in the axis that is perpendicular to their travel. New segments are created as needed to complete the path when a drag occurs. If you drag a segment such that it aligns with one or both of its adjoining segments, the segments are fused back into one.

On each node you will see a white circle. Dragging this allows you to reposition the anchor for the connector - but note that this only works when the anchor is either a Dynamic or Continuous anchor. Anchors in fixed positions (such as Left, Top or defined by a position array) can not be moved.


An extension of the Bezier connector that allows the user to edit the path by way of dragging the control points. Supported parameters are as shown in the Bezier connector above.

{ "renderParams":{ "layout":{ "type":"Absolute" }, "jsPlumb":{ "Anchor":"AutoDefault", "Endpoint":"Blank", "Connector":"EditableBezier" }, "zoomToFit":true }, "data":{ "nodes":[ { "id":"1", "left":50, "top":50 }, { "id":"2", "left":150, "top":250 } ], "edges":[ { "source":"1", "target":"2", "data":{"id":"1"} } ] }, "onload":function(surface) { var e = surface.getToolkit().getEdge("1"); surface.startEditing(e); } }

An extension of the StateMachine connector that allows the user to edit the path by way of dragging the control points. Supported parameters are as shown in the StateMachine connector above.

{ "renderParams":{ "layout":{ "type":"Absolute" }, "jsPlumb":{ "Anchor":"AutoDefault", "Endpoint":"Blank", "Connector":"EditableStateMachine" }, "zoomToFit":true }, "data":{ "nodes":[ { "id":"1", "left":50, "top":50 }, { "id":"2", "left":150, "top":250 } ], "edges":[ { "source":"1", "target":"2", "data":{"id":"1"} } ] }, "onload":function(surface) { var e = surface.getToolkit().getEdge("1"); surface.startEditing(e); } }

TOP


To start editing a path you call startEdit on an instance of the Surface widget. A number of parameters are supported.

To use the defaults, just pass in the Edge you wish to edit the path for:

surface.startEditing(edge);

You can attach an arbitrary set of overlays to the edge to show for the duration of the path edit:

surface.startEditing(edge, {
    overlays:[
        [ "Label", { 
            location:0.2, 
            label:"Editing this edge",
            events:{
                click:function() {
                    // you can attach events to these overlays...
                }
            }  
        }]
    ]
})

Since it's a fairly common use case, the Toolkit offers a shortcut for attaching an edge delete button:

surface.startEditing(edge, {
    deleteButton:true,
    deleteButtonLocation:0.3,
    onMaybeDelete:function(edge, connection, deleteCallback) {
        ...
        deleteCallback();        
    }
})

The only required parameter here (required if you want a delete button that is) is the deleteButton parameter. If you pass that in alone, you will get a delete button at location 0.1, with a CSS class as described below. Other options are:

  • deleteButtonLocation either a decimal between 0 - 1 inclusive (as shown above), or an array of decimals in that range (as shown below). In this latter case, you will get one delete button per location specified.
  • onMaybeDelete This optional function will be called when the user taps/clicks on a delete button. It is given the Edge that was clicked, its visual Connection, and a function to call if you wish to proceed with edge deletion.
surface.startEditing(edge, {
    deleteButton:true,
    deleteButtonLocation:[ 0.3, 0.7 ],
    onMaybeDelete:function(edge, connection, deleteCallback) {
        ...
        deleteCallback();        
    }
})

Path data is automatically stored inside the corresponding edge's backing data by the Toolkit whenever changes are made. Each connector type has its own format, and they are not interchangeable.

For the EditableFlowchart connector, the path data has the following format:

{
    "segments": [
      [ 502, 320 ],
      [ 622, 320 ],
      [ 622, 102 ],
      [ 720, 102 ]
    ],
    "source": [ 502, 350, 0.5, 0, 0, -1 ],
    "target": [ 750, 102, 0, 0.5, -1, 0 ]    
}
  • segments is an array of target points for the segments in the connector. For instance above, the first segment ends at [ 502, 320 ].
  • source is the position of the source anchor. The first two values are the absolute location, in pixels, of the source anchor relative to the notional origin of the view. The second two values are decimals indicating the anchor's proportional location in each axis. The last two values provide the orientation for the anchor.
  • target is the position of the target anchor, in the same format as source

Note that in this example there are actually 6 segments in the connector - the four shown in the array, plus a segment from the source anchor to the first segment point, and then one from the last segment point to the target anchor.

For the EditableBezier and EditableStateMachine connectors, the path data has the following format:

{
    "source": [ 402, 450, 0.5, 0 ],
    "target": [ 702, 154, 0.5, 1 ],
    "controlPoints": [ [ 412, 79 ], [ -10, 146 ] ]
}
  • source is the position of the source anchor. The first two values are the absolute location, in pixels, of the anchor. The second two values are decimals indicating the anchor's proportional location in each axis. Unlike the EditableFlowchart data, anchors for this connector type do not include the anchor orientation data
  • controlPoints Array of control points for the curve. Note that currently the Toolkit supports two control points for EditableBezier and one for EditableStateMachine. Any points you provide that are surplus to requirements will be ignored.

The Toolkit will automatically load path data found inside some edge when you use the key geometry. For instance in this dataset with two nodes and one edge, the path data is provided:

{
    "nodes":[
        { "id":"1", "left":390, "top":450 },
        { "id":"2", "left":690, "top":600 }
    ],
    "edges":[
        {
            "source":"1",
            "target":"2",
            "geometry":{
                "source": [ 402, 450, 0.5, 0 ],
                "target": [ 702, 154, 0.5, 1 ],
                "controlPoints": [ [ 412, 79 ], [ -10, 146 ] ]
            }
        }
    ]
}

There are a few points to note about working with path data:

  • The format of path data differs between connector types. You will not, for instance, be able to load path data from an EditableFlowchart connector into an EditableBezier or EditableStateMachine connector.

  • Any error that occurs during the loading of path data will cause the data to be discarded and removed from the edge. Subsequent export of the dataset will not include the path data.

  • Using path data only makes sense if you're using an absolute layout, or you're using a dynamic layout that is absolute backed and your path data does not reference any nodes that do not themselves have an absolute position.

The Toolkit offers a number of CSS classes to assist you in styling the path editors:

Added to segment drag handles that can be dragged upwards and downwards
Common Classes
jtk-connection-editAdded to a connector when it is being edited
jtk-anchor-placeholderAdded to the elements used to indicate where the anchors for the currently edited connection reside on their respective elements
jtk-anchor-candidateAdded to the elements used to indicate where an anchor for the currently edited connection may be dragged to.
jtk-edge-deleteAdded to the overlay element representing a delete button
EditableFlowchart classes
jtk-flowchart-handleAdded to all handles created by the EditableFlowchart editor
jtk-flowchart-segment-dragAdded to the segment drag handles created by the EditableFlowchart editor
jtk-flowchart-segment-drag-ns
jtk-flowchart-segment-drag-ewAdded to segment drag handles that can be dragged left and right
EditableBezier/EditableStateMachine classes
jtk-bezier-handleAdded to all handles created by the EditableBezier/EditableStateMachine editor
jtk-bezier-handle-control-pointAdded to the handles representing control points
jtk-bezier-handle-control-point-1Added to the control point handle for the first control point
jtk-bezier-handle-control-point-2Added to the control point handle for the second control point
jtk-bezier-guidelineAdded to the guidelines created by the EditableBezier/EditableStateMachine editor

In addition to the variety of CSS classes the editors use, they also write an attribute:

jtk-anchor-face

This is written onto the element that is the source or target of some connection, when the anchor can be moved (which is when the anchor is Continuous or Dynamic). When editing begins this value is set to the current face. If a user drags an anchor placeholder around, this value is updated to reflect the current candidate face. When the user stops dragging the anchor placeholder the value is updated for the new face. Valid values are:

  • left
  • top
  • right
  • bottom

%/toolkit