UNPKG

29.8 kBHTMLView Raw
1<!DOCTYPE html>
2<html lang="en">
3 <head>
4<meta charset="utf-8"/>
5<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, viewport-fit=cover"/>
6
7<link rel="stylesheet" href="../assets/css/style.css"/>
8<!-- Copyright 1998-2021 by Northwoods Software Corporation. --> <title> GoJS Link Labels -- Northwoods Software </title>
9 <link rel="stylesheet" href="../assets/css/prism.css" />
10 </head>
11 <script>
12
13 window.diagrams = [];
14 window.goCode = function(pre, w, h, parentid, animation) {
15 window.diagrams.push([pre, w, h, parentid, animation]);
16 }
17 </script>
18 <body>
19 <nav id="navTop" class="w-full z-30 top-0 text-white bg-nwoods-primary">
20 <div class="w-full container max-w-screen-lg mx-auto flex flex-wrap sm:flex-nowrap items-center justify-between mt-0 py-2">
21 <div class="md:pl-4">
22 <a class="text-white hover:text-white no-underline hover:no-underline
23 font-bold text-2xl lg:text-4xl rounded-lg hover:bg-nwoods-secondary " href="../">
24 <h1 class="mb-0 p-1 ">GoJS</h1>
25 </a>
26 </div>
27 <button id="topnavButton" class="rounded-lg sm:hidden focus:outline-none focus:ring" aria-label="Navigation">
28 <svg fill="currentColor" viewBox="0 0 20 20" class="w-6 h-6">
29 <path id="topnavOpen" fill-rule="evenodd" d="M3 5a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM3 10a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM9 15a1 1 0 011-1h6a1 1 0 110 2h-6a1 1 0 01-1-1z" clip-rule="evenodd"></path>
30 <path id="topnavClosed" class="hidden" fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"></path>
31 </svg>
32 </button>
33 <div id="topnavList" class="hidden sm:block items-center w-auto mt-0 text-white p-0 z-20">
34 <ul class="list-reset list-none font-semibold flex justify-end flex-wrap sm:flex-nowrap items-center px-0 pb-0">
35 <li class="p-1 sm:p-0"><a class="topnav-link" href="../learn/">Learn</a></li>
36 <li class="p-1 sm:p-0"><a class="topnav-link" href="../samples/">Samples</a></li>
37 <li class="p-1 sm:p-0"><a class="topnav-link" href="../intro/">Intro</a></li>
38 <li class="p-1 sm:p-0"><a class="topnav-link" href="../api/">API</a></li>
39 <li class="p-1 sm:p-0"><a class="topnav-link" href="https://www.nwoods.com/products/register.html">Register</a></li>
40 <li class="p-1 sm:p-0"><a class="topnav-link" href="../download.html">Download</a></li>
41 <li class="p-1 sm:p-0"><a class="topnav-link" href="https://forum.nwoods.com/c/gojs/11">Forum</a></li>
42 <li class="p-1 sm:p-0"><a class="topnav-link" href="https://www.nwoods.com/contact.html"
43 target="_blank" rel="noopener" onclick="getOutboundLink('https://www.nwoods.com/contact.html', 'contact');">Contact</a></li>
44 <li class="p-1 sm:p-0"><a class="topnav-link" href="https://www.nwoods.com/sales/index.html"
45 target="_blank" rel="noopener" onclick="getOutboundLink('https://www.nwoods.com/sales/index.html', 'buy');">Buy</a></li>
46 </ul>
47 </div>
48 </div>
49 <hr class="border-b border-gray-600 opacity-50 my-0 py-0" />
50 </nav>
51
52 <div class="md:flex flex-col md:flex-row md:min-h-screen w-full max-w-screen-xl mx-auto">
53
54 <div id="navSide" class="flex flex-col w-full md:w-40 lg:w-48 text-gray-700 bg-white flex-shrink-0">
55 <div class="flex-shrink-0 px-8 py-4">
56 <button id="navButton" class="rounded-lg md:hidden focus:outline-none focus:ring" aria-label="Navigation">
57 <svg fill="currentColor" viewBox="0 0 20 20" class="w-6 h-6">
58 <path id="navOpen" fill-rule="evenodd" d="M3 5a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM3 10a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM9 15a1 1 0 011-1h6a1 1 0 110 2h-6a1 1 0 01-1-1z" clip-rule="evenodd"></path>
59 <path id="navClosed" class="hidden" fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"></path>
60 </svg>
61 </button>
62 </div>
63 <nav id="navList" class="min-h-screen hidden md:block sidebar-nav flex-grow px-1 lg:px-4 pb-4 md:pb-0 md:overflow-y-auto break-words">
64 <a href="index.html">Basics</a>
65 <a href="buildingObjects.html">Building Parts</a>
66 <a href="usingModels.html">Using Models</a>
67 <a href="dataBinding.html">Data Binding</a>
68 <a href="react.html">GoJS with React</a>
69 <a href="angular.html">GoJS with Angular</a>
70 <a href="textBlocks.html">TextBlocks</a>
71 <a href="shapes.html">Shapes</a>
72 <a href="pictures.html">Pictures</a>
73 <a href="panels.html">Panels</a>
74 <a href="tablePanels.html">Table Panels</a>
75 <a href="brush.html">Brushes</a>
76 <a href="sizing.html">Sizing Objects</a>
77 <a href="itemArrays.html">Item Arrays</a>
78 <a href="changedEvents.html">Changed Events</a>
79 <a href="transactions.html">Transactions</a>
80 <a href="viewport.html">Coordinates</a>
81 <a href="initialView.html">Initial View</a>
82 <a href="collections.html">Collections</a>
83 <a href="links.html">Links</a>
84 <a href="linkLabels.html">Link Labels</a>
85 <a href="connectionPoints.html">Link Points</a>
86 <a href="ports.html">Ports</a>
87 <a href="nodes.html">Nodes</a>
88 <a href="debugging.html">Debugging</a>
89 <a href="layouts.html">Layouts</a>
90 <a href="trees.html">Trees</a>
91 <a href="subtrees.html">SubTrees</a>
92 <a href="groups.html">Groups</a>
93 <a href="subgraphs.html">SubGraphs</a>
94 <a href="sizedGroups.html">Sized Groups</a>
95 <a href="selection.html">Selection</a>
96 <a href="highlighting.html">Highlighting</a>
97 <a href="animation.html">Animation</a>
98 <a href="toolTips.html">ToolTips</a>
99 <a href="contextmenus.html">Context Menus</a>
100 <a href="events.html">Diagram Events</a>
101 <a href="tools.html">Tools</a>
102 <a href="commands.html">Commands</a>
103 <a href="permissions.html">Permissions</a>
104 <a href="validation.html">Validation</a>
105 <a href="HTMLInteraction.html">HTML Interaction</a>
106 <a href="layers.html">Layers &amp; Z-ordering</a>
107 <a href="palette.html">Palette</a>
108 <a href="overview.html">Overview</a>
109 <a href="resizing.html">Resizing Diagrams</a>
110 <a href="replacingDeleting.html">Replacing and Deleting</a>
111 <a href="buttons.html">Buttons</a>
112 <a href="templateMaps.html">Template Maps</a>
113 <a href="legends.html">Legends and Titles</a>
114 <a href="extensions.html">Extensions</a>
115 <a href="geometry.html">Geometry Strings</a>
116 <a href="grids.html">Grid Patterns</a>
117 <a href="graduatedPanels.html">Graduated Panels</a>
118 <a href="makingImages.html">Diagram Images</a>
119 <a href="makingSVG.html">Diagram SVG</a>
120 <a href="printing.html">Printing</a>
121 <a href="serverSideImages.html">Server-side Images</a>
122 <a href="nodeScript.html">GoJS in Node.js</a>
123 <a href="testing.html">Testing</a>
124 <a href="storage.html">Storage</a>
125 <a href="performance.html">Performance</a>
126 <a href="source.html">Building from Source</a>
127 <a href="platforms.html">Platforms</a>
128 <a href="deployment.html">Deployment</a>
129 </nav>
130 </div>
131 <div class="pt-4 px-2 md:px-0 lg:px-4 pb-16 w-full overflow-hidden">
132
133<h1>Labels on Links</h1>
134<p>
135It is common to add annotations or decorations on a link, particularly text.
136</p>
137
138<h2 id="SimpleLinkLabels">Simple Link labels</h2>
139<p>
140By default if you add a <a>GraphObject</a> to a <a>Link</a>, it will be positioned at the middle of the link.
141In this example, we just add a <a>TextBlock</a> to the link and bind its <a>TextBlock.text</a> property
142to the link data's "text" property.
143</p>
144<pre class="lang-js" id="simple"><code>
145 diagram.nodeTemplate =
146 $(go.Node, "Auto",
147 new go.Binding("location", "loc", go.Point.parse),
148 $(go.Shape, "RoundedRectangle", { fill: "lightgray" }),
149 $(go.TextBlock, { margin: 5 },
150 new go.Binding("text", "key"))
151 );
152
153 diagram.linkTemplate =
154 $(go.Link,
155 $(go.Shape), // this is the link shape (the line)
156 $(go.Shape, { toArrow: "Standard" }), // this is an arrowhead
157 $(go.TextBlock, // this is a Link label
158 new go.Binding("text", "text"))
159 );
160
161 var nodeDataArray = [
162 { key: "Alpha", loc: "0 0" },
163 { key: "Beta", loc: "200 50" }
164 ];
165 var linkDataArray = [
166 { from: "Alpha", to: "Beta", text: "a label" }
167 ];
168 diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
169</code></pre>
170<script>goCode("simple", 600, 100)</script>
171<p>
172Note that clicking on the text label results in selection of the whole Link.
173</p>
174
175<p>
176Although it is commonplace to use a <a>TextBlock</a> as the link label, it can be any <a>GraphObject</a>
177such as a <a>Shape</a> or an arbitrarily complex <a>Panel</a>. Here is a simple Panel label:
178</p>
179<pre class="lang-js" id="labels"><code>
180 diagram.nodeTemplate =
181 $(go.Node, "Auto",
182 new go.Binding("location", "loc", go.Point.parse),
183 $(go.Shape, "RoundedRectangle", { fill: "lightgray" }),
184 $(go.TextBlock, { margin: 5 },
185 new go.Binding("text", "key"))
186 );
187
188 diagram.linkTemplate =
189 $(go.Link,
190 $(go.Shape),
191 $(go.Shape, { toArrow: "Standard" }),
192 $(go.Panel, "Auto", // this whole Panel is a link label
193 $(go.Shape, "TenPointedStar", { fill: "yellow", stroke: "gray" }),
194 $(go.TextBlock, { margin: 3 },
195 new go.Binding("text", "text"))
196 )
197 );
198
199 var nodeDataArray = [
200 { key: "Alpha", loc: "0 0" },
201 { key: "Beta", loc: "200 50" }
202 ];
203 var linkDataArray = [
204 { from: "Alpha", to: "Beta", text: "hello!" } // added information for link label
205 ];
206 diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
207</code></pre>
208<script>goCode("labels", 600, 100)</script>
209
210<p>
211This also works if the link is orthogonally routed or bezier-curved.
212</p>
213<pre class="lang-js" id="simpleOrtho"><code>
214 diagram.nodeTemplate =
215 $(go.Node, "Auto",
216 new go.Binding("location", "loc", go.Point.parse),
217 $(go.Shape, "RoundedRectangle", { fill: "lightgray" }),
218 $(go.TextBlock, { margin: 5 },
219 new go.Binding("text", "key"))
220 );
221
222 diagram.linkTemplate =
223 $(go.Link,
224 { routing: go.Link.Orthogonal },
225 $(go.Shape),
226 $(go.Shape, { toArrow: "Standard" }),
227 $(go.TextBlock, { textAlign: "center" }, // centered multi-line text
228 new go.Binding("text", "text"))
229 );
230
231 var nodeDataArray = [
232 { key: "Alpha", loc: "0 0" },
233 { key: "Beta", loc: "200 50" }
234 ];
235 var linkDataArray = [
236 { from: "Alpha", to: "Beta", text: "a label\non an\northo link" }
237 ];
238 diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
239</code></pre>
240<script>goCode("simpleOrtho", 600, 100)</script>
241
242<p>
243Although positioning the label at the middle of the link is the default behavior,
244you can set <a>GraphObject</a> properties that start with "segment" to specify exactly
245where and how to arrange the object along the route of the link.
246</p>
247
248<h2 id="LinkLabelSegmentIndexAndSegmentFraction">Link label segmentIndex and segmentFraction</h2>
249<p>
250Set the <a>GraphObject.segmentIndex</a> property in order to specify which segment of the link route
251the object should be on.
252Set the <a>GraphObject.segmentFraction</a> property to control how far the object should be, as a fraction
253from the start of the segment (zero) to the end of the segment (one).
254</p>
255<p>
256When setting the <a>GraphObject.segmentIndex</a> property to NaN,
257the fraction will be calculated along the entire link route instead of a particular segment.
258</p>
259<p>
260In the case of a link that comes from a node with no <a>GraphObject.fromSpot</a> (i.e. <a>Spot,None</a>)
261and goes to a node with no <a>GraphObject.toSpot</a>, there may be only one segment in the link, segment number zero.
262</p>
263<pre class="lang-js" id="fraction"><code>
264 diagram.nodeTemplate =
265 $(go.Node, "Auto",
266 new go.Binding("location", "loc", go.Point.parse),
267 $(go.Shape, "RoundedRectangle", { fill: "lightgray" }),
268 $(go.TextBlock, { margin: 5 },
269 new go.Binding("text", "key"))
270 );
271
272 diagram.linkTemplate =
273 $(go.Link,
274 $(go.Shape),
275 $(go.Shape, { toArrow: "Standard" }),
276 $(go.TextBlock, "from", { segmentIndex: 0, segmentFraction: 0.2 }),
277 $(go.TextBlock, "mid", { segmentIndex: 0, segmentFraction: 0.5 }),
278 $(go.TextBlock, "to", { segmentIndex: 0, segmentFraction: 0.8 })
279 );
280
281 var nodeDataArray = [
282 { key: "Alpha", loc: "0 0" },
283 { key: "Beta", loc: "200 50" }
284 ];
285 var linkDataArray = [
286 { from: "Alpha", to: "Beta" }
287 ];
288 diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
289</code></pre>
290<script>goCode("fraction", 600, 100)</script>
291
292<p>
293In the case of a link that has many segments in it, you will want to specify different segment numbers.
294Orthogonal links, for example, typically have 6 points in the route, which means five segments numbered from 0 to 4.
295</p>
296<pre class="lang-js" id="fractionOrtho"><code>
297 diagram.nodeTemplate =
298 $(go.Node, "Auto",
299 new go.Binding("location", "loc", go.Point.parse),
300 $(go.Shape, "RoundedRectangle", { fill: "lightgray" }),
301 $(go.TextBlock, { margin: 5 },
302 new go.Binding("text", "key"))
303 );
304
305 diagram.linkTemplate =
306 $(go.Link,
307 { routing: go.Link.Orthogonal },
308 $(go.Shape),
309 $(go.Shape, { toArrow: "Standard" }),
310 $(go.TextBlock, "from", { segmentIndex: 1, segmentFraction: 0.5 }),
311 $(go.TextBlock, "mid", { segmentIndex: 2, segmentFraction: 0.5 }),
312 $(go.TextBlock, "to", { segmentIndex: 3, segmentFraction: 0.5 })
313 );
314
315 var nodeDataArray = [
316 { key: "Alpha", loc: "0 0" },
317 { key: "Beta", loc: "200 50" }
318 ];
319 var linkDataArray = [
320 { from: "Alpha", to: "Beta" }
321 ];
322 diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
323</code></pre>
324<script>goCode("fractionOrtho", 600, 100)</script>
325
326<p>
327However, you can also count segments backwards from the "to" end of the link.
328-1 is the last segment, -2 is the next to last, etc.
329When you use a negative segment index, the segment fraction goes from 0 closest to the "to" end
330to 1 for the end of that segment that is farthest back along the route from the "to" end.
331Thus a segmentIndex of -1 with a segmentFraction of 0 is the very end point of the link route.
332A segmentIndex of -1 with a segmentFraction of 1 is the same point as segmentIndex -2 and segmentFraction 0.
333</p>
334<p>
335For labels that belong near the "to" end of a link, you will normally use negative values for <a>GraphObject.segmentIndex</a>.
336This convention works better when the number of segments in a link is unknown or may vary.
337</p>
338
339<p>
340 Lastly, one can specify a segmentIndex of NaN to have the fraction calculated along the entire link route instead of just a particular segment.
341</p>
342<pre class="lang-js" id="fractionNoIndex"><code>
343 diagram.nodeTemplate =
344 $(go.Node, "Auto",
345 new go.Binding("location", "loc", go.Point.parse),
346 $(go.Shape, "RoundedRectangle", { fill: "lightgray" }),
347 $(go.TextBlock, { margin: 5 },
348 new go.Binding("text", "key"))
349 );
350
351 diagram.linkTemplate =
352 $(go.Link,
353 { curve: go.Link.Bezier },
354 $(go.Shape),
355 $(go.Shape, { toArrow: "Standard" }),
356 $(go.TextBlock, "1/3", { segmentIndex: NaN, segmentFraction: 0.33 }), // label at 1/3 of link length
357 $(go.TextBlock, "2/3", { segmentIndex: NaN, segmentFraction: 0.67 }) // label at 2/3 of link length
358 );
359
360 var nodeDataArray = [
361 { key: "Alpha", loc: "0 0" },
362 { key: "Beta", loc: "200 50" }
363 ];
364 var linkDataArray = [
365 { from: "Alpha", to: "Beta" }
366 ];
367 diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
368</code></pre>
369<script>goCode("fractionNoIndex", 600, 100)</script>
370
371<h2 id="LinkLabelSegmentOffsetAndAlignmentFocus">Link label segmentOffset and alignmentFocus</h2>
372<p>
373There are two ways of making small adjustments to the position of a label object given a particular point on a link segment
374specified by the segment index and fractional distance.
375</p>
376<p>
377The <a>GraphObject.segmentOffset</a> property controls where to position the object relative to the point
378on a link segment determined by the <a>GraphObject.segmentIndex</a> and <a>GraphObject.segmentFraction</a> properties.
379The offset is not a simple offset of the point -- it is rotated according to the angle of that link segment.
380A positive value for the Y offset moves the label element towards the right side of the
381link, as seen going in the direction of the link. Naturally a negative value for the Y offset moves it towards
382the left side.
383</p>
384<pre class="lang-js" id="offset"><code>
385 diagram.nodeTemplate =
386 $(go.Node, "Auto",
387 new go.Binding("location", "loc", go.Point.parse),
388 $(go.Shape, "RoundedRectangle", { fill: "lightgray" }),
389 $(go.TextBlock, { margin: 5 },
390 new go.Binding("text", "key"))
391 );
392
393 diagram.linkTemplate =
394 $(go.Link,
395 $(go.Shape),
396 $(go.Shape, { toArrow: "Standard" }),
397 $(go.TextBlock, "left", { segmentOffset: new go.Point(0, -10) }),
398 $(go.TextBlock, "right", { segmentOffset: new go.Point(0, 10) })
399 );
400
401 var nodeDataArray = [
402 { key: "Alpha", loc: "0 0" },
403 { key: "Beta", loc: "200 50" }
404 ];
405 var linkDataArray = [
406 { from: "Alpha", to: "Beta" }
407 ];
408 diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
409</code></pre>
410<script>goCode("offset", 600, 200)</script>
411<p>
412If you drag one node around in a circle around the other one,
413you will see how the "left" and "right" labels are positioned.
414</p>
415
416<p>
417Another way to change the effective offset is by changing the spot in the object that is being
418positioned relative to the link segment point.
419You can do that by setting the <a>GraphObject.alignmentFocus</a>, which as you have seen above defaults to <a>Spot.Center</a>.
420(<a>GraphObject.alignmentFocus</a> is also used by other <a>Panel</a> types, which is why its name does not start with "segment".)
421</p>
422<pre class="lang-js" id="alignmentFocus"><code>
423 diagram.nodeTemplate =
424 $(go.Node, "Auto",
425 new go.Binding("location", "loc", go.Point.parse),
426 $(go.Shape, "RoundedRectangle", { fill: "lightgray" }),
427 $(go.TextBlock, { margin: 5 },
428 new go.Binding("text", "key"))
429 );
430
431 diagram.linkTemplate =
432 $(go.Link,
433 $(go.Shape),
434 $(go.Shape, { toArrow: "Standard" }),
435 $(go.TextBlock, "left", { alignmentFocus: new go.Spot(1, 0.5, 3, 0) }),
436 $(go.TextBlock, "right", { alignmentFocus: new go.Spot(0, 0.5, -3, 0) })
437 );
438
439 var nodeDataArray = [
440 { key: "Alpha", loc: "0 0" },
441 { key: "Beta", loc: "200 50" }
442 ];
443 var linkDataArray = [
444 { from: "Alpha", to: "Beta" }
445 ];
446 diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
447</code></pre>
448<script>goCode("alignmentFocus", 600, 200)</script>
449<p>
450Yet you may instead want to control the angle of the individual labels based on the angle of the link segment.
451</p>
452
453<h2 id="LinkLabelSegmentOrientation">Link label segmentOrientation</h2>
454<p>
455The <a>GraphObject.segmentOrientation</a> property controls the angle of the label object relative
456to the angle of the link segment.
457There are several possible values that you can use.
458The default orientation is <a>Link,None</a>, meaning no rotation at all.
459<a>Link,OrientAlong</a> is commonly used to have the object always rotated at the same angle as the link segment.
460<a>Link,OrientUpright</a> is like "OrientAlong", but is often used when there is text in the label, to make it easier to read.
461</p>
462<pre class="lang-js" id="orient"><code>
463 diagram.nodeTemplate =
464 $(go.Node, "Auto",
465 new go.Binding("location", "loc", go.Point.parse),
466 $(go.Shape, "RoundedRectangle", { fill: "lightgray" }),
467 $(go.TextBlock, { margin: 5 },
468 new go.Binding("text", "key"))
469 );
470
471 diagram.linkTemplate =
472 $(go.Link,
473 $(go.Shape),
474 $(go.Shape, { toArrow: "Standard" }),
475 $(go.TextBlock, "left",
476 { segmentOffset: new go.Point(0, -10),
477 segmentOrientation: go.Link.OrientUpright }),
478 $(go.TextBlock, "middle",
479 { segmentOffset: new go.Point(0, 0),
480 segmentOrientation: go.Link.OrientUpright }),
481 $(go.TextBlock, "right",
482 { segmentOffset: new go.Point(0, 10),
483 segmentOrientation: go.Link.OrientUpright })
484 );
485
486 var nodeDataArray = [
487 { key: "Alpha", loc: "0 0" },
488 { key: "Beta", loc: "200 50" }
489 ];
490 var linkDataArray = [
491 { from: "Alpha", to: "Beta" }
492 ];
493 diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
494</code></pre>
495<script>goCode("orient", 600, 200)</script>
496<p>
497Now if you move a node around you will always be able to read the label texts,
498and yet each label stays on its intended side of the link, as seen going in the direction of the link.
499</p>
500<p>
501This points out a difference between a segmentIndex/segmentFraction pair of 0/1 and 1/0.
502Although they both refer to the same point, the angle associated with the first pair is the angle of the first segment (segment 0),
503whereas the angle associated with the second pair is the angle of the second segment.
504</p>
505
506<h2 id="LinkLabelsNearEnds">Link labels near the ends</h2>
507<p>
508For labels that are near either end of a link, it may be convenient to set the <a>GraphObject.segmentOffset</a> to
509Point(NaN, NaN). This causes the offset to be half the width and half the height of the label object.
510</p>
511<pre class="lang-js" id="nearEnds"><code>
512 diagram.nodeTemplate =
513 $(go.Node, "Auto",
514 new go.Binding("location", "loc", go.Point.parse),
515 $(go.Shape, "RoundedRectangle", { fill: "lightgray" }),
516 $(go.TextBlock, { margin: 5 },
517 new go.Binding("text", "key"))
518 );
519
520 diagram.linkTemplate =
521 $(go.Link,
522 $(go.Shape),
523 $(go.Shape, { toArrow: "Standard" }),
524 $(go.TextBlock, "from",
525 { segmentIndex: 0, segmentOffset: new go.Point(NaN, NaN),
526 segmentOrientation: go.Link.OrientUpright }),
527 $(go.TextBlock, "to",
528 { segmentIndex: -1, segmentOffset: new go.Point(NaN, NaN),
529 segmentOrientation: go.Link.OrientUpright })
530 );
531
532 var nodeDataArray = [
533 { key: "Alpha", loc: "0 0" },
534 { key: "Beta", loc: "200 50" }
535 ];
536 var linkDataArray = [
537 { from: "Alpha", to: "Beta" }
538 ];
539 diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
540</code></pre>
541<script>goCode("nearEnds", 600, 200)</script>
542
543<h2 id="Arrowheads">Arrowheads</h2>
544<p>
545Now that you know more about the <a>GraphObject</a> "segment..." properties for controlling the position and angle of objects in a <a>Link</a>,
546it is easy to explain how arrowheads are defined. Arrowheads are just labels: <a>Shape</a>s that are initialized in a convenient manner.
547</p>
548<p>
549You can see a copy of all of the built-in arrowhead definitions in this file: <a href="../extensions/Arrowheads.js">Arrowheads.js</a>.
550</p>
551<p>
552Here are the equivalent settings for initializing an arrowhead <a>Shape</a> by setting <a>Shape.toArrow</a> to "Standard".
553</p>
554
555<pre class="lang-js" id="arrowheads"><code>
556 diagram.nodeTemplate =
557 $(go.Node, "Auto",
558 new go.Binding("location", "loc", go.Point.parse),
559 $(go.Shape, "RoundedRectangle", { fill: "lightgray" }),
560 $(go.TextBlock, { margin: 5 },
561 new go.Binding("text", "key"))
562 );
563
564 diagram.linkTemplate =
565 $(go.Link,
566 $(go.Shape),
567 $(go.Shape,
568 // the following are the same as { toArrow: "Standard" }:
569 { segmentIndex: -1,
570 segmentOrientation: go.Link.OrientAlong,
571 alignmentFocus: go.Spot.Right,
572 geometry: go.Geometry.parse("F1 m0 0 l8 4 -8 4 2 -4 z") })
573 );
574
575 var nodeDataArray = [
576 { key: "Alpha", loc: "0 0" },
577 { key: "Beta", loc: "200 50" }
578 ];
579 var linkDataArray = [
580 { from: "Alpha", to: "Beta" }
581 ];
582 diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
583</code></pre>
584<script>goCode("arrowheads", 600, 200)</script>
585
586 </div>
587 </div>
588
589 <div class="bg-nwoods-primary">
590 <section class="max-w-screen-lg text-white container mx-auto py-2 px-12">
591 <p id="version" class="leading-none mb-2 my-4">GoJS</p>
592 </section>
593 </div><footer class="bg-nwoods-primary text-white">
594 <div class="container max-w-screen-lg mx-auto px-8">
595 <div class="w-full py-6">
596
597 <div class="max-w-screen-lg xl:max-w-screen-xl mx-auto px-4 sm:px-6 md:px-8">
598 <ul class="text-sm font-medium pb-14 sm:pb-20 grid grid-cols-1 sm:grid-cols-3 gap-y-10">
599 <li class="list-none row-span-2">
600 <h2 class="text-base font-semibold tracking-wide">GoJS</h2>
601 <ul class="list-none space-y-4 md:space-y-1 px-0">
602 <li>
603 <a href="../samples/index.html">Samples</a>
604 </li>
605 <li>
606 <a href="../learn/index.html">Learn</a>
607 </li>
608 <li>
609 <a href="../intro/index.html">Intro</a>
610 </li>
611 <li>
612 <a href="../api/index.html">API</a>
613 </li>
614 <li>
615 <a href="../changelog.html">Changelog</a>
616 </li>
617 <li>
618 <a href="https://github.com/NorthwoodsSoftware/GoJS">GitHub</a>
619 </li>
620 </ul>
621 </li>
622 <li class="list-none row-span-2">
623 <h2 class="text-base font-semibold tracking-wide">Support</h2>
624 <ul class="list-none space-y-4 md:space-y-1 px-0">
625 <li>
626 <a href="https://www.nwoods.com/contact.html"
627 target="_blank" rel="noopener" onclick="getOutboundLink('https://www.nwoods.com/contact.html', 'contact');">Contact</a>
628 </li>
629 <li>
630 <a href="https://forum.nwoods.com/c/gojs">Forum</a>
631 </li>
632 <li>
633 <a href="https://www.nwoods.com/app/activate.aspx?sku=gojs">Activate</a>
634 </li>
635 <li>
636 <a href="https://www.nwoods.com/sales/index.html"
637 target="_blank" rel="noopener" onclick="getOutboundLink('https://www.nwoods.com/sales/index.html', 'buy');">Buy</a>
638 </li>
639 <li>
640 <a href="https://www.youtube.com/channel/UC9We8EoX596-6XFjJDtZIDg">Videos</a>
641 </li>
642 </ul>
643 </li>
644 <li class="list-none row-span-2">
645 <h2 class="text-base font-semibold tracking-wide">Company</h2>
646 <ul class="list-none space-y-4 md:space-y-1 px-0">
647 <li>
648 <a href="https://www.nwoods.com">Northwoods</a>
649 </li>
650 <li>
651 <a href="https://www.nwoods.com/about.html">About Us</a>
652 </li>
653 <li>
654 <a href="https://www.nwoods.com/contact.html">Contact Us</a>
655 </li>
656 <li>
657 <a href="https://twitter.com/northwoodsgo">Twitter</a>
658 </li>
659
660 </ul>
661 </li>
662 </ul>
663
664
665 <p class="text-sm text-gray-100 md:mb-6">
666 Copyright 1998-2021 <a class="text-white" href="https://www.nwoods.com">Northwoods Software</a>
667 </p>
668 </div>
669 </div>
670</footer> </body>
671
672<script async src="https://www.googletagmanager.com/gtag/js?id=UA-1506307-5"></script>
673<script>
674 window.dataLayer = window.dataLayer || [];
675 function gtag(){dataLayer.push(arguments);}
676 gtag('js', new Date()); gtag('config', 'UA-1506307-5');
677 var getOutboundLink = function(url, label) {
678 gtag('event', 'click', {
679 'event_category': 'outbound',
680 'event_label': label,
681 'transport_type': 'beacon'
682 });
683 }
684
685 // topnav
686 var topButton = document.getElementById("topnavButton");
687 var topnavList = document.getElementById("topnavList");
688 topButton.addEventListener("click", function() {
689 this.classList.toggle("active");
690 topnavList.classList.toggle("hidden");
691 document.getElementById("topnavOpen").classList.toggle("hidden");
692 document.getElementById("topnavClosed").classList.toggle("hidden");
693 });
694</script>
695 <script src="../assets/js/prism.js"></script>
696 <script src="../release/go.js"></script>
697<script src="../extensions/Figures.js"></script> <script src="../assets/js/goDoc.js"></script>
698 <script>
699 document.addEventListener("DOMContentLoaded", function() {
700 if (window.go) document.getElementById('version').textContent = "GoJS version " + go.version;
701 if (window.goDoc) window.goDoc();
702 var d = window.diagrams;
703 for (var i = 0; i < d.length; i++) {
704 var dargs = d[i];
705 goCodeExecute(dargs[0], dargs[1], dargs[2], dargs[3], dargs[4]);
706 }
707 if (window.extra) window.extra();
708 });
709 </script>
710</html>