jointjs
Version:
JavaScript diagramming library
97 lines (68 loc) • 4.27 kB
HTML
<p>New connection strategies can be defined in the <code>joint.connectionStrategies</code> namespace (e.g. <code>joint.connectionStrategies.myConnectionStrategy</code>) or passed directly as a function to the <code>connectionStrategy</code> <a href="#dia.Paper.prototype.options.connectionStrategy">option of a paper</a>.</p>
<p>In either case, the connection strategy function must return an end definition (i.e. an object in the format supplied to the <code>link.source()</code> and <code>link.target()</code> functions). The function is expected to have the form <code>function(endDefinition, endView, endMagnet, coords)</code>:</p>
<table>
<tr>
<th>endDefinition</th>
<td><i>object</i></td>
<td>An end definition; the output of the appropriate end function (<code>link.source()</code> or <code>link.target()</code>). An object containing at least an <code>id</code> 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.</td>
</tr>
<tr>
<th>endView</th>
<td><i>dia.ElementView</i></td>
<td>The ElementView to which we are connecting. The Element model can be accessed as <code>endView.model</code>; this may be useful for writing conditional logic based on element attributes.</td>
</tr>
<tr>
<th>endMagnet</th>
<td><i>SVGElement</i></td>
<td>The SVGElement in our page that contains the magnet (element/subelement/port) to which we are connecting.</td>
</tr>
<tr>
<th>coords</th>
<td><i>g.Point</i></td>
<td>A Point object recording the x-y coordinates of the user pointer when the connection strategy was invoked.</td>
</tr>
</table>
<p>Custom connection strategies may be enormously useful for your users. Here we provide some examples of custom functionality.</p>
<h4 id="ancestors">Connecting to Ancestors</h4>
<p>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):</p>
<pre><code>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;</code></pre>
<h4 id="ports">Connecting to Ports</h4>
<p>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:</p>
<pre><code>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;</code></pre>
<h4 id="anchors">Replicating Built-in Anchor Functions</h4>
<p>Furthermore, it is very easy to replicate the built-in <a href="#anchors">anchor functions</a> for connection strategy scenarios - simply apply the anchor function to the received <code>end</code> parameter:</p>
<pre><code>joint.connectionStrategy.midSide = function(end) {
end.anchor = {
name: 'midSide',
args: {
rotate: true
}
};
return end;
}
paper.options.connectionStrategy = joint.connectionStrategy.midSide;</code></pre>
<h4 id="connectionPoints">Replicating Built-in Connection Point Functions</h4>
<p>What if we needed to replicate a built-in <a href="#connectionPoints">connection point function</a> instead? We use the same idea as in the previous example:</p>
<pre><code>joint.connectionStrategy.boundary = function(end) {
end.connectionPoint = {
name: 'boundary',
args: {
offset: 5
}
};
return end;
}
paper.options.connectionStrategy = joint.connectionStrategy.boundary;</code></pre>
<p>Of course, it is also possible to combine both of the examples and assign an <code>anchor</code> as well as <code>connectionPoint</code> to the <code>end</code> parameter of the modified link.</p>