jointjs
Version:
JavaScript diagramming library
338 lines (269 loc) • 16.4 kB
HTML
<html>
<head>
<link rel="canonical" href="http://www.jointjs.com/" />
<meta name="description" content="Create interactive diagrams in JavaScript easily. JointJS plugins for ERD, Org chart, FSA, UML, PN, DEVS, LDM diagrams are ready to use." />
<meta name="keywords" content="JointJS, JavaScript, diagrams, diagramming library, UML, charts" />
<link href="http://fonts.googleapis.com/css?family=Source+Sans+Pro:400,700" rel="stylesheet" type="text/css" />
<link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet">
<link rel="stylesheet" href="css/tutorial.css" />
<link rel="stylesheet" href="../node_modules/prismjs/themes/prism.css">
<!-- Dependencies: -->
<script src="../node_modules/jquery/dist/jquery.js"></script>
<script src="../node_modules/lodash/lodash.js"></script>
<script src="../node_modules/backbone/backbone.js"></script>
<link rel="stylesheet" type="text/css" href="../build/joint.min.css" />
<script type="text/javascript" src="../build/joint.min.js"></script>
<title>JointJS - JavaScript diagramming library - Getting started.</title>
</head>
<body class="language-javascript tutorial-page">
<script>
SVGElement.prototype.getTransformToElement = SVGElement.prototype.getTransformToElement || function(toElement) {
return toElement.getScreenCTM().inverse().multiply(this.getScreenCTM());
};
</script>
<div class="tutorial">
<h2>Link Tools</h2>
<p>This is the eighth article of the intermediate section of the JointJS tutorial.
<a href="element-tools.html">Go back to element tools.</a>
Alternatively, you can <a href="intermediate.html">return to index</a> of all articles.</p>
<p>JointJS allows creating fully customizable <a href="/docs/jointjs#linkTools" target="_blank">user
interaction tools for your links</a>.
These tools show up on user interaction (e.g. mouseover) with a link view and allow the user to interact
with the underlying <a href="links.html">link model</a>.
For example:</p>
<div class="paper" id="paper-link-tools-example"></div>
<p>JointJS source code: <a href="js/link-tools-example.js" target="_blank">link-tools-example.js</a></p>
<p>The process of getting link tools up and running on your link view is relatively straightforward:</p>
<ul>
<li><a href="#link-tools">Create individual link tools.</a></li>
<li><a href="#add-to-tools-view">Add the link tools to a toolsView.</a></li>
<li><a href="#add-to-link-view">Add the toolsView to a link view.</a></li>
<li><a href="#interaction">Make the tools interactive.</a></li>
</ul>
<p>We will explain every step in turn.
We will also touch on <a href="#custom-button">creating custom buttons</a>.</p>
<h3 id="link-tools">Link Tools</h3>
<p>A <a href="/docs/jointjs#linkTools" target="_blank">link tool</a> (type
<a href="/docs/jointjs#dia.ToolView" target="_blank"><code>joint.dia.ToolView</code></a>) is a view that
renders a certain type of control elements on top of the link view it is attached to; for example the
<code>Vertices</code> <a href="/docs/jointjs#linkTools.Vertices" target="_blank">tool</a> creates an
interactive handle above every vertex (these handles then allow the user to move and/or delete each
vertex).
The JointJS library comes with a collection of pre-made link tool definitions in the
<a href="/docs/jointjs#linkTools" target="_blank"><code>joint.linkTools</code></a> namespace.</p>
<p>The pre-made link tools include:</p>
<ul>
<li><a href="/docs/jointjs#linkTools.Vertices" target="_blank"><code>Vertices</code></a> - adds handles
above link vertices</li>
<li><a href="/docs/jointjs#linkTools.Segments" target="_blank"><code>Segments</code></a> - adds handles
above link segments</li>
<li><a href="/docs/jointjs#linkTools.SourceArrowhead" target="_blank"><code>SourceArrowhead</code></a>
- adds a handle above link source connection point</li>
<li><a href="/docs/jointjs#linkTools.TargetArrowhead" target="_blank"><code>TargetArrowhead</code></a>
- adds a handle above link target connection point</li>
<li><a href="/docs/jointjs#linkTools.SourceAnchor" target="_blank"><code>SourceAnchor</code></a> - adds
a handle above link source anchor</li>
<li><a href="/docs/jointjs#linkTools.TargetAnchor" target="_blank"><code>TargetAnchor</code></a> - adds
a handle above link target anchor</li>
<li><a href="/docs/jointjs#linkTools.Boundary" target="_blank"><code>Boundary</code></a> - shows the
bounding box of the link</li>
<li><a href="/docs/jointjs#linkTools.Remove" target="_blank"><code>Remove</code></a> - adds an
interactive remove button</li>
</ul>
<p>To create a new link tool, we call its constructor:</p>
<pre><code>var verticesTool = new joint.linkTools.Vertices();</code></pre>
<p>The link tool constructors also accept optional arguments that modify the appearance and function of the
created tools:</p>
<pre><code>var verticesTool = new joint.linkTools.Vertices({
redundancyRemoval: false,
snapRadius: 10,
vertexAdding: false,
});</code></pre>
<h3 id="add-to-tools-view">Add to Tools View</h3>
<p>Link tools always need to come bundled in a tools view object (type
<a href="/docs/jointjs#dia.ToolsView" target="_blank"><code>joint.dia.ToolsView</code></a>).
This allows them to be shown/hidden as a group above a link.
We create a new tools view and add our tools to it:</p>
<pre><code>var verticesTool = new joint.linkTools.Vertices();
var segmentsTool = new joint.linkTools.Segments();
var sourceArrowheadTool = new joint.linkTools.SourceArrowhead();
var targetArrowheadTool = new joint.linkTools.TargetArrowhead();
var sourceAnchorTool = new joint.linkTools.SourceAnchor();
var targetAnchorTool = new joint.linkTools.TargetAnchor();
var boundaryTool = new joint.linkTools.Boundary();
var removeButton = new joint.linkTools.Remove();
var toolsView = new joint.dia.ToolsView({
tools: [
verticesTool, segmentsTool,
sourceArrowheadTool, targetArrowheadTool,
sourceAnchorTool, targetAnchorTool,
boundaryTool, removeButton
]
});</code></pre>
<p>Remember, it is necessary to create a new set of tools for every new tools view object we create; tools
are automatically reassigned to the last tools view that uses them.</p>
<h3 id="add-to-link-view">Add to Link View</h3>
<p>Finally, we need to add our tools view to a link view.
The <a href="/docs/jointjs#dia.LinkView" target="_blank"><code>joint.dia.LinkView</code></a> class comes
with a suite of tools-related methods:</p>
<ul>
<li><a href="/docs/jointjs#dia.LinkView.prototype.addTools" target="_blank"><code>linkView.addTools(toolsView)</code></a>
- adds given <code>toolsView</code> onto the link view.
The tools are visible by default.</li>
<li><a href="/docs/jointjs#dia.LinkView.prototype.showTools" target="_blank"><code>linkView.showTools()</code></a>
- shows tools on the link view.</li>
<li><a href="/docs/jointjs#dia.LinkView.prototype.hideTools" target="_blank"><code>linkView.hideTools()</code></a>
- hides tools on the link view.</li>
<li><a href="/docs/jointjs#dia.LinkView.prototype.removeTools" target="_blank"><code>linkView.removeTools()</code></a>
- removes tools from the link view.</li>
</ul>
<p>We can thus show all of our tools in one place:</p>
<p>Try playing around with the user controls.
Note that redundant vertices are will be removed whenever they appear; new vertices can be added by
clicking anywhere on the link.
Double-clicking a vertex removes it.
The disconnected handles are link anchors; when moved, they stay within the bounds of their respective
end elements.</p>
<div class="paper" id="paper-link-tools-all"></div>
<pre><code>var linkView = link.findView(paper);
linkView.addTools(toolsView);</code></pre>
<p>JointJS source code: <a href="js/link-tools-all.js" target="_blank">link-tools-all.js</a></p>
<p>Remember, it is necessary to create a new tools view object for every link view; tools view objects are
automatically reassigned to the last link view that uses them.</p>
<h3 id="interaction">Interaction</h3>
<p>You can easily toggle link tools using the
<code>'link:mouseenter'</code>/<code>'link:mouseleave'</code> Paper events:</p>
<div class="paper" id="paper-link-tools-interaction"></div>
<pre><code>paper.on('link:mouseenter', function(linkView) {
linkView.addTools(toolsView);
});
paper.on('link:mouseleave', function(linkView) {
linkView.removeTools();
});</code></pre>
<p>JointJS source code: <a href="js/link-tools-interaction.js" target="_blank">link-tools-interaction.js</a></p>
<p>More complex interaction scenarios might require showing, hiding or removing all tools at once.
You can find relevant functions in the Paper class:</p>
<ul>
<li><a href="/docs/jointjs#dia.Paper.prototype.showTools" target="_blank"><code>paper.showTools()</code></a>
- shows tools on all link and element views.</li>
<li><a href="/docs/jointjs#dia.Paper.prototype.hideTools" target="_blank"><code>paper.hideTools()</code></a>
- hides tools on all link and element views.</li>
<li><a href="/docs/jointjs#dia.Paper.prototype.removeTools" target="_blank"><code>paper.removeTools()</code></a>
- removes tools from all link and element views.</li>
</ul>
<p>These functions can also help to make anchor handles (which usually lie outside the path but inside an
element) more accessible to users - by removing link tools only if the mouse pointer enters a blank area
of the paper:</p>
<pre><code>paper.on('link:mouseenter', function(linkView) {
linkView.addTools(toolsView);
});
paper.on('blank:mouseover', function() {
paper.removeTools();
});</code></pre>
<p>Note that our example toggles visibility of link tools by using the
<code>addTools()</code>/<code>removeTools()</code> functions, and not
<code>showTools()</code>/<code>hideTools()</code> which we have seen in the
<a href="element-tools.html#interaction">element tools tutorial</a>.
This is necessary because the tools view in our tutorial includes the <code>SourceArrowhead</code> and
<code>TargetArrowhead</code> tools, which may cause the link tools view to not be hidden as expected
when the link is reconnected to a topic.
Tools views without those two tools may use the <code>showTools()</code>/<code>hideTools()</code>
approach illustrated in the <a href="element-tools.html#interaction">element tools tutorial</a> without
issue.</p>
<h3 id="custom-button">Custom Buttons</h3>
<p>It is possible to create <a href="/docs/jointjs#linkTools.Button" target="_blank">custom buttons</a> to
complement the pre-made <a href="/docs/jointjs#linkTools.Remove" target="_blank"><code>Remove</code></a>
button tool;
JointJS exposes the
<a href="/docs/jointjs#linkTools.Button" target="_blank"><code>joint.linkTools.Button</code></a> class
for you to extend.
The markup of the new button can be sent as <code>options.markup</code>, while the behavior of the
button on pointerdown interaction is determined by the callback function provided in
<code>options.action</code>.</p>
<div class="paper" id="paper-link-tools-custom-button"></div>
<p>You can add the extended button to the <code>joint.linkTools</code> namespace and then just use that
class in the code:</p>
<pre><code>joint.linkTools.InfoButton = joint.linkTools.Button.extend({
name: 'info-button',
options: {
markup: [{
tagName: 'circle',
selector: 'button',
attributes: {
'r': 7,
'fill': '#001DFF',
'cursor': 'pointer'
}
}, {
tagName: 'path',
selector: 'icon',
attributes: {
'd': 'M -2 4 2 4 M 0 3 0 0 M -2 -1 1 -1 M -1 -4 1 -4',
'fill': 'none',
'stroke': '#FFFFFF',
'stroke-width': 2,
'pointer-events': 'none'
}
}],
distance: 60,
offset: 0,
action: function(evt) {
alert('View id: ' + this.id + '\n' + 'Model id: ' + this.model.id);
}
}
});
var infoButton = new joint.linkTools.InfoButton();
var toolsView = new joint.dia.ToolsView({
tools: [infoButton]
});
var linkView = link.findView(paper);
linkView.addTools(toolsView);</code></pre>
<p>JointJS source code: <a href="js/link-tools-custom-button.js" target="_blank">link-tools-custom-button.js</a></p>
<p>A single-use custom button can also be created by direct reference to the
<a href="/docs/jointjs#linkTools.Button" target="_blank"><code>Button</code></a> class, without making
an entry in the <code>joint.linkTools</code> namespace:</p>
<pre><code>var infoButton = new joint.linkTools.Button({
markup: [{
tagName: 'circle',
selector: 'button',
attributes: {
'r': 7,
'fill': '#001DFF',
'cursor': 'pointer'
}
}, {
tagName: 'path',
selector: 'icon',
attributes: {
'd': 'M -2 4 2 4 M 0 3 0 0 M -2 -1 1 -1 M -1 -4 1 -4',
'fill': 'none',
'stroke': '#FFFFFF',
'stroke-width': 2,
'pointer-events': 'none'
}
}],
distance: 60,
offset: 0,
action: function(evt) {
alert('View id: ' + this.id + '\n' + 'Model id: ' + this.model.id);
}
});
var toolsView = new joint.dia.ToolsView({
tools: [infoButton]
});
var linkView = link.findView(paper);
linkView.addTools(toolsView);</code></pre>
<p>This concludes the intermediate section of the JointJS tutorial.
Congratulations!
You should now be able to create serializable diagrams with custom elements and links that make use of
JointJS attributes and can react to user interaction.</p>
<p><a href="advanced.html">The next step is to head over to the advanced section of the tutorial.</a></p>
</div><!--end tutorial-->
<script src="../node_modules/prismjs/prism.js"></script>
<script src="js/link-tools-example.js"></script>
<script src="js/link-tools-all.js"></script>
<script src="js/link-tools-interaction.js"></script>
<script src="js/link-tools-custom-button.js"></script>
</body>
</html>