Summary

jsPlumb allows you to connect elements on the screen using SVG, Canvas or VML, depending on the capabilities of the browser.

It can be used with jQuery, MooTools or YUI3 (or another library of your choice if you feel like implementing an adapter for it).

Browser Compatibility

jsPlumb 1.3.3 has been tested on the following browsers:

Changes since version 1.3.1

Version 1.3.3 contains a few new methods for working with Overlays, and a couple of bug fixes. Since a few 1.3.x versions have been released in a short amount of time, I've left in the notes from 1.3.1, as there are a few backwards compatibility issues you may need to know about.

New Features
Issues Resolved

Version 1.3.1 was a major new release of jsPlumb, containing several important new features, and a few changes that break backwards compatibility.

Major new features include:

Backwards Compatibility Issues:

Setup

Required Imports

jQuery

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/jquery-ui.min.js"></script>
<script type="text/javascript" src="PATH_TO/jquery.jsPlumb-1.3.3-all-min.js "></script>

MooTools

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/mootools/1.3.3/mootools-yui-compressed.js"></script>
<script type="text/javascript" src="PATH_TO_MOO_TOOLS_MORE_1_3_2_1"></script>
<script type="text/javascript" src="PATH_TO/mootools.jsPlumb-1.3.3-all-min.js "></script>

YUI3

<script type="text/javascript" src="http://yui.yahooapis.com/3.3.0/build/simpleyui/simpleyui-min.js"></script>
<script type="text/javascript" src="PATH_TO/yui.jsPlumb-1.3.3-all-min.js "></script>

Render Mode

jsPlumb can use SVG, HTML5 Canvas elements or VML to render the various objects it adds to the display. Most modern browsers support Canvas and SVG; IE<9 browsers support neither.

By default, jsPlumb attempts to use jsPlumb.CANVAS as the render mode, falling back to jsPlumb.VML if the browser is IE<9. You can change the render mode by making this call:

jsPlumb.setRenderMode(jsPlumb.SVG);
if, for some reason, you set the render mode to be jsPlumb.VML but you're in any browser other than IE<9, jsPlumb will use Canvas.

The jsPlumb.setRenderMode method returns you the render mode that jsPlumb actually ended up setting. Valid values for setRenderMode are:

Initializing jsPlumb

You should not start making calls to jsPlumb until the DOM has been initialized - perhaps no surprises there. With YUI, though, the asynchronous nature of the script loading process means that you are not guaranteed that jsPlumb is ready as soon as the DOM is. To handle this, you should bind to the "ready" event on jsPlumb (or the instance of jsPlumb you are working with):
jsPlumb.bind("ready", function() {
...	
		
// your jsPlumb related init code goes here

...

});						
			
In 1.3.3 a helper method was added that can save you approximately 9 (count them!) characters:
jsPlumb.ready(function() {
...	
		
// your jsPlumb related init code goes here

...

});						
			

For jQuery and MooTools you do not actually need to do this; by the time the DOM ready event is fired in each of those libraries you can be sure all the JS we need has been loaded. But in terms of explicitly calling out that you are waiting for jsPlumb, it seems like a good practice to bind to the "ready" event.

If you bind to the "ready" event after jsPlumb has already been initialized, your callback will be executed immediately.

Unloading jsPlumb

jsPlumb offers a method you can call when your page is unloading. You should do this to insure against memory leaks. You configure it like this:
<body onunload="jsPlumb.unload();">

...

</body>

Multiple jsPlumb instances

jsPlumb is registered on the browser's Window by default, providing one static instance for the whole page to use. Should you need to, though, you can instantiate independent instances of jsPlumb, using the getInstance method, for example:
var firstInstance = jsPlumb.getInstance();
The variable 'firstInstance' can now be treated exactly as you would treat the 'jsPlumb' variable - you can set defaults, call the connect method, whatever:
firstInstance.Defaults.Connector = [ "Bezier", { curviness: 150 } ];
firstInstance.Defaults.Anchors = [ "TopCenter", "BottomCenter" ];

firstInstance.connect({source:"element1", target:"element2", scope:"someScope" });
getInstance optionally takes an object that provides the defaults:
var secondInstance = jsPlumb.getInstance({
	PaintStyle:{ lineWidth:6, strokeStyle:"#567567", outlineColor:"black", outlineWidth:1 },
	Connector:[ "Bezier", { curviness: 30 } ],
	Endpoint:[ "Dot", { radius:5 } ],
	EndpointStyle : { fillStyle: "#567567"  },
	Anchor : [ 0.5, 0.5, 1, 1 ]
});

secondInstance.connect({ source:"element4", target:"element3", scope:"someScope" });

Z-index Considerations

You need to pay attention to the z-indices of the various parts of your UI when using jsPlumb, in particular to ensure that the elements that jsPlumb adds to the DOM do not overlay other parts of the interface.

jsPlumb adds an element to the DOM for each Endpoint, Connector and Overlay. So for a connection having visible Endpoints at each end and a label in the middle, jsPlumb adds four elements to the DOM. The actual elements it adds depend on the renderer in use (Canvas/SVG/VML).

To help you organise z-indices correctly, jsPlumb adds a CSS class to each type of element it adds. They are as follows:

type of elementclass added
Endpoint_jsPlumb_endpoint
Connector_jsPlumb_connector
Overlay_jsPlumb_overlay

Where does jsPlumb add elements?

It's important to understand where in the DOM jsPlumb will add any elements it creates, as it has a bearing on the markup you can use with jsPlumb.

Prior to 1.3.0, jsPlumb added everything to the end of the body element. This has the advantage of being the most flexible arrangement in terms of supporting what elements can be connected, but in certain use cases produced unexpected results. Consider the arrangement where you have some connected elements in a tab: you would expect jsPlumb to add elements inside the tab, so that when the user switches tabs and the current one is hidden, all the jsPlumb stuff is hidden too. But when the elements are on the body, this does not happen!

For this reason, from 1.3.0 onwards, jsPlumb's default behaviour is to attach Endpoint elements to the parent of the element the Endpoint is attached to (not the actual element the Endpoint is attached to), and to attach Connector elements to the parent of the source Endpoint in the Connection. This results in all the elements of the Connection being siblings inside the same parent node, which jsPlumb requires, for various reasons arising from the trade off between doing lots of maths and the performance of the whole thing.

In general, the default behaviour means that you cannot do things like this:

<body>
	<div id="container0">
		<div id="node0"></div>
	</div>
	<div id="container1">
		<div id="node1"></div>
	</div>
</body>

<script type="text/javascript">

	var e0 = jsPlumb.addEndpoint("node0"),
	e1 = jsPlumb.addEndpoint("node1");

	jsPlumb.connect({ source:e0, target:e1 });
</script>

because the elements created for 'e0' and 'e1' would have different parent nodes, and an attempt to make a Connection between them would not work. For the example just given, you would need to register the Endpoints on the 'container' divs (and then quite possibly throw away the 'node' divs):

<body>
	<div id="container0">
	</div>
	<div id="container1">
	</div>
</body>

<script type="text/javascript">

	var e0 = jsPlumb.addEndpoint("container0"),
	e1 = jsPlumb.addEndpoint("container1");

	jsPlumb.connect({ source:e0, target:e1 });
</script>
now 'e0' and 'e1' have the same parent - the body element.

Remember that you can use the anchor parameter to an addEndpoint call to specify where on an element you want an Endpoint to appear. Used in conjunction with CSS classes (discussed below), you can have an Endpoint on top of some element wherever you like.

Note regarding the drawEndpoints option on jsPlumb.connect: with the default behaviour, jsPlumb uses the offsetParent of the source endpoint in a connection to make final adjustments to the position of a connector. When drawEndpoints is set to false, there is no offsetParent of the source endpoint because it is not visible. If your connection lies inside some container other than the document body, the connector will not be able to take that container's offset into account, and will most likely not be in the right place. You should either use the "Blank" endpoint when you don't want to see one, or instruct jsPlumb to attach everything to the document body (see below).

Overriding the default behaviour

From version 1.3.3, the container concept was reintroduced into jsPlumb, because there are use cases in which the default behaviour makes it difficult or impossible to build the UI you want. You can instruct jsPlumb to use some element as the parent of everything jsPlumb adds to the UI through usage of the jsPlumb.Defaults.Container property, or you can set a container parameter on calls to addEndpoint or connect (if this is set and a default is also set, this default value is actually used. This may seem counter-intuitive, and could of course be changed if there is feedback from the community that this would be a good idea). Some examples:

Set a container to use as the default container, using a jQuery selector (you can supply MooTools/YUI selectors if that's the library you're using), and then add an Endpoint. The canvas (or SVG/VML element) created will be a child of the document body:
jsPlumb.Defaults.Container = $("body");
...
jsPlumb.addEndpoint(someDiv, { endpoint options });
Set a container to use as the default container, using an element id, and then connect two elements. The canvases (or SVG/VML elements) created in this example will be children of the element with id "containerId":
jsPlumb.Defaults.Container = "containerId";
...
jsPlumb.connect({ source:someDiv, target:someOtherDiv });
Pass a container to use into a jsPlumb.connect call, using a selector. The canvases (or SVG/VML elements) created in this example will be children of the element with id "containerId":
jsPlumb.connect({ source:someDiv, target:someOtherDiv, container:$("#containerId") });
Pass a container to use into a jsPlumb.addEndpoint call, using an element id. The canvas (or SVG/VML element) created in this example will be a child of the element with id "containerId":
jsPlumb.addEndpoint(someDiv, { ..., container:"containerId" });

Basic Concepts

jsPlumb is all about connecting things together, so the core abstraction in jsPlumb is the Connection object, which is itself broken down into these four concepts:

One Connection is made up of two Endpoints, a Connector, and zero or more Overlays working together to join two elements.

jsPlumb's public API exposes only Connection and Endpoint, handling the creation and configuration of everything else internally. But you still need to be across the concepts encapsulated by Anchor, Connector and Overlay.

Anchors

An Anchor models the notion of where on an element a Connector should connect. jsPlumb has nine default anchor locations you can use to specify where the Connectors connect to elements: these are the four corners of an element, the center of the element, and the midpoint of each edge of the element:

Each of these string representations is just a wrapper around the underlying array-based syntax [x, y, dx, dy], where x and y are coordinates in the interval [0,1] specifying the position of the anchor, and dx and dy are coordinates in the interval [-1, 1] specifying the orientation of the curve incident to the anchor. For example, [0, 0.5, -1, 0] defines a "LeftCenter" anchor with a connector curve that emanates leftward from the anchor. Similarly, [0.5, 0, 0, -1] defines a "CenterTop" anchor with a connector curve emanating upwards.
jsPlumb.connect({...., anchor:"BottomCenter", ... }); 
is identical to:
jsPlumb.connect({...., anchor:[ 0.5, 1, 0, 1 ], ... }); 

Dynamic Anchors

These are Anchors that can be positioned in one of a number of locations, choosing the one that is most appropriate each time something moves or is painted in the UI.

There is no special syntax to creating a DynamicAnchor; you just provide an array of individual Anchor specifications, eg:

var dynamicAnchors = [ [ 0.2, 0, 0, -1 ],  [ 1, 0.2, 1, 0 ], 
			   [ 0.8, 1, 0, 1 ], [ 0, 0.8, -1, 0 ] ];

Default Dynamic Anchor

jsPlumb provides a dynamic anchor called "AutoDefault" that chooses from TopCenter, RightMiddle, BottomCenter and LeftMiddle:
jsPlumb.connect({...., anchor:"AutoDefault", ... });

Location Selection

The initial implementation of the algorithm that decides which location to choose just calculates which location is closest to the center of the other element in the connection. It is possible that future versions of jsPlumb could support more sophisticated choice algorithms, if the need arose.

Draggable Connections

Dynamic Anchors and Draggable Connections can interoperate: jsPlumb locks the position of a dynamic anchor when you start to drag a connection from it, and unlocks it once the connection is either established or abandoned. At that point you may see the position of the dynamic anchor change, as jsPlumb optimises the connection.

You can see this behaviour in the draggable connections demonstration, when you drag a connection from the blue endpoint on window 1 to the blue endpoint on window 3 - the connection is established and then window 1's blue endpoint jumps down to a location that is closer to window 3.

Connector, Endpoint & Overlay Definitions

Before we discuss Connector, Endpoints and Overlays, a quick word on definitions: whenever you need to define a Connector, Endpoint or Overlay, you must use a "definition" of it, rather than constructing one directly. This definition can be either a string that nominates the artifact you want to create:
jsPlumb.connect({
	source:"someDiv",
	target:"someOtherDiv",
	endpoint:"Rectangle"
});
or an array consisting of both the artifact's name and the arguments you want to pass to its constructor:
jsPlumb.connect({
	source:"someDiv",
	target:"someOtherDiv",
	endpoint:[ "Rectangle", { cssClass:"myEndpoint", width:30, height:10 } ]
});
there is also a three-argument method that allows you to specify two sets of parameters, which jsPlumb will merge together for you. The idea behind this is that you will often want to define common characteristics somewhere and reuse them across a bunch of different calls:
var common = {
	cssClass:"myCssClass"
};
jsPlumb.connect({
	source:"someDiv",
	target:"someOtherDiv",
	endpoint:[ "Rectangle", { width:30, height:10 }, common ]
});
This syntax is supported for all Endpoint, Connector and Overlay definitions. Here's an example using definitions for all three:
var common = {
	cssClass:"myCssClass"
};
jsPlumb.connect({
	source:"someDiv",
	target:"someOtherDiv",
	endpoint:[ "Dot", { radius:5 }, common ],
	connector:[ "Bezier", { curviness:100 }, common ],
	overlays: [
		[ "Arrow", { foldback:0.2 }, common ],
		[ "Label", { cssClass:"labelClass" } ]	
	]
});
The allowed constructor parameters are different for each artifact you create, but every artifact takes a single JS object as argument, with the parameters as [key,value] pairs in that object. See the relevant sections on Connectors, Endpoints and Overlays for information on supported parameters.

Connectors

Connectors are the lines that actually join elements of the UI. jsPlumb has three connector implementations - a straight line, a Bezier curve, and "flowchart" connectors. The default connector is the Bezier curve.

You optionally specify a Connector by setting the 'connector' property on a call to jsPlumb.connect or jsPlumb.addEndpoint(s). If you do not supply a value for 'connector', the default will be used (see defaults).

You specify Connectors using the syntax described above in Connector, Endpoint & Overlay Definitions.Allowed constructor values for each Connector type are described below:

Bezier Connector

The Bezier Connector 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, because they are a complex topic, we refer you to Wikipedia.

Straight Connector

The Straight Connector draws a straight line between the two endpoints. No constructor arguments are supported; use the endpointStyle argument to a connect or addEndpoint call to control the appearance of one of these Connectors.

Flowchart Connector

This type of Connector draws a connection that consists of a series of vertical or horizontal segments - the classic flowchart look. A single constructor argument is supported:

stub - this is the minimum length, in pixels, of the initial stub that emanates from an Endpoint. This parameter is optional, and defaults to 30 pixels.

Endpoint Types

An Endpoint is the UI component that marks the location of an Anchor, ie. the place where a Connector joins an element. jsPlumb comes with three Endpoint implementations - Dot, Rectangle and Image. You optionally specify Endpoint properties using the endpoint parameter in a call to jsPlumb.connect, jsPlumb.addEndpoint or jsPlumb.makeTarget.

As with Connectors and Overlays, you specify Endpoints using the syntax described above in Connector, Endpoint & Overlay Definitions.

The three available Endpoint types, and their constructor arguments, are as follows:

Dot Endpoint

This Endpoint draw a dot on the screen. It supports a single constructor parameter:

radius - Optional; defaults to 10 pixels. Defines the radius of the dot.

Rectangle Endpoint

Draws a rectangle. Supported constructor parameters are:

width - Optional; defaults to 20 pixels. Defines the width of the rectangle.

height - Optional; defaults to 20 pixels. Defines the height of the rectangle.

Image Endpoint

Draws an image from a given URL. This Endpoint supports one constructor parameter:

src - Required. Specifies the URL of the image to use.

Overlay Types

Overlays are UI elements that are painted onto connections, such as labels or arrows. jsPlumb comes with four defaults:

The last two are actually just configured instances of the generic Arrow overlay (see examples).

You can specify one or more overlays when making a call to jsPlumb.connect or jsPlumb.addEndpoint (but not jsPlumb.makeTarget; overlays are always derived from what the source of a Connection defines) The two cases are discussed below:

1. Specifying one or more overlays on a jsPlumb.connect call. In this example we'll create an Arrow with the default options for an Arrow, and a label with the text "foo":
jsPlumb.connect({
	...
	overlays:[ 
		"Arrow", 
		[ "Label", { 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).

2. Specifying one or more overlays on a jsPlumb.addEndpoint call. Note in this example that we use the parameter 'connectorOverlays' and not 'overlays' as in the last example. This is because 'overlays' will one day be used to support Endpoint Overlays:
jsPlumb.addEndpoint("someDiv", {
	...
	connectorOverlays:[ 
		[ "Arrow", { width:10, length:30, location:1, id:"arrow" } ], 
		[ "Label", { label:"foo", id:"label" } ]
	],
	...
});
This connection will have a 10x30 Arrow located right at the head of the connection, and the label "foo" located at the halfway point. Again, note that id parameter passed in to each Overlay spec.

Arrow Overlay

This overlay draws 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

PlainArrow Overlay

This is just 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.

Diamond Overlay

This 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 PlainArrow.

Label Overlay

This provides a text label to decorate Connectors with. The available constructor arguments are:

Hiding/Showing Overlays

You 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 the Overlay from a Connection:

var connection = jsPlumb.connect({
	...
	overlays:[ 
		"Arrow", 
		[ "Label", { label:"foo", location:0.25 }, id:"myLabel" ]
	],
	...
});		

// time passes

var 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 also has two convenience methods you could use instead:

var connection = jsPlumb.connect({
	...
	overlays:[ 
		"Arrow", 
		[ "Label", { label:"foo", location:0.25 }, id:"myLabel" ]
	],
	...
});		

// time passes

connection.hideOverlay("myLabel");

// more time passes

connection.showOverlay("myLabel");

Removing Overlays

Connection also has a removeOverlay method, that does what you might expect:

var connection = jsPlumb.connect({
	...
	overlays:[ 
		"Arrow", 
		[ "Label", { label:"foo", location:0.25 }, id:"myLabel" ]
	],
	...
});		

// time passes

connection.removeOverlay("myLabel");


Defaults

The easiest way to set a look and feel for your plumbing is to override the defaults that jsPlumb uses. If you do not do this you are forced to provide your overridden values on every call. Every argument to the connect and addEndpoint methods has an associated default value in jsPlumb.

The defaults that ship with jsPlumb are stored in jsPlumb.Defaults, which is a Javascript object. Valid entries, and their initial values, are:
Anchor : "BottomCenter",
Anchors : [ null, null ],
AppendElementsToBody : false,
Connector : "Bezier",
DragOptions : { },
DropOptions : { },
Endpoint : "Dot",
Endpoints : [ null, null ],
EndpointStyle : { fillStyle : null },
EndpointStyles : [ null, null ],
EndpointHoverStyle : null,
EndpointHoverStyles : [ null, null ],
HoverPaintStyle : null,
LabelStyle : { color : "black" },
LogEnabled : false,
Overlays : [ ],
MaxConnections : 1,
MouseEventsEnabled : true,
PaintStyle : { lineWidth : 8, strokeStyle : "#456" },
RenderMode : "canvas",
Scope : "_jsPlumb_DefaultScope"

Note that in EndpointStyle, the default fillStyle is 'null'. This instructs jsPlumb to use the strokeStyle from the attached connector to fill the endpoint.

Note also that you can specify either or both (or neither) of 'EndpointStyle' and 'EndpointStyles'. This allows you to specify a different end point for each end of a connection. 'Endpoint' and 'Endpoints' use the same concept. jsPlumb will look first in the individual endpoint/endpoint style arrays, and then fall back to the single default version.

you can override these defaults by including this in a script somewhere:
jsPlumb.Defaults.PaintStyle = {
	lineWidth:13,
	strokeStyle: 'rgba(200,0,0,100)'
}

jsPlumb.Defaults.DragOptions = { cursor: "crosshair" };

jsPlumb.Default.Endpoints = [ [ "Dot", 7 ], [ "Dot", 11 ] ];

jsPlumb.Defaults.EndpointStyles = [{ fillStyle:"#225588" }, { fillStyle:"#558822" }];
after the jsPlumb script has been loaded of course! Here we have specified the following default behaviour:

Connections

Programmatic Connections

The most simple connection you can make with jsPlumb looks like this:
jsPlumb.connect({source:"element1", target:"element2"});
In this example we have created a Connection from 'element1' to 'element2'. Remember that a Connection in jsPlumb consists of two Endpoints, a Connector, and zero or more Overlays. But this call to 'connect' supplied none of those things, so jsPlumb uses the default values wherever it needs to. In this case, default values have been used for the following:

So this call will result in an 8px Bezier, colored "#456", from the bottom center of 'element1' to the bottom center of 'element2', and each Endpoint will be a 10px radius Dot Endpoint, colored "#456".

Let's beef up this call a little and tell jsPlumb what sort of Endpoints we want, and where we want them:

jsPlumb.connect({
	source:"element1", 
	target:"element2",
	anchors:["RightMiddle", "LeftMiddle" ],
	endpoint:"Rectangle",
	endpointStyle:{ fillStyle: "yellow" }
});

This is what we have told jsPlumb we want this time:

Reusing common settings between jsPlumb.connect calls

A fairly common situation you will find yourself in is wanting to create a bunch of Connections that have only minor differences between them. To support that, jsPlumb.connect takes an optional second argument. For example:

var common = {
	anchors:[ "BottomCenter", "TopCenter" ],
	endpoints:["Dot", "Blank" ]
};

jsPlumb.connect({ source:"someElement", target:"someOtherElement" }, common);

jsPlumb.connect({ source:"aThirdElement", target:"yetAnotherElement" }, common);

Connections using Drag and Drop

To support drag and drop connections, you first need to set a few things up. Every drag and drop connection needs at least a source Endpoint that the user can drag a connection from. Here's a simple example of how to create an Endpoint:
var endpointOptions = { isSource:true };
var endpoint = jsPlumb.addEndpoint('elementId', endpointOptions);
This Endpoint will act as a source for new Connections, and will use the jsPlumb defaults for its own appearance and that of any Connections that are drawn from it.
Tip: use the three-argument addEndpoint method for common data
One thing that happens quite often is that you have an Endpoint whose appearance and behaviour is largely the same between usages on different elements, with just a few differences.
var exampleGreyEndpointOptions = {
	endpoint:"Rectangle",
	paintStyle:{ width:25, height:21, fillStyle:'#666' },
	isSource:true,
	connectorStyle : { strokeStyle:"#666" },
	isTarget:true
};
Notice there is no 'anchor' set. Here we apply it to two elements, at a different location in each:
jsPlumb.addEndpoint('element1', { anchor:"BottomCenter" }, exampleGreyEndpointOptions)); 

jsPlumb.addEndpoint('element2', { anchor:"TopCenter" }, exampleGreyEndpointOptions));

Now that you have a source Endpoint, you need to either create a target Endpoint on some element, or notify jsPlumb that you wish to make an entire element a drop target. Let's look at how to attach a target Endpoint first:

var endpointOptions = { isTarget:true, endpoint:"Rectangle", paintStyle:{ fillStyle:"gray" } };
var endpoint = jsPlumb.addEndpoint("otherElementId", endpointOptions);

This Endpoint, a gray rectangle, has declared that it can act as a drop target for Connections.

Your other option for creating a drag and drop target is to make an entire element a drop target, using the jsPlumb.makeTarget method. This method takes two arguments, the first of which specifies some element (or list of elements); the second specifies the Endpoint you wish to create on that element whenever a Connection is established on it. In this example we will use the exact same target Endpoint we used before - the gray rectangle - but we will tell jsPlumb that the element "aTargetDiv" will be the drop target:

var endpointOptions = { isTarget:true, endpoint:"Rectangle", paintStyle:{ fillStyle:"gray" } };
jsPlumb.makeTarget("aTargetDiv", endpointOptions);

The allowed values in 'endpointOptions' are identical for both the jsPlumb.addEndpoint and jsPlumb.makeTarget methods.

There are many things you can set in an Endpoint options object; for a thorough list see the API documentation for Endpoint.

Here's an example of specifying that you want an Arrow overlay halfway along any Connection dragged from this Endpoint:

var exampleGreyEndpointOptions = {
	endpoint:"Rectangle",
	paintStyle:{ width:25, height:21, fillStyle:'#666' },
	isSource:true,
	connectorStyle : { strokeStyle:"#666" },
	isTarget:true,
	connectorOverlays: [ [ "Arrow", { location:0.5 } ] ]
};
This is an Endpoint that moves around the element it is attached to dependent on the location of other elements in the connections it is attached to (a 'dynamic' anchor):
var exampleGreyEndpointOptions = {
	endpoint:"Rectangle",
	paintStyle:{ width:25, height:21, fillStyle:'#666' },
	isSource:true,
	connectorStyle : { strokeStyle:"#666" },
	isTarget:true,
	connectorOverlays: [ [ "Arrow", { location:0.5 } ] ]
	anchor:[ "TopCenter","RightMiddle","BottomCenter","LeftMiddle" ]
};
Drag Options
These are options that will be passed through to the supporting library's drag API. jsPlumb passes everything you supply here through, inserting wrapping functions if necessary for the various lifecycle events that jsPlumb needs to know about. So if, for example, you pass a function to be called when dragging starts, jsPlumb will wrap that function with a function that does what jsPlumb needs to do, then call yours.

At the time of writing, jsPlumb supports jQuery, MooTools and YUI3, and each of those libraries uses different terminology. In addition, jQuery's API is more fully featured, providing easy support for setting the zIndex and opacity of elements being dragged, as well as the 'scope' for a drag/drop (allowing you to specify more than one type of drag/drop pair), and hover classes for when a draggable is on the move or over a droppable. If you're using jQuery you can of course just supply these values on the dragOptions; to make it easier, jsPlumb's MooTools and YUI3 adapters recognize these options and add appropriate callbacks for you.

Given that the options here are library-specific, and they are all well-documented, we're going to discuss just the three drag options that behave the same way in all (see below for hoverClass):

For more information about drag options, take a look at the jQuery, MooTools, or YUI3 docs.

NOTE: there is an issue in Chrome that affects the 'cursor' argument to drag options in jQuery. See these links:

http://forum.jquery.com/topic/draggable-cursor-option-does-not-work
http://forum.jquery.com/topic/chrome-text-select-cursor-on-drag

You should put something like this at the top of your JS to avoid it (perhaps not something so drastic as a document-wide override):
document.onselectstart = function () { return false; };
Drop Options
Drop options are treated by jsPlumb in the same way as drag options - they are passed through to the underlying library. MooTools does not have drop options like jQuery and YUI3 do; droppable functionality in MooTools is actually implemented by the Drag.Move class - the one used to initialise a draggable. But when you setup an Endpoint in jsPlumb you should ignore that fact, and treat droppables like you would in jQuery or YUI3. jsPlumb wires everything up for you under the hood.

There are three jQuery droppable options that jsPlumb treats as shortcuts in MooTools and YUI3, for the sake of consistency:

For more information about drop options when using jQuery, see here.

Drag and Drop Scope
jsPlumb borrowed the concept of 'scope' from jQuery's drag/drop implementation: the notion of which draggables can be dropped on which droppables. In jsPlumb you can provide a 'scope' entry when creating an Endpoint. Here's the example grey Endpoint example with 'scope' added:
var exampleGreyEndpointOptions = {
	endpoint:"Rectangle",
	paintStyle:{ width:25, height:21, fillStyle:"#666" },
	isSource:true,
	connectionStyle : { strokeStyle:"#666" },
	isTarget:true,
	scope:"exampleGreyConnection"
};
If you do not provide a 'scope' entry, jsPlumb uses a default scope. Its value is accessible through this method:
jsPlumb.getDefaultScope();
If you want to change it for some reason you can do so with this method:
jsPlumb.setDefaultScope("mySpecialDefaultScope");
You can also, should you want to, provide the scope value separately on the drag/drop options, like this:
var exampleGreyEndpointOptions = {
	endpoint:"Rectangle",
	painStyle:{ width:25, height:21, fillStyle:'#666' },
	isSource:true,
	connectionStyle : { strokeStyle:"#666" },
	isTarget:true,
	dragOptions:{ scope:"dragScope" },
	dropOptions:{ scope:"dropScope" }
};

Paint Styles

Defining the appearance of Connectors, Endpoints (and Overlays, but this is deprecated in favour of using CSS classes) is achieved through a 'paintStyle' (or a quite similar name...keep reading) object passed as a parameter to one of jsPlumb.connect, jsPlumb.addEndpoint or jsPlumb.makeTarget. Depending on the method you are calling, the parameter names vary.
Connector Paint Styles
These are specified in a paintStyle parameter on a call to jsPlumb.connect:
jsPlumb.connect({
	source:"el1",
	target:"el2",
	paintStyle:{ strokeStyle:"blue", lineWidth:10 }
});
or in the connectorPaintStyle parameter on a call to jsPlumb.addEndpoint:
jsPlumb.addEndpoint({
	source:"el1",
	target:"el2",
	paintStyle:{ fillStyle:"blue", outlineColor:"black", outlineWidth:1 },
	connectorPaintStyle:{ strokeStyle:"blue", lineWidth:10 }
});
Notice the paintStyle parameter in that example: it is the paint style for the Endpoint, which we'll discuss below.
Endpoint Paint Styles
These are specified in a paintStyle parameter on a call to jsPlumb.addEndpoint. This is the example from just above:
jsPlumb.addEndpoint("el1", {
	paintStyle:{ fillStyle:"blue", outlineColor:"black", outlineWidth:1 },
	connectorPaintStyle:{ strokeStyle:"blue", lineWidth:10 }
});
...or as the endpointStyle parameter to a jsPlumb.connect call:
jsPlumb.connect({
	source:"el1",
	target:"el2",
	endpointStyle:{ fillStyle:"blue", outlineColor:"black", outlineWidth:1 },
	paintStyle:{ strokeStyle:"blue", lineWidth:10 }
});
... or as an entry in the endpointStyles array passed to a jsPlumb.connect call:
jsPlumb.connect({
	source:"el1",
	target:"el2",
	endpointStyles:[ 
		{ fillStyle:"blue", outlineColor:"black", outlineWidth:1 },
		{ fillStyle:"green" }
	],
	paintStyle:{ strokeStyle:"blue", lineWidth:10 }
});
or as the paintStyle entry in an endpoint parameter passed to a jsPlumb.makeTarget call:
jsPlumb.makeTarget("el1", {
	endpoint: {
		paintStyle:{ fillStyle:"blue", outlineColor:"black", outlineWidth:1 }
	}
});
In this example we've made "el1" into a drop target, and defined a paint style for the Endpoint jsPlumb will create when a Connection is established.
Overlay Paint Styles
The preferred way to set paint styles for Overlays is to use the cssClass parameter in the constructor arguments of an Overlay definition.

Paint Style Parameters

This is the full list of parameters you can set in a paintStyle object, but note that fillStyle is ignored by Connectors, and strokeStyle is ignored by Endpoints. Also, if you create a Connection using jsPlumb.connect and do not specify any Endpoint styles, the Endpoints will derive their fillStyle from the Connector's strokeStyle.

fillStyle, strokeStyle and outlineColor can be specified using any valid CSS3 syntax.

Hover Paint Styles

Connectors and Endpoints both support the concept of a "hover" paint style - a paint style to use when the mouse is hovering over the component. These are specified in the exact same format as paint styles discussed above, but hover paint styles also inherit any values from the main paint style. This is because you will typically want to just change the color, or perhaps outline color, of a Connector or Endpoint when the mouse is hovering, but leave everything else the same. So having hover paint styles inherit their values precludes you from having to define things in more than one place.

The naming convention adopted for hover paint styles is pretty much to insert the word 'hover' into the corresponding main paint style parameters. Here are a couple of examples:

jsPlumb.connect({
	source:"el1",
	target:"el2",
	paintStyle:{ strokeStyle:"blue", lineWidth:10 },
	hoverPaintStyle:{ strokeStyle:"red" },
	endpointStyle:{ fillStyle:"blue", outlineColor:"black", outlineWidth:1 },
	endpointHoverStyle:{ fillStyle:"red" }
});
In this example we specified a hover style for both the Connector, and each of its Endpoints. Here's the same thing, but using the plural version, to specify a different hover style for each Endpoint:
jsPlumb.connect({
	source:"el1",
	target:"el2",
	paintStyle:{ strokeStyle:"blue", lineWidth:10 },
	hoverPaintStyle:{ strokeStyle:"red" },
	endpointStyle:{ fillStyle:"blue", outlineColor:"black", outlineWidth:1 },
	endpointHoverStyles:[ { fillStyle:"red" }, { fillStyle:"yellow" } ]
});
Calls to jsPlumb.addEndpoint and jsPlumb.makeTarget can also specify various hover paint styles:
jsPlumb.addEndpoint("el1", {
	paintStyle:{ fillStyle:"blue", outlineColor:"black", outlineWidth:1 },
	hoverPaintStyle:{ fillStyle:"red" },
	connectorPaintStyle:{ strokeStyle:"blue", lineWidth:10 },
	connectorHoverPaintStyle:{ strokeStyle:"red", outlineColor:"yellow", outlineWidth:1 }
});
Here we specified a hover paint style for both the Endpoint we are adding, and any Connections that are made from the Endpoint.

jsPlumb.makeTarget also supports hover paint styles - here's the example from before, with one applied:

jsPlumb.makeTarget("el1", {
	endpoint: {
		paintStyle:{ fillStyle:"blue", outlineColor:"black", outlineWidth:1 },
		hoverPaintStyle:{ fillStyle:"red" }
	}
});
Note that jsPlumb.makeTarget does not support Connector parameters. It is for creating targets only; Connector parameters will be set by the source Endpoint in any Connections that are made to the element that you turned into a target by using this method.

Gradients

The Canvas and SVG renderers both support gradients. The VML renderer does not. jsPlumb uses its own syntax to define gradients, to abstract out the differences between the syntax required by canvas and that required by SVG.

There are two types of gradients available - a 'linear' gradient, which consists of colored lines all going in one direction, and a 'radial' gradient, which consists of colored circles emanating from one circle to another. Because of their basic shape, jsPlumb supports only linear gradients for Connectors. But for Endpoints, jsPlumb supports both linear and radial gradients.

Connector gradients
To specify a linear gradient to use in a Connector, you must add a gradient object to your Connector's paintStyle, for instance:
jsPlumb.connect({
	source : "window2",
	target : "window3",
	paintStyle:{
		gradient:{
			stops:[[0,"green"], [1,"red"]]
		},
		lineWidth:15
	}
});
Here we have connected window2 to window3 with a 15 pixel wide connector that has a gradient from green to red.

Notice the gradient object and the stops list inside it - the gradient consists of an arbitrary number of these "color stops". Each color stop is comprised of two values - [position, color]. Position must be a decimal value between 0 and 1 (inclusive), and indicates where the color stop is situated as a fraction of the length of the entire gradient. Valid values for the colors in the stops list are the same as those that are valid for strokeStyle when describing a color.

As mentioned, the stops list can hold an arbitrary number of entries. Here's an example of a gradient that goes from red to blue to green, and back again through blue to red:
jsPlumb.connect({
	source : 'window2',
	target : 'window3',
	paintStyle : {
		gradient:{
			stops:[[0,'red'], [0.33,'blue'], [0.66,'green'], [0.33,'blue'], [1,'red']]
		},
		lineWidth : 15
	}
});
Note: when using the VML renderer, jsPlumb will simply ignore the gradient directive so it is best to ensure you also supply a strokeStyle in your paintStyle object, to give jsPlumb something to fall back on. If you do not supply a strokeStyle your Connectors will be painted black. The previous example might look like this, for instance:
jsPlumb.connect({
	source : 'window2',
	target : 'window3',
	paintStyle:{
		strokeStyle:'red',
		gradient:{
			stops:[[0,'red'], [0.33,'blue'], [0.66,'green'], [0.33,'blue'], [1,'red']]
		},
		lineWidth:15
	}
});
Notice the strokeStyle:'red' directive at the beginning of the parameter list in paintStyle.
Endpoint gradients
Endpoint gradients are specified using the same syntax as Connector gradients. You put the gradient specifier either in the endpoint member, or if you are specifying different Endpoints for each end of the Connector, in one or both of the values in the endpoints array. Also, this information applies to the case that you are creating standalone Endpoints that you will be configuring for drag and drop creation of new Connections.

This is an example of an Endpoint gradient that is different for each Endpoint in the Connector. This comes from the main demo; it is the Connector joining Window 2 to Window 3:

var w23Stroke = 'rgb(189,11,11)';
jsPlumb.connect({
	source : 'window2',
	target : 'window3',
	paintStyle:{
		lineWidth:8,
		strokeStyle:w23Stroke
	},
 	anchors:[ [0.3,1,0,1], "TopCenter" ],
 	endpoint:"Rectangle",
 	endpointStyles:[
 		{ gradient : {stops:[[0, w23Stroke], [1, '#558822']] } },
    	{ gradient : {stops:[[0, w23Stroke], [1, '#882255']] } }
    ]
});
The first entry in the gradient will be the one that is on the Connector end of the Endpoint. You can of course have as many color stops as you want in this gradient, just like with Connector gradients.
Applying the gradient in Endpoints
Only the Dot and Rectangle endpoints honour the presence of a gradient (and, remember, not in VML). The Image endpoint of course ignores a gradient as it does no painting of its own.

The type of gradient you will see depends on the Endpoint type:

CSS Class Reference

jsPlumb attaches classes to each of the UI components it creates.

These class names are exposed on the jsPlumb object and can be overridden if you need to do so (see the third column in the table)

ComponentCSS ClassjsPlumb Member
Connector_jsPlumb_connectorconnectorClass
Endpoint_jsPlumb_endpointendpointClass
Overlay_jsPlumb_overlayoverlayClass

You would typically use these to establish appropriate z-indices for your UI.

Animation

jsPlumb offers an 'animate' function, which wraps the underlying animation engine for whichever library you happen to be using and inserts a callback for jsPlumb to repaint whatever it needs to at each step. You could of course do this yourself; it's a convenience method really.

The method signature is:

jsPlumb.animate : function(el, properties, options) 
The arguments are as follows:

Retrieving Connection Information

jsPlumb offers one fairly versatile method - getConnections - to retrieve information about the currently managed connections.

Before you use this method you should understand jsPlumb's notion of 'scope' - documentation is here

Retrieving connections for a single scope

To do this, you call getConnections with either no arguments, in which case jsPlumb uses the default scope, or with a string specifying one scope

var connectionList = jsPlumb.getConnections();     // you get a list of Connection objects that are in the default scope.
Compare this with:
var connectionList = jsPlumb.getConnections("myScope");     // you get a list of Connection objects that are in "myScope".

More advanced filtering

getConnections optionally takes a JS object specifying filter parameters, of which there are three: Each of these three parameters may be supplied as a string, or a list of strings - see the examples below.

The return value of a call to getConnection using a JS object as parameter varies on how many scopes you defined. If you defined only a single scope then jsPlumb returns you a list of Connections in that scope. Otherwise the return value is a dictionary whose keys are scope names, and whose values are lists of Connections. For example, the following call:

	jsPlumb.getConnections({scope:["someScope", "someCustomScope"]});
would result in this output:
{
	"someScope" : [ 1..n Connections ],
	"someCustomScope": [ 1..m Connections ]
}
The following examples show the various ways you can get connection information:

Events

jsPlumb supports binding to several different events, both on Connections, Endpoints and Overlays, and also on the jsPlumb object itself. To bind events on any of these objects you use the jsPlumb.bind(object, event, callback) method, except in the case of Overlays, in which you provide the event listeners in the Overlay's constructor arguments (example below).

jsPlumb Events

Connection Events

Endpoint Events

Overlay Events

Registering event listeners on an Overlay is a slightly different procedure - you provide them as arguments to the Overlay's constructor. This is because you never actually act on an 'Overlay' object. Here's how to register a click listener on an Overlay:
jsPlumb.connect({
	source:"el1",
	target:"el2",
	overlays:[
		[ "Label", {
			events:{
				click:function(labelOverlay, originalEvent) { alert("you clicked on the label overlay for this connection :" + labelOverlay.connection) }
			}
		}] 	
	]
});

jsPlumb.connect Examples

This section provides examples of how to use the programmatic API to establish Connections.

The basic syntax of a call is that you execute 'connect', providing a source and a target, and optionally a paintStyle and preferences for where you want the plumbing to be anchored on each element, as well as the type of connector to use.

Draggable Connections Examples

This is a list of examples of how to use jsPlumb to create Connections using drag and drop.

The basic procedure is:

  1. 1a. Create Endpoints and register them on elements in your UI
  2. 1b. alternatively, create a source endpoint and then make some element a drop target
  3. 2. Drag and Drop
That's all there is to it. Of course there are plenty of options you can set when doing this...it will be easier to show you some examples:

Utility Functions

Advanced Topics

Which files are which?

In development, jsPlumb is broken up into seven scripts: These seven files are packaged together to form the scripts that people use, for example:

Pluggable Library Support

Out of the box, jsPlumb can be run on top of jQuery, MooTools or YUI3. This is achieved by delegating several core methods - tasks such as finding an element by id, finding an element's position or dimensions, initialising a draggable, etc - to the library in question.

To develop one of these, your test page should include the first two scripts discussed above, and then your own script containing your library specific functionality. The existing implementations may be documented well enough for you to create your own, but contact me if you need assistance. If you do this, it would be great to share it with everyone...