UNPKG

jointjs

Version:

JavaScript diagramming library

281 lines (225 loc) 14.4 kB
<p>The basic model for diagram links. It inherits from <a href="#dia.Cell">joint.dia.Cell</a> with a few additional properties and methods specific to links. For a quick introduction to elements, see our <a href="http://resources.jointjs.com/tutorial/elements">tutorial</a>.</p> <p>Links' properties may be split into several groups according to their function:</p> <h4 id="dia.Link.intro.geometry">Geometry</h4> <p>Links have two crucial attributes: <code>source</code> and <code>target</code>. They define the starting point and the end point of the link. They can be defined with a Cell id (optionally, with additional subelement/magnet/port reference) or with a Point:</p> <pre><code>var link1 = new joint.dia.Link({ source: { id: sourceId }, target: { id: targetId, port: portId } }); var link2 = new joint.dia.Link({ source: { id: sourceId }, target: { x: 100, y: 100 } });</code></pre> <p>The <a href="#dia.Link.geometry.source"><code>source</code></a> and <a href="#dia.Link.geometry.target"><code>target</code></a> properties accept additional modifier properties that modify the actual position of the link end: <a href="#dia.Link.geometry.anchor"><code>anchor</code></a>/<a href="#dia.Link.geometry.linkAnchor"><code>linkAnchor</code></a>, and <a href="#dia.Link.geometry.connectionPoint"><code>connectionPoint</code></a>.</p> <p>Additionally, the path of the link is determined by its <a href="#dia.Link.geometry.vertices"><code>vertices</code></a>, and the applied <a href="#dia.Link.geometry.router"><code>router</code></a> and <a href="#dia.Link.geometry.connector"><code>connector</code></a>. All these attributes are described in more detail in <a href="#dia.Link.geometry">link geometry documentation</a>.</p> <h4 id="dia.Link.intro.presentation">Presentation</h4> <p>Each <code>joint.dia.Link</code> defines its own SVG <code>markup</code> which is then used by <a href="#dia.LinkView"><code>joint.dia.LinkView</code></a> to render the link to the <a href="#dia.Paper">paper</a>. For instance, the <a href="#shapes.standard.Link"><code>joint.shapes.standard.Link</code></a> (which inherits from <code>joint.dia.Link</code>) defines its markup using the <a href="#dia.Cell.markup.json">JSON array notation</a> as follows:</p> <pre><code>markup: [{ tagName: 'path', selector: 'wrapper', attributes: { 'fill': 'none', 'cursor': 'pointer', 'stroke': 'transparent', 'stroke-linecap': 'round' } }, { tagName: 'path', selector: 'line', attributes: { 'fill': 'none', 'pointer-events': 'none' } }]</code></pre> <p>As we can see, the <code>joint.shapes.standard.Link</code> shape consists of two <q>subelements</q>: one SVGPathElement named <code>'wrapper'</code> and one SVGPathElement named <code>'line'</code>. The <a href="#dia.Link.intro.styling"><code>attrs</code></a> object refers to the subelements' names (<q>selectors</q>) to provide SVG attributes to these constituent SVGElements.</p> <div class="docs-important-note"> Direct use of <code>joint.dia.Link</code> is deprecated. Use links from <a href="#shapes.standard"><code>standard</code></a> namespace. </div> <p>The <code>joint.dia.Link</code> markup looks like:</p> <pre><code data-lang="svg">&lt;path class=&quot;connection&quot;/&gt; &lt;path class=&quot;marker-source&quot;/&gt; &lt;path class=&quot;marker-target&quot;/&gt; &lt;path class=&quot;connection-wrap&quot;/&gt; &lt;g class=&quot;labels&quot; /&gt; &lt;g class=&quot;marker-vertices&quot;/&gt; &lt;g class=&quot;marker-arrowheads&quot;/&gt; &lt;g class=&quot;link-tools&quot; /&gt;</code></pre> <p>As you can see, the link consists of a couple of SVG path elements and couple of SVG group elements:</p> <ul> <li><code>.connection</code> is the actual line of the link.</li> <li><code>.connection-wrap</code> is an SVG path element that covers the <code>.connection</code> element and is usually thicker so that the link is able to handle pointer events (mousedown, mousemove, mouseup) that didn't target the thin <code>.connection</code> path exactly. This makes it easy to &quot;grab&quot; the link even though the mouse cursor didn't point exactly at the (usually thin) <code>.connection</code> path element.</li> <li><code>.marker-source</code> and <code>.marker-target</code> are the arrowheads of the link.</li> </ul> <pre><code>link.attr({ '.connection': { stroke: 'blue' }, '.marker-source': { fill: 'red', d: 'M 10 0 L 0 5 L 10 10 z' }, '.marker-target': { fill: 'yellow', d: 'M 10 0 L 0 5 L 10 10 z' } });</code></pre> <p>The <code>markup</code> attribute is not the only presentation attribute that may be specified for a <code>joint.dia.Link</code>. However, all the following Link properties are deprecated and included only for backwards compatibility. Use <a href="#linkTools">link tools</a> instead:</p> <ul> <li><code>vertexMarkup</code> - provide default vertex markup for all vertices created on an instance of this Link type (on hover).</li> <li><code>toolMarkup</code> - provide custom tool markup for all instances of this Link type (on hover).</li> <li><code>doubleToolMarkup</code> - provide custom markup for second set of tools for all instances of this Link type (on hover, if <code>linkView.doubleLinkTools</code> is <code>true</code>).</li> <li><code>arrowheadMarkup</code> - provide custom arrowhead markup for all instances of this Link type (on hover).</li> </ul> <h4 id="dia.Link.intro.styling">Styling</h4> <p>The keys of the <code>attrs</code> object are selectors that match subelements defined in the link's <a href="#dia.Link.intro.presentation"><code>markup</code></a>. The values of this object are SVG attributes that will be set on the selected subelements. One can find the full list of SVG attributes and their descriptions online, e.g. on <a href="https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute">MDN</a>.</p> <p>For example, in order to set a red stroke color on a subelement called <code>'line'</code>, the <code>attrs</code> object would contain:</p> <pre><code>line: { stroke: 'red' }</code></pre> <p>If you simply need to change a value of an attribute, it is not recommended to modify the <code>attrs</code> object directly. Instead, use the <a href="#dia.Link.prototype.attr"><code>link.attr()</code></a> method.</p> <p>We can use the <a href="#shapes.standard.Link"><code>joint.shapes.standard.Link</code></a> (which inherits from <code>joint.dia.Link</code>) as an example. The <code>attrs</code> object in its definition is provided below:</p> <pre><code>attrs: { line: { connection: true, stroke: '#333333', strokeWidth: 2, strokeLinejoin: 'round', targetMarker: { 'type': 'path', 'd': 'M 10 -5 0 0 10 5 z' } }, wrapper: { connection: true, strokeWidth: 10, strokeLinejoin: 'round' } }</code></pre> <p>Notice that the object makes use of special JointJS attributes (e.g. <a href="#dia.attributes.connection"><code>connection</code></a>, <a href="#dia.attributes.targetMarker"><code>targetMarker</code></a>) on top of standard SVG attributes (e.g. <code>stroke</code>, <code>strokeWidth</code>). All of these <q>special attributes</q> are listed in the <a href="#dia.attributes">attributes</a> section of this documentation. You should also refer to our <a href="http://resources.jointjs.com/tutorial/special-attributes">tutorial on special attributes</a>.</p> <p>In the context of links, the most important special attribute is <code>connection</code>. It specifies that the SVGPathElement(s) in question should follow the path of the Link's model, as provided by the interplay of <a href="#dia.Link.intro.geometry">link geometry methods</a>.</p> <h4 id="dia.Link.intro.z">Z</h4> <p>The <code>z</code> property specifies the stack order of the element in the SVG DOM. An element with a higher <code>z</code> value will be rendered in front of an element with a lower <code>z</code> value. (<a href="#dia.Element.intro.z">This also applies to Elements.</a>)</p> <h4 id="dia.Link.intro.labels">Labels</h4> <p>You may provide an array of labels to the link through the <code>labels</code> attribute. Each can have its own markup, position, and attrs. See the <a href="#dia.Link.labels">link labels documentation</a>. You should also refer to our <a href="http://resources.jointjs.com/tutorial/link-labels">tutorial</a> on link labels.</p> <h4 id="dia.Link.intro.customAttributes">Custom Attributes</h4> <p>It is also possible to pass custom attributes to the link. These may be useful to identify an individual link model for the purposes of linkView interaction (see <code>LinkView</code> <a href="#dia.LinkView">documentation</a> for more information). For example, to only enable custom contextmenu interaction for <code>link1</code> but not <code>link2</code>:</p> <pre><code>var CustomLinkView = joint.dia.LinkView.extend({ contextmenu: function(evt, x, y) { if (this.model.get('customLinkInteractions')) { // only links with `customLinkInteractions: true` this.addLabel(x, y); } } }); var paper = new joint.dia.Paper({ //... linkView: CustomLinkView, interactive: function(cellView) { if (cellView.model.get('customLinkInteractions')) { // only links with `customLinkInteractions: true` return { vertexAdd: false }; } return true; // otherwise } }); var link1 = new joint.dia.Link({ //... customLinkInteractions: true // right-click adds a label }); var link2 = new joint.dia.Link({ //... customLinkInteractions: false // or omit completely });</code></pre> <h4 id="dia.Link.intro.events">Events</h4> <p>Links trigger several special events, detailed in the <a href="#dia.Link.events">link events documentation</a>. <h4 id="dia.Link.intro.customLink">Custom Link</h4> <p>It is possible to extend the <code>joint.dia.Link</code> class to create a custom link. A custom link may override Link properties to assign its own defaults. These values override builtin defaults, if provided, and are applied to all instances of the new Link type, unless an individual instance overrides them with its own values. The following Link properties are applicable in this context:</p> <ul> <li><code>markup</code> - provide default link markup for all instances of this Link type, specified with a <a href="#dia.Cell.markup.json">JSON array</a>.</li> <li><code>attrs</code> - provide default link attributes for all instances of this Link type. These allow you to change the style and size of SVG elements, identified by their selectors.</li> <li><code>defaultLabel</code> - provide default properties (markup, attrs, position) for all labels created on an instance of this Link type.</li> </ul> <p>The values of these defaults may be important; the <code>linkView.addLabel()</code> <a href="#dia.LinkView.prototype.addLabel">shortcut function</a> is only capable of adding default labels to the link.</p> <p>Creating custom links is explained in more detail in our <a href="http://resources.jointjs.com/tutorial/custom-links">tutorial</a>.</p> <p>Example:</p> <pre><code>var CustomLink = joint.dia.Link.define('examples.CustomLink', { defaultLabel: { markup: [ { tagName: 'circle', selector: 'body' }, { tagName: 'text', selector: 'label' } ], attrs: { label: { text: '%', // default label text fill: '#ff0000', // default text color fontSize: 14, textAnchor: 'middle', yAlignment: 'middle', pointerEvents: 'none' }, body: { ref: 'label', fill: '#ffffff', stroke: '#000000', strokeWidth: 1, refR: 1, refCx: 0, refCy: 0 } }, position: { distance: 0.5, // place label at midpoint by default offset: { y: -20 // offset label by 20px upwards by default }, args: { absoluteOffset: true // keep offset absolute when moving by default } } } }); var link = new CustomLink({ //... });</code></pre> <h4 id="dia.Link.intro.builtinDefaultAttributes">Builtin Default Attributes</h4> <p>To ensure backwards compatibility, the <code>joint.dia.Link</code> class comes with a private builtin <code>defaultLabel</code> attribute. It is reproduced here for reference:</p> <pre><code>defaultLabel: { // builtin default markup: // used if neither defaultLabel.markup // nor label.markup is set markup: [ { tagName: 'rect', selector: 'rect' }, { tagName: 'text', selector: 'text' } ], // builtin default attributes: // applied only if builtin default markup is used attrs: { text: { fill: '#000000', fontSize: 14, textAnchor: 'middle', yAlignment: 'middle', pointerEvents: 'none' }, rect: { ref: 'text', fill: '#ffffff', rx: 3, ry: 3, refWidth: 1, refHeight: 1, refX: 0, refY: 0 } }, // builtin default position: // used if neither defaultLabel.position // nor label.position is set position: { distance: 0.5 } }</code></pre> <p>If custom <code>position</code> object is not provided (neither as a type default nor as an instance value), builtin default label position is applied instead (<code>{ distance: 0.5 }</code>).</p> <p>Furthermore, if custom <code>markup</code> is not provided (neither as a type default nor as an instance value), builtin default label markup is applied, alongside the builtin default label attrs object. However, it is very highly recommended that you provide both your own <code>markup</code> and your own <code>attrs</code> - unless you want to use the builtin default precisely as-is.</p>