Styling edges
There are a few approaches you can take when it comes to styling your edges - JsPlumb provides an out of the box mapping from edge data to basic properties such as edge width, color etc, via the concept of Simple edge styles. You can also use CSS, or you can map a PaintStyle to your edges via a view or in the UI defaults. That's a lot of choice, so here we present a quick pros and cons for each option:
| Method | Pros | Cons |
|---|---|---|
| CSS | Clean separation of presentation from code. Allows usage of various SVG CSS effects. Allows styling all edges of some type uniformly. | Does not support export to SVG. Does not support styling each edge individually. Does not support path outlines. |
| Paint styles | Allows styling all edges of some type uniformly. Supports export to SVG. Supports path outlines. | Does not support styling each edge individually. |
| Simple edge styles | Minimal setup. Allows each edge to be styled individually. Seamlessly integrated with update and undo/redo. Supports path outlines. Supports export to SVG. | Each edge needs its own styles declared in the backing data. Limited set of configurable properties. |
| UI Defaults | Allows configuration of default styles value which will apply, in the absence of some other value, to all edges. Supports export to SVG. Supports path outlines. | Does not support styling each edge individually. Applies to all types (but you can override on a per-type basis via Paint styles(. |
Styling with CSS
Targeting the SVG path
Since JsPlumb uses SVG to render edges, you can target the artifacts that JsPlumb adds to the DOM via CSS. JsPlumb uses a class of jtk-connector on the SVG element it uses for each edge, and the edge itself is written as one or more path elements inside of that:
<svg class="jtk-connector">
<path d="..." class="jtk-connector-outline"></path>
<path d="..."></path>
</svg>
So to target the element used to render the path, you need a rule like this:
.jtk-connector path {
stroke-width:2;
stroke:cadetblue;
stroke-dasharray: 2;
}
Hover styles
To change the appearance of an edge on hover, use the :hover css meta class:
.jtk-connector path:hover {
stroke:orangered;
}
Note that the above example targets the path element on hover, but you can also target the parent SVG element of course:
.jtk-connector:hover {
outline:1px solid orangered;
}
Marching ants effect
It's simple to get this 'marching ants' effect via CSS with JsPlumb:
1. Define the CSS animation
Define a CSS animation with a single keyframe that sets the dash offset:
@keyframes dashdraw {
0% {
stroke-dashoffset:10;
}
}
2. Map the animation to a CSS rule
.animated-edge {
stroke-dasharray:5;
animation: dashdraw .5s linear infinite;
}
3. Use the cssClass property in an edge definition to map to this class (optional)
import { newInstance } from "@jsplumbtoolkit/browser-ui"
const toolkit = newInstance()
const surface = toolkit.render(someElement, {
"view": {
"edges": {
"animated": {
"cssClass": "animated-edge"
}
}
}
});
We said that (3) is optional because if you just want to apply it to every edge in your dataset you can change the CSS rule shown in (2) to target every edge:
.jtk-connector {
stroke-dasharray:5;
animation: dashdraw .5s linear infinite;
}
Selected edges
When an edge is in a Toolkit's current selection, it has the CSS class jtk-surface-selected-connection applied to it. You can target this class to change the appearance of either the connector's parent element:
.jtk-surface-selected-connection {
outline:2px solid orangered;
}
or the path element representing the edge:
.jtk-surface-selected-connection path {
stroke:orangered;
}
Styling with PaintStyles
A PaintStyle is an object containing various properties to apply to a given type of edge. The definition of PaintStyle is:
Interface PaintStyle
| Name | Type | Description |
|---|---|---|
dashstyle? | string | Dash style for the path, in the format discussed here https://developer.mozilla.org/en-US/docs/Web/CSS/stroke-dasharray. |
fill? | string | For overlays and endpoints, the color to use to fill the SVG shape |
outlineStroke? | string | The color to use for path outline. |
outlineWidth? | number | The width of the outline. The value here should indicate how much of an outline you want on each side of the path, _not_ the total width of the outline. |
stroke? | string | The color to use to stroke the SVG path. |
strokeWidth? | number | The width of the path. |
With the exception of stroke all properties are optional. To setup an outline path, you must provide both outlineStroke and outlineWidth.
Mapping a PaintStyle in a view
You can map a PaintStyle to some specific edge type inside a view:
import { newInstance } from "@jsplumbtoolkit/browser-ui"
const toolkit = newInstance()
const surface = toolkit.render(someElement, {
"view": {
"edges": {
"redWithOutline": {
"paintStyle": {
"stroke": "red",
"strokeWidth": 3
}
}
}
}
});
Mapping a PaintStyle in the UI defaults
You can also set a default paint style via the defaults for some surface:
import { newInstance } from "@jsplumbtoolkit/browser-ui"
const toolkit = newInstance()
const surface = toolkit.render(someElement, {
"defaults": {
"paintStyle": {
"stroke": "red",
"strokeWidth": 3
}
}
});
Controlling the hit zone
By default, JsPlumb paints a single path element for each edge. If you want your users to be able to interact with your edges but your edges have a stroke width of only a couple of pixels, this can be difficult. To manage this with a paintStyles we recommend using the outlineWidth and outlineStroke paint style properties to setup a hit zone:
import { newInstance } from "@jsplumbtoolkit/browser-ui"
const toolkit = newInstance()
const surface = toolkit.render(someElement, {
"defaults": {
"paintStyle": {
"stroke": "red",
"strokeWidth": 3,
"outlineStroke": "transparent",
"outlineWidth": 2
}
}
});
When you provide outlineWidth and outlineStroke properties in a PaintStyle, the visible width of the outline is computed as:
w = strokeWidth + (2 * outlineWidth)
which is to say that the outlineWidth value you provide is applied to each side of the connector's path.
In this example we've used "transparent" for the outline color, which gives us the expanded hit zone without altering the appearance of each edge. You can, of course, use any color you like.
Hover styles
You can also provide a hoverPaintStyle property in your view, which JsPlumb will use to paint the edge when the mouse is hovering over it:
import { newInstance } from "@jsplumbtoolkit/browser-ui"
const toolkit = newInstance()
const surface = toolkit.render(someElement, {
"view": {
"edges": {
"redWithOutline": {
"paintStyle": {
"stroke": "red",
"strokeWidth": 3,
"outlineStroke": "orangered",
"outlineWidth": 2
},
"hoverPaintStyle": {
"stroke": "green",
"strokeWidth": 3,
"outlineStroke": "yellowgreen",
"outlineWidth": 4
}
}
}
}
});
Simple edge styles
Simple edge styles allow you to map values from an edge's backing data to its appearance.
Supported properties
- color A valid CSS color, which will be used to paint the connector
- lineWidth An integer value denoting the width, in pixels, of the connector.
- outlineColor A valid CSS color, which will be used to paint the connector's outline.
- outlineWidth An integer value denoting the width of the connector's outline. Note that this is not added to the
lineWidthvalue; this values describes the total width of the outline. For instance, alineWidthof 3 and anoutlineWidthof 5 would result in a 1 pixel outline on either side of the connector path.
None of these properties are mandatory. JsPlumb will fall back to its defaults for these via the paintStyle mechanism if your edge data does not contain any of these properties.
Example
import { newInstance } from "@jsplumbtoolkit/browser-ui"
const toolkit = newInstance()
const surface = toolkit.render(someElement, {
"simpleEdgeStyles": true
});
toolkit.load({
type:"json",
data:{
nodes:[
{ id:"1" }, { id:"2" }
],
edges:[
{
source:"1",
target:"2",
data:{
color:"cadetblue",
lineWidth:3,
outlineColor:"pink",
outlineWidth:5
}
}
]
}
})
In this example the edge in our dataset will have a color of "cadetblue" and a stroke width of 3 pixels. It will also have an outline of 5 pixels each side, and the color of the outline will be pink. I think we can all agree it will look pretty fetching indeed.
And..that's it, basically. There's not much else to it. If you call updateEdge(...) with some new values for these properties, the edge will be updated.
Let's render that example from above. We'll render an edge with this backing data:
{
color:"cadetblue",
lineWidth:3,
outlineColor:"pink",
outlineWidth:5,
id:"edge"
}
(we gave it an id because we want to access it when you press a button in a moment; id is not a mandatory property).
If you now , we'll update those values:
toolkit.updateEdge("edge", {
color:"black",
outlineColor:"yellow",
lineWidth:2,
outlineWidth:3
})
Simple edge styles are switched on by default. If you do not want this behaviour in your app, you can save yourself some CPU cycles by setting simpleEdgeStyles:false in your render options.
Styling with UI Defaults
The UI defaults support a few keys that allow you to configure default paint styles for your edges, and to setup a hit zone for edges that will apply to every edge in your app.
Supported properties
| Key | Constant | Description |
|---|---|---|
paintStyle | DEFAULT_KEY_PAINT_STYLE | A PaintStyle object as discussed above, whose values will be used for all edges unless a more specific type mapping is found in the view. Defaults to a stroke width of 2 pixels and a stroke color of #456. |
hoverPaintStyle | DEFAULT_KEY_HOVER_PAINT_STYLE | A PaintStyle object as discussed above, whose values will be used for all edges when the mouse is hovering over it unless a more specific type mapping is found in the view. Defaults to null. |
paintConnectorOutline | DEFAULT_KEY_PAINT_CONNECTOR_OUTLINE | Defaults to false. When true, JsPlumb will draw a second path underneath each edge, with, by default, a transparent stroke. This arrangement is a useful way to manage the hit zone for your edges, to make it easier for your users to click/tap on edges. The outline path is assigned a CSS class of .jtk-connector-outline, so you can override its transparent stroke via CSS if you wish. |
connectorOutlineWidth | DEFAULT_KEY_CONNECTOR_OUTLINE_WIDTH | Defaults to 10 pixels, but only takes effect if paintConnectorOutline is true. NOTE this value defines the total width of the outline path, not, as in the case of the outlineWidth property of a PaintStyle, the number of pixels to pad the main edge path with. |
connectorOutlineColor | DEFAULT_KEY_CONNECTOR_OUTLINE_COLOR | Defaults to "transparent". You can use any valid CSS3 color spec here. |
Example
import { newInstance } from "@jsplumbtoolkit/browser-ui"
const toolkit = newInstance()
const surface = toolkit.render(someElement, {
"defaults": {
"paintStyle": {
"stroke": "red",
"strokeWidth": 3
},
"hoverPaintStyle": {
"stroke": "orangered",
"strokeWidth": 5
},
"paintConnectorOutline": true,
"connectorOutlineWidth": 15
}
});
Controlling the hit zone
As discussed in the paint style section above, by default, JsPlumb paints a single path element for each edge. If you want your users to be able to interact with your edges but your edges have a stroke width of only a couple of pixels, this can be difficult. To manage this via UI defaults you can use the paintConnectorOutline default:
import { newInstance } from "@jsplumbtoolkit/browser-ui"
const toolkit = newInstance()
const surface = toolkit.render(someElement, {
"defaults": {
"paintConnectorOutline": true,
"connectorOutlineWidth": 30
}
});
In this example we've instructed JsPlumb to paint a connector outline on every edge, and we've also used the connectorOutlineWidth default to specify we want the outline to be 30 pixels. If you omit this flag JsPlumb will use a default value of 10 pixels. By default this outline will be transparent, but you can also set connectorOutlineColor if you wish:
import { newInstance } from "@jsplumbtoolkit/browser-ui"
const toolkit = newInstance()
const surface = toolkit.render(someElement, {
"defaults": {
"paintConnectorOutline": true,
"connectorOutlineWidth": 20,
"connectorOutlineColor": "cadetblue"
}
});