New connection strategies can be defined in the joint.connectionStrategies
namespace (e.g. joint.connectionStrategies.myConnectionStrategy
) or passed directly as a function to the connectionStrategy
option of a paper.
In either case, the connection strategy function must return an end definition (i.e. an object in the format supplied to the link.source()
and link.target()
functions). The function is expected to have the form function(endDefinition, endView, endMagnet, coords)
:
endDefinition | object | An end definition; the output of the appropriate end function (link.source() or link.target() ). An object containing at least an id of the Element to which we are connecting. This object is expected to be changed by this function and then sent as the return value. |
---|---|---|
endView | dia.ElementView | The ElementView to which we are connecting. The Element model can be accessed as endView.model ; this may be useful for writing conditional logic based on element attributes. |
endMagnet | SVGElement | The SVGElement in our page that contains the magnet (element/subelement/port) to which we are connecting. |
coords | g.Point | A Point object recording the x-y coordinates of the user pointer when the connection strategy was invoked. |
Custom connection strategies may be enormously useful for your users. Here we provide some examples of custom functionality.
If your diagram makes heavy use of nested elements, it may be useful to always connect links to a top-level ancestor element (instead of the element on which the arrowhead was actually dropped by user interaction):
joint.connectionStrategies.topAncestor = function(end, endView) {
var ancestors = endView.model.getAncestors();
var numAncestors = ancestors.length;
var end = numAncestors ? ancestors[numAncestors - 1] : end;
return end;
}
paper.options.connectionStrategy = joint.connectionStrategies.topAncestor;
If your diagram uses ports, you usually do not want links to be able to connect anywhere else. The solution is similar to the one above:
joint.connectionStrategies.firstPort = function(end, endView) {
var ports = endView.model.getPorts();
var numPorts = ports.length;
var end = numPorts ? { id: end.id, port: ports[0].id } : end;
return end;
}
paper.options.connectionStrategy = joint.connectionStrategies.firstPort;
Furthermore, it is very easy to replicate the built-in anchor functions for connection strategy scenarios - simply apply the anchor function to the received end
parameter:
joint.connectionStrategy.midSide = function(end) {
end.anchor = {
name: 'midSide',
args: {
rotate: true
}
};
return end;
}
paper.options.connectionStrategy = joint.connectionStrategy.midSide;
What if we needed to replicate a built-in connection point function instead? We use the same idea as in the previous example:
joint.connectionStrategy.boundary = function(end) {
end.connectionPoint = {
name: 'boundary',
args: {
offset: 5
}
};
return end;
}
paper.options.connectionStrategy = joint.connectionStrategy.boundary;
Of course, it is also possible to combine both of the examples and assign an anchor
as well as connectionPoint
to the end
parameter of the modified link.