Overlays
Overlays are UI elements that are painted onto connections, such as labels or arrows.
#
IntroductionjsPlumb comes with five types of overlays:
Arrow
- a configurable arrow that is painted at some point along the connector. You can control the length and width of the Arrow, the 'foldback' point - a point the tail points fold back into, and the direction (allowed values are 1 and -1; 1 is the default and means point in the direction of the connection)Label
- a configurable label that is painted at some point along the connector.PlainArrow
- an arrow shaped as a triangle, with no foldback.Diamond
- as the name suggests...a diamond.Custom
- allows you to create the overlay yourself - your overlay may be any DOM element you like.
PlainArrow
and Diamond
are actually just configured instances of the generic Arrow
overlay (see examples).
#
Overlay LocationA key concept with overlays is that of their location.
For a connector, the location of an overlay refers to some point along the path inscribed by the connector. It can be specified in one of three ways:
- as a decimal in the range [0..1], which indicates some proportional amount of travel along the path inscribed by the connector. The default value of 0.5 is in this form, and it means the default location of an overlay on a connector is a point halfway along the path.
- as an integer greater than 1, which indicates some absolute number of pixels to travel along the connector from the start point
- as an integer less than zero, which indicates some absolute number of pixels to travel backwards along the connector from the end point.
For an endpoint, the same principles apply, but location is specified as an [x,y] array. For instance, this would specify an overlay that was positioned in the center of an Endpoint:
location:[ 0.5, 0.5 ]
Whereas this would specify an overlay that was positioned 5 pixels along the x axis from the top left corner:
location: [ 5, 0 ]
And this would specify an overlay that was positioned 5 pixels along the x axis from the bottom right corner:
location: [ -5, 0 ]
All overlays support these two methods for getting/setting their location:
- getLocation - returns the current location
- setLocation - sets the current location. For Endpoints, location is expressed in terms of an [ x, y ] array whose values are either proportional to the width/height of the Endpoint (decimals in the range 0-1 inclusive), or absolute values (decimals greater than 0).
#
Adding overlaysYou can specify one or more overlays when making a call to the connect
, addEndpoint
or addSourceSelector
methods of a jsPlumb instance (but not addTargetSelector
: overlays are always derived from what the source of a Connection defines). The three cases are discussed below:
connect
call#
Specifying one or more overlays on a In this example we'll create an arrow with the default options for an arrow, and a label with the text "foo":
instance.connect({ source:someElement, target:someOtherElement, anchor: "AutoDefault", endpoints: ["Dot", "Blank"], overlays:[ { type:"Arrow", options:{location:1}}, { type:"Label", options:{ label:"foo", location:0.25, id:"myLabel" } } ]})
This connection will have an arrow located halfway along it, and the label "foo" one quarter of the way along. Notice the id parameter; it can be used later if you wish to remove the overlay or change its visibility (see below).
Another example, this time with the label at an absolute location of 30 pixels from the source:
instance.connect({ source:someElement, target:someOtherElement, anchor: "AutoDefault", endpoints: ["Dot", "Blank"], overlays:[ { type:"Arrow", options:{location:1}}, { type:"Label", options:{ label:"foo", location:50, id:"myLabel" } } ]})
addEndpoint
call.#
Specifying one or more overlays on an Note in this example we use both connectorOverlays
and overlays
. overlays
refers to overlays on the endpoint, and connectorOverlays
refers to overlays on any connection attached to the endpoint:
instance.addEndpoint(someElement, { ... overlays:[ { type:"Label", options:{ label:"foo", id:"label", location:[-0.5, -0.5] } } ], connectorOverlays:[ { type:"PlainArrow", options:{location:1 }}, { type:"Label", options:{ label:"foo", id:"label" } } ], ...});
This connection will have a 10x20 PlainArrow
located right at the head of the connection, and the label "connector foo" located at the halfway point. The endpoint itself also has an overlay, located at [ -0.5, -0.5 ] relative to the endpoint's top,left corner. The numbers in the array refer to proportions of the endpoint's size - in this case, half its width and half its height.
addSourceSelector
call.#
Specifying one or more overlays on a Note in this example that we again use the parameter connectorOverlays
and not overlays
. The endpoint
parameter to jsPlumb.makeSource
supports everything you might pass to the second argument of a jsPlumb.addEndpoint
call:
instance.addSourceSelector({ selector:".someMatchingSelector", endpoint:{ connectorOverlays:[ { type:"Arrow", options:{ width:10, length:20, location:1, id:"arrow" } }, { type:"Label", options:{ label:"foo", id:"label" } } ] } ...});
Any connections dragged from an element matching this selector will have a 10x20 arrow located right at the head of the connection, and the label "foo" located at the halfway point.
addOverlay
method on an endpoint or connection#
Using the Endpoints and connections both have an addOverlay
method that takes as an argument a single overlay definition. An example:
var e = instance.addEndpoint(someElement)e.addOverlay({ type: "Arrow", options:{ width:10, height:10, id:"arrow" }})
#
EventsYou can bind several different event handlers in an overlay specification by including them in an events
section.
Constant | Name | Payload | Description |
---|---|---|---|
EVENT_CLICK | click | (e:Event, o:Overlay) | Fired when the user clicks on an overlay. |
EVENT_DBL_CLICK | dblclick | (e:Event, o:Overlay) | Fired when the user double clicks on an overlay. |
EVENT_TAP | tap | (e:Event, o:Overlay) | Fired when the user taps on an overlay. |
EVENT_DBL_TAP | dbltap | (e:Event, o:Overlay) | Fired when the user double taps on an overlay. |
Here's an example. Note that we bind dbl
instance.connect){ source:someElement, target:someOtherElement, overlays:[ { type:"Label", options:{ label:"click me", location:0.25, events:{ click:(e:Event, o:Overlay) => alert("click!") } } }, { type:"Label", options:{ label:"tap me", location:0.75, events:{ tap:(e:Event, o:Overlay) => alert("tap!") } } }, { type:"Label", options:{ label:"double click me", location:0.50, events:{ dblclick:(e:Event, o:Overlay) => alert("dbllick!") } } } ]}
#
Overlay Types#
ArrowDraws an arrow, using four points: the head and two tail points, and a foldback
point, which permits the tail of the arrow to be indented. Available constructor arguments for this overlay are:
width
- width of the tail of the arrowlength
- distance from the tail of the arrow to the headlocation
- where, either as a proportional value from 0 to 1 inclusive, or as an absolute value (negative values mean distance from target; positive values greater than 1 mean distance from source) the arrow should appear on the connectordirection
- which way to point. Allowed values are 1 (the default, meaning forwards) and -1, meaning backwardsfoldback
- how far along the axis of the arrow the tail points foldback in to. Default is 0.623.
#
PlainArrowThis is a specialized instance of Arrow
in which jsPlumb hardcodes foldback
to 1, meaning the tail of the arrow is a flat edge. All of the constructor parameters from Arrow
apply for PlainArrow
.
#
DiamondThis is a specialized instance of Arrow
in which jsPlumb hardcodes 'foldback' to 2, meaning the arrow turns into a Diamond. All of the constructor parameters from Arrow
apply for Diamond
.
#
LabelProvides a text label to decorate connectors with. The available constructor arguments are:
label
- The text to display. You can provide a function here instead of plain text: it is passed the Connection as an argument, and it should return a String.cssClass** - Optional css class to use for the Label. This is now preferred over using the
labelStyle` parameter.location
- As forArrow
overlay. Where, either proportionally from 0 to 1 inclusive, or as an absolute offset from either source or target, the label should appear.
The Label overlay offers two methods - getLabel
and setLabel
- for accessing/manipulating its content dynamically:
const c = instance.connect({ source:someElement, target:someOtherElement, overlays:[ { type:"Label", options:{label:"FOO", id:"label"}} ] }) ... const label = c.getOverlay("label")console.log("Label is currently", label.getLabel())label.setLabel("BAR")console.log("Label is now", label.getLabel())
In this example you can see that the label overlay is assigned an id of "label" in the connect call, and then retrieved using that id in the call to connection's getOverlay
method.
Both Connections and endpoints support label overlays, and because changing labels is quite a common operation, setLabel
and getLabel
methods have been added to these objects:
const conn = instance.connect({ source:someElement, target:someOtherElement, label:"FOO"}); ...
console.log("Label is currently", conn.getLabel());conn.setLabel("BAR");console.log("Label is now", conn.getLabel());
These methods support passing in a function instead of a string, and jsPlumb will create a label overlay for you if one does not yet exist when you call setLabel
:
const conn = instance.connect({ source:someElement, target:someOtherElement}); ... conn.setLabel((c) => { var s = new Date(); return s.getTime() + "milliseconds have elapsed since 01/01/1970";});console.log("Label is now", conn.getLabel())
#
CustomThe custom overlay allows you to create your own overlays, which jsPlumb will position for you. You need to implement one method - create(component)
- which is passed the component on which the overlay is located as an argument, and which returns either a DOM element or a valid selector from the underlying library:
const conn = instance.connect({ source:someElement, target:someOtherElement, overlays:[ { type:"Custom" options:{ create:(component) => { const d = document.createElement("select") d.innerHTML = "<option value='foo'>foo</option><option value='bar'>bar</option>" return d }, location:0.7, id:"customOverlay" } } ]});
Here we have created a select box with a couple of values, assigned to it the id of 'customOverlay' and placed it at location 0.7. Note that the 'id' we assigned is distinct from the element's id. You can use the id you provided to later retrieve this overlay using the getOverlay(id)
method on a Connection or an Endpoint.
#
Hiding/Showing overlaysYou can control the visibility of overlays using the setVisible
method of overlays themselves, or with showOverlay(id)
or hideOverlay(id)
on a connection.
Remember the id parameter that we specified in the examples above? This can be used to retrieve an overlay from a connection:
const connection = instance.connect({ ... overlays:[ "Arrow", { type: "Label", options:{ label:"foo", location:0.25, id:"myLabel" } } ], ...}); // time passes const overlay = connection.getOverlay("myLabel")// now you can hide this overlay:overlay.setVisible(false)// there are also hide/show methods:overlay.show()overlay.hide()
However, connection and endpoint also have two convenience methods you could use instead:
const connection = instance.connect({ ... overlays:[ "Arrow", { type:"Label", options:{ label:"foo", location:-30 }, id:"myLabel" } ], ...}); // time passes connection.hideOverlay("myLabel"); // more time passes connection.showOverlay("myLabel");
#
Removing overlaysConnection and endpoint also have a removeOverlay
method:
const connection = instance.connect({ ... overlays:[ "Arrow", { type:"Label", options:{ label:"foo", location:0.25 }, id:"myLabel" } ], ...}); // time passes connection.removeOverlay("myLabel")