UNPKG

37.7 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<meta name="description" content="Tutorial for getting started with GoJS."/>
7<link rel="stylesheet" href="../assets/css/style.css"/>
8<!-- Copyright 1998-2021 by Northwoods Software Corporation. --> <title> Get Started with GoJS </title>
9 <link rel="stylesheet" href="../assets/css/prism.css" />
10
11 <script src="../release/go.js"></script>
12 </head>
13 <body>
14 <nav id="navTop" class="w-full z-30 top-0 text-white bg-nwoods-primary">
15 <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">
16 <div class="md:pl-4">
17 <a class="text-white hover:text-white no-underline hover:no-underline
18 font-bold text-2xl lg:text-4xl rounded-lg hover:bg-nwoods-secondary " href="../">
19 <h1 class="mb-0 p-1 ">GoJS</h1>
20 </a>
21 </div>
22 <button id="topnavButton" class="rounded-lg sm:hidden focus:outline-none focus:ring" aria-label="Navigation">
23 <svg fill="currentColor" viewBox="0 0 20 20" class="w-6 h-6">
24 <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>
25 <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>
26 </svg>
27 </button>
28 <div id="topnavList" class="hidden sm:block items-center w-auto mt-0 text-white p-0 z-20">
29 <ul class="list-reset list-none font-semibold flex justify-end flex-wrap sm:flex-nowrap items-center px-0 pb-0">
30 <li class="p-1 sm:p-0"><a class="topnav-link" href="../learn/">Learn</a></li>
31 <li class="p-1 sm:p-0"><a class="topnav-link" href="../samples/">Samples</a></li>
32 <li class="p-1 sm:p-0"><a class="topnav-link" href="../intro/">Intro</a></li>
33 <li class="p-1 sm:p-0"><a class="topnav-link" href="../api/">API</a></li>
34 <li class="p-1 sm:p-0"><a class="topnav-link" href="https://www.nwoods.com/products/register.html">Register</a></li>
35 <li class="p-1 sm:p-0"><a class="topnav-link" href="../download.html">Download</a></li>
36 <li class="p-1 sm:p-0"><a class="topnav-link" href="https://forum.nwoods.com/c/gojs/11">Forum</a></li>
37 <li class="p-1 sm:p-0"><a class="topnav-link" href="https://www.nwoods.com/contact.html"
38 target="_blank" rel="noopener" onclick="getOutboundLink('https://www.nwoods.com/contact.html', 'contact');">Contact</a></li>
39 <li class="p-1 sm:p-0"><a class="topnav-link" href="https://www.nwoods.com/sales/index.html"
40 target="_blank" rel="noopener" onclick="getOutboundLink('https://www.nwoods.com/sales/index.html', 'buy');">Buy</a></li>
41 </ul>
42 </div>
43 </div>
44 <hr class="border-b border-gray-600 opacity-50 my-0 py-0" />
45 </nav>
46
47 <div class="md:flex flex-col md:flex-row md:min-h-screen w-full max-w-screen-xl mx-auto">
48
49 <div id="navSide" class="flex flex-col w-full md:w-40 lg:w-48 text-gray-700 bg-white flex-shrink-0">
50 <div class="flex-shrink-0 px-8 py-4">
51 <button id="navButton" class="rounded-lg md:hidden focus:outline-none focus:ring" aria-label="Navigation">
52 <svg fill="currentColor" viewBox="0 0 20 20" class="w-6 h-6">
53 <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>
54 <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>
55 </svg>
56 </button>
57 </div>
58 <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">
59 <a href="../learn/index.html">Get Started</a>
60 <a href="../learn/graphObject.html">Manipulating GraphObjects</a>
61 <a href="../learn/interactivity.html">Interacting with Diagrams</a>
62 </nav>
63 </div>
64 <div class="pt-4 px-2 md:px-0 lg:px-4 pb-16 w-full overflow-hidden">
65
66<h1>Get Started with GoJS</h1>
67
68<h2 id="GoJSTutorials">GoJS Tutorials</h2>
69<p>
70 For video tutorials, see our
71 <a href="https://www.nwoods.com/videos.html">YouTube videos</a>. For textual
72 tutorials, read on.
73</p>
74
75<p>
76 <b>GoJS</b> is a JavaScript library for implementing interactive diagrams.
77 This page will show you the essentials of using <b>GoJS</b>.
78 We assume you are a programmer who is familiar with HTML, CSS, and JavaScript.
79</p>
80
81<p>
82 First, let's load the GoJS library. If you have the library downloaded to your machine:
83</p>
84
85<pre class="lang-html"><code>
86 &lt;!-- use go-debug.js when developing and go.js when deploying --&gt;
87 &lt;script src="go-debug.js"&gt;&lt;/script&gt;
88</code></pre>
89
90<p>
91 You can download <b>GoJS</b> and all the documentation and samples from
92 <a target="_blank" href="../download.html">here</a>.
93</p>
94
95<p>
96 Alternatively you can link straight to a <b>GoJS</b> library provided by a
97 <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Glossary/CDN">CDN</a>
98 such as:
99</p>
100
101<pre class="lang-html"><code>
102&lt;script src="https://unpkg.com/gojs/release/go-debug.js"&gt;&lt;/script&gt;</code></pre>
103<p>
104 Each <b>GoJS</b> diagram is contained in an HTML
105 <code>&lt;div&gt;</code> element in your HTML page that you give an explicit
106 size:
107</p>
108
109<pre class="lang-html"><code>
110&lt;!-- The DIV for a Diagram needs an explicit size or else we will not see anything.
111 In this case we also add a background color so we can see that area. --&gt;
112&lt;div id="myDiagramDiv"
113 style="width:400px; height:150px; background-color: #DAE4E4;"&gt;&lt;/div&gt;
114</code></pre>
115
116<p>
117 In JavaScript code you pass the <code>&lt;div&gt;</code>'s
118 <code>id</code> when making a Diagram:
119</p>
120
121<pre class="lang-js"><code>
122var $ = go.GraphObject.make;
123
124var myDiagram =
125 $(go.Diagram, "myDiagramDiv");
126</code></pre>
127
128<p>Together, this creates an empty diagram:</p>
129
130<!-- LIVE -->
131<div id="myDiagramDiv" class="diagramStyling" style="width: 400px; height: 150px"></div>
132<script>
133 var $ = go.GraphObject.make;
134
135 var myDiagram =
136 $(go.Diagram, "myDiagramDiv");
137</script>
138
139<p>
140 Notice that <code>go</code> is the "namespace" in which all <b>GoJS</b> types
141 reside. All code uses of <b>GoJS</b> classes such as Diagram or Node or Panel
142 or Shape or TextBlock will be prefixed with "<code>go.</code>".
143</p>
144<p>
145 This article will show you by example how to use
146 <code>go.GraphObject.make</code> to build <b>GoJS</b> objects. For more
147 detail, read
148 <a href="../intro/buildingObjects.html">Building Objects in GoJS</a>. Using
149 <code>$</code> as an abbreviation for <code>go.GraphObject.make</code> is so
150 handy that we will assume its use from now on. If you use <code>$</code> for
151 something else in your code, you can always pick a different short variable
152 name, such as <code>$$</code> or <code>MAKE</code> or <code>GO</code>.
153</p>
154
155<h2 id="DiagramsAndModels">Diagrams and Models</h2>
156
157<p>
158 The Nodes and Links of a Diagram are visualizations of data that is managed by
159 a Model.
160 <b>GoJS</b> has a model-view architecture, where Models hold the data (arrays
161 of JavaScript objects) that describe nodes and links, and Diagrams act as
162 views to visualize this data using actual Node and Link objects. Models, not
163 Diagrams, are what you load and then save after editing. You add whatever
164 properties you need for your app on the data objects in the model; you do not
165 add properties to or modify the prototype of the Diagram and GraphObject
166 classes.
167</p>
168
169<p>
170 Here's an example of a Model and Diagram, followed by the actual diagram it
171 generates:
172</p>
173
174<pre class="lang-js"><code>
175var $ = go.GraphObject.make;
176
177var myDiagram =
178 $(go.Diagram, "myDiagramDiv",
179 { // enable Ctrl-Z to undo and Ctrl-Y to redo
180 "undoManager.isEnabled": true
181 });
182
183myDiagram.model = new go.Model(
184 [ // for each object in this Array, the Diagram creates a Node to represent it
185 { key: "Alpha" },
186 { key: "Beta" },
187 { key: "Gamma" }
188 ]);
189</code></pre>
190
191<!-- LIVE -->
192<div id="myDiagramDiv2" class="diagramStyling" style="width: 400px; height: 150px"></div>
193<script>
194 var $ = go.GraphObject.make;
195
196 var myDiagram = $(go.Diagram, "myDiagramDiv2",
197 { // enable Ctrl-Z to undo and Ctrl-Y to redo
198 "undoManager.isEnabled": true,
199 });
200
201 myDiagram.model = new go.Model(
202 [ // for each object in this Array, the Diagram creates a Node to represent it
203 { key: "Alpha" },
204 { key: "Beta" },
205 { key: "Gamma" }
206 ]);
207</script>
208
209<p>
210 The diagram displays the three nodes that are in the model. Some interaction
211 is already possible:
212</p>
213<ul>
214 <li>
215 Click and drag the background in the above diagram to pan the view.
216 </li>
217 <li>
218 Click a node to select it, or press down on and drag a node to move it
219 around.
220 </li>
221 <li>
222 To create a selection box, click and hold on the background, then start
223 dragging.
224 </li>
225 <li>
226 Use Ctrl-C and Ctrl-V, or control-drag-and-drop, to make a copy of the selection.
227 (Use Command key as the modifier on MacOS instead of the Control key.)
228 </li>
229 <li>
230 Press the Delete key to delete selected nodes. (Read about more
231 <a href="../intro/commands.html">Keyboard Commands</a>.)
232 </li>
233 <li>
234 On touch devices, press and hold to bring up a context menu. (Read about
235 <a href="../intro/contextMenus.html">Context Menus</a>.)
236 </li>
237 <li>
238 Since the undo manager was enabled, Ctrl-Z and Ctrl-Y will undo and redo
239 moves and copies and deletions.
240 </li>
241</ul>
242
243<h2 id="StylingNodes">Styling Nodes</h2>
244
245<p>
246 Nodes are styled by creating templates consisting of GraphObjects and setting
247 properties on those objects. To create a
248 <a href="../intro/nodes.html">Node</a>, we have several building block classes
249 at our disposal:
250</p>
251<ul>
252 <li>
253 <a href="../intro/shapes.html">Shape</a>, to display pre-defined or custom
254 geometry with colors
255 </li>
256 <li>
257 <a href="../intro/textblocks.html">TextBlock</a>, to display (potentially
258 editable) text in various fonts
259 </li>
260 <li>
261 <a href="../intro/pictures.html">Picture</a>, to display images, including
262 SVG files
263 </li>
264 <li>
265 <a href="../intro/panels.html">Panel</a>, containers to hold a collection of
266 other objects that can be positioned and sized in different manners
267 according to the type of the Panel (like tables, vertical stacks, and
268 stretching containers)
269 </li>
270</ul>
271
272<p>
273 All of these building blocks are derived from the
274 <a href="../api/symbols/GraphObject.html">GraphObject</a> abstract class, so
275 we casually refer to them as GraphObjects or objects or elements. Note that a
276 GraphObject is <em>not</em> an HTML DOM element, so there is much less overhead in
277 creating or modifying such objects.
278</p>
279
280<p>
281 We want the model data properties to affect our Nodes, and this is done by way
282 of data bindings. Data bindings allow us to change the appearance and behavior
283 of GraphObjects in Nodes by automatically setting properties on those
284 GraphObjects to values that are taken from the model data. The model data
285 objects are plain JavaScript objects. You can choose to use whatever property
286 names you like on the node data in the model.
287</p>
288
289<p>
290 The default Node template is simple: A Node which contains one TextBlock.
291 There is a data binding between a TextBlock's <code>text</code> property and
292 the model data's <code>key</code> property. In code, the template looks
293 something like this:
294</p>
295
296<pre class="lang-js"><code>
297myDiagram.nodeTemplate =
298 $(go.Node,
299 $(go.TextBlock,
300 // TextBlock.text is bound to Node.data.key
301 new go.Binding("text", "key"))
302 );
303</code></pre>
304<p>
305 TextBlocks, Shapes, and Pictures are the primitive building blocks of
306 <b>GoJS</b>. TextBlocks cannot contain images; Shapes cannot contain text. If
307 you want your node to show some text, you must use a TextBlock. If you want to
308 draw or fill some geometrical figures, you must use a Shape.
309</p>
310<p>
311 More generally, the skeleton of a Node template will look something like this:
312</p>
313
314<pre class="lang-js"><code>
315myDiagram.nodeTemplate =
316 $(go.Node, "Vertical", // second argument of a Node (or any Panel) can be a Panel type
317 /* set Node properties here */
318 { // the Node.location point will be at the center of each node
319 locationSpot: go.Spot.Center
320 },
321
322 /* add Bindings here */
323 // example Node binding sets Node.location to the value of Node.data.loc
324 new go.Binding("location", "loc"),
325
326 /* add GraphObjects contained within the Node */
327 // this Shape will be vertically above the TextBlock
328 $(go.Shape,
329 "RoundedRectangle", // string argument can name a predefined figure
330 { /* set Shape properties here */ },
331 // example Shape binding sets Shape.figure to the value of Node.data.fig
332 new go.Binding("figure", "fig")),
333
334 $(go.TextBlock,
335 "default text", // string argument can be initial text string
336 { /* set TextBlock properties here */ },
337 // example TextBlock binding sets TextBlock.text to the value of Node.data.text
338 new go.Binding("text"))
339 );
340</code></pre>
341
342<p>
343 The nesting of GraphObjects within Panels can be arbitrarily deep, and every
344 class has its own unique set of properties to utilize, but this shows the
345 general idea.
346</p>
347
348<p>
349 Now that we have seen how to make a Node template, let's see a live example.
350 We will make a simple template commonly seen in organizational diagrams — an
351 image next to a name. Consider the following Node template:
352</p>
353<ul>
354 <li>
355 A Node of "Horizontal" Panel type, meaning that its elements will be laid
356 out horizontally side-by-side. It has two elements:
357 <ul>
358 <li>A Picture for the portrait, with the image source data bound</li>
359 <li>A TextBlock for the name, with the text data bound</li>
360 </ul>
361 </li>
362</ul>
363
364<pre class="lang-js"><code>
365var $ = go.GraphObject.make;
366
367var myDiagram =
368 $(go.Diagram, "myDiagramDiv",
369 { // enable Ctrl-Z to undo and Ctrl-Y to redo
370 "undoManager.isEnabled": true
371 });
372
373// define a simple Node template
374myDiagram.nodeTemplate =
375 $(go.Node, "Horizontal",
376 // the entire node will have a light-blue background
377 { background: "#44CCFF" },
378 $(go.Picture,
379 // Pictures should normally have an explicit width and height.
380 // This picture has a red background, only visible when there is no source set
381 // or when the image is partially transparent.
382 { margin: 10, width: 50, height: 50, background: "red" },
383 // Picture.source is data bound to the "source" attribute of the model data
384 new go.Binding("source")),
385 $(go.TextBlock,
386 "Default Text", // the initial value for TextBlock.text
387 // some room around the text, a larger font, and a white stroke:
388 { margin: 12, stroke: "white", font: "bold 16px sans-serif" },
389 // TextBlock.text is data bound to the "name" property of the model data
390 new go.Binding("text", "name"))
391 );
392
393myDiagram.model = new go.Model(
394 [ // note that each node data object holds whatever properties it needs;
395 // for this app we add the "name" and "source" properties
396 { name: "Don Meow", source: "cat1.png" },
397 { name: "Copricat", source: "cat2.png" },
398 { name: "Demeter", source: "cat3.png" },
399 { /* Empty node data */ }
400 ]);
401</code></pre>
402
403<p>That code produces this diagram:</p>
404
405<!-- LIVE -->
406<div id="myDiagramDiv3" class="diagramStyling" style="width: 700px; height: 200px"></div>
407<script>
408 var $ = go.GraphObject.make;
409
410 var myDiagram =
411 $(go.Diagram, "myDiagramDiv3",
412 { // enable Ctrl-Z to undo and Ctrl-Y to redo
413 "undoManager.isEnabled": true,
414 });
415
416 // define a simple Node template
417 myDiagram.nodeTemplate =
418 $(go.Node, "Horizontal",
419 // the entire node will have a light-blue background
420 { background: "#44CCFF" },
421 $(go.Picture,
422 // Pictures should normally have an explicit width and height.
423 // This picture has a red background, only visible when there is no source set
424 // or when the image is partially transparent.
425 { margin: 10, width: 50, height: 50, background: "red" },
426 // Picture.source is data bound to the "source" attribute of model data:
427 new go.Binding("source")),
428 $(go.TextBlock,
429 "Default Text", // the initial value for TextBlock.text
430 // some room around the text, a larger font, and a white stroke
431 { margin: 12, stroke: "white", font: "bold 16px sans-serif" },
432 // TextBlock.text is data bound to the "name" property of model data:
433 new go.Binding("text", "name"))
434 );
435
436 myDiagram.model = new go.Model(
437 [
438 // note that each node data object holds whatever properties it needs;
439 // for this app we add the "name" and "source" properties
440 { name: "Don Meow", source: "cat1.png" },
441 { name: "Copricat", source: "cat2.png" },
442 { name: "Demeter", source: "cat3.png" },
443 { /* Empty node data */ }
444 ]);
445</script>
446
447<p>
448 We may want to show some "default" state when not all information is present,
449 for instance when an image does not load or when a name is not known. The
450 "empty" node data in this example is used to show that node templates can work
451 perfectly well without any of the properties on the bound data.
452</p>
453
454<h2 id="KindsOfNodes">Kinds of Models</h2>
455
456<p>
457 With a custom node template our diagram is becoming a pretty sight, but
458 perhaps we want to show more. Perhaps we want an organizational chart to show
459 that Don Meow is really the boss of a cat cartel. So we will create a complete
460 organization chart diagram by adding some Links to show the relationship
461 between individual nodes and a Layout to automatically position the nodes.
462</p>
463
464<p>
465 In order to get links into our diagram, the basic <code>Model</code> is not
466 going to cut it. We are going to have to pick one of the other two models in
467 <b>GoJS</b>, both of which support Links. These are
468 <code>GraphLinksModel</code> and <code>TreeModel</code>. (Read more about
469 models <a href="../intro/usingModels.html">here</a>.)
470</p>
471
472<p>
473 In GraphLinksModel, we have a <code>model.linkDataArray</code> in addition to
474 the <code>model.nodeDataArray</code>. It holds an array of JavaScript objects,
475 each describing a link by specifying the "to" and "from" node keys. Here's an
476 example where node A links to node B and where node B links to node C:
477</p>
478
479<pre class="lang-js"><code>
480myDiagram.model = new go.GraphLinksModel(
481 [ // the nodeDataArray
482 { key: "A" },
483 { key: "B" },
484 { key: "C" }
485 ],
486 [ // the linkDataArray
487 { from: "A", to: "B" },
488 { from: "B", to: "C" }
489 ]);
490</code></pre>
491
492<p>
493 A GraphLinksModel allows you to have any number of links between nodes, going
494 in any direction. There could be ten links running from A to B, and three more
495 running the opposite way, from B to A.
496</p>
497
498<p>
499 A TreeModel works a little differently. Instead of maintaining a separate
500 array of link data, the links in a tree model are created by specifying a
501 "parent" for a node data. Links are then created from this association. Here's
502 the same example done as a TreeModel, with node A linking to node B and node B
503 linking to node C:
504</p>
505
506<pre class="lang-js"><code>
507myDiagram.model = new go.TreeModel(
508 [ // the nodeDataArray
509 { key: "A" },
510 { key: "B", parent: "A" },
511 { key: "C", parent: "B" }
512 ]);
513</code></pre>
514
515<p>
516 TreeModel is simpler than GraphLinksModel, but it cannot make arbitrary link
517 relationships, such as multiple links between the same two nodes, or having
518 multiple parents. Our organizational diagram is a simple hierarchical
519 tree-like structure, so we will choose TreeModel for this example.
520</p>
521
522<p>
523 First, we will complete the data by adding a few more nodes, using a
524 TreeModel, and specifying keys and parents in the data.
525</p>
526
527<pre class="lang-js"><code>
528var $ = go.GraphObject.make;
529
530var myDiagram =
531 $(go.Diagram, "myDiagramDiv",
532 { "undoManager.isEnabled": true });
533
534// the template we defined earlier
535myDiagram.nodeTemplate =
536 $(go.Node, "Horizontal",
537 { background: "#44CCFF" },
538 $(go.Picture,
539 { margin: 10, width: 50, height: 50, background: "red" },
540 new go.Binding("source")),
541 $(go.TextBlock, "Default Text",
542 { margin: 12, stroke: "white", font: "bold 16px sans-serif" },
543 new go.Binding("text", "name"))
544 );
545
546myDiagram.model = new go.TreeModel(
547 [ // the "key" and "parent" property names are required,
548 // but you can add whatever data properties you need for your app
549 { key: "1", name: "Don Meow", source: "cat1.png" },
550 { key: "2", parent: "1", name: "Demeter", source: "cat2.png" },
551 { key: "3", parent: "1", name: "Copricat", source: "cat3.png" },
552 { key: "4", parent: "3", name: "Jellylorum", source: "cat4.png" },
553 { key: "5", parent: "3", name: "Alonzo", source: "cat5.png" },
554 { key: "6", parent: "2", name: "Munkustrap", source: "cat6.png" }
555 ]);
556</code></pre>
557
558<!-- LIVE -->
559<div id="myDiagramDiv4" class="diagramStyling" style="width: 700px; height: 200px"></div>
560<script>
561 var $ = go.GraphObject.make;
562
563 var myDiagram =
564 $(go.Diagram, "myDiagramDiv4",
565 { "undoManager.isEnabled": true });
566
567 // the template we defined earlier
568 myDiagram.nodeTemplate =
569 $(go.Node, "Horizontal",
570 { background: "#44CCFF" },
571 $(go.Picture,
572 { margin: 10, width: 50, height: 50, background: "red" },
573 new go.Binding("source")),
574 $(go.TextBlock, "Default Text",
575 { margin: 12, stroke: "white", font: "bold 16px sans-serif" },
576 new go.Binding("text", "name"))
577 );
578
579 myDiagram.model = new go.TreeModel(
580 [ // the "key" and "parent" property names are required,
581 // but you can add whatever data properties you need for your app
582 { key: "1", name: "Don Meow", source: "cat1.png" },
583 { key: "2", parent: "1", name: "Demeter", source: "cat2.png" },
584 { key: "3", parent: "1", name: "Copricat", source: "cat3.png" },
585 { key: "4", parent: "3", name: "Jellylorum", source: "cat4.png" },
586 { key: "5", parent: "3", name: "Alonzo", source: "cat5.png" },
587 { key: "6", parent: "2", name: "Munkustrap", source: "cat6.png" },
588 ]);
589</script>
590
591<h2 id="DiagramLayouts">Diagram Layouts</h2>
592
593<p>
594 As you can see the TreeModel automatically creates the necessary Links to
595 associate the Nodes, but it's hard to tell whose parent is who.
596</p>
597
598<p>
599 Diagrams have a default layout which takes all nodes that do not have a
600 location and gives them locations, arranging them in a grid. We could
601 explicitly give each of our nodes a location to sort out this organizational
602 mess, but as an easier solution in our case, we will use a layout that gives
603 us good locations automatically.
604</p>
605
606<p>
607 We want to show a hierarchy, and are already using a TreeModel, so the most
608 natural layout choice is TreeLayout. TreeLayout defaults to flowing from left
609 to right, so to get it to flow from top to bottom (as is common in
610 organizational diagrams), we will set the <code>angle</code> property to 90.
611</p>
612
613<p>
614 Using layouts in <b>GoJS</b> is usually simple. Each kind of layout has a
615 number of properties that affect the results. There are samples for each
616 layout (like <a href="../samples/tLayout.html">TreeLayout Demo</a>) that
617 showcase its properties.
618</p>
619
620<pre class="lang-js"><code>
621// define a TreeLayout that flows from top to bottom
622myDiagram.layout =
623 $(go.TreeLayout,
624 { angle: 90, layerSpacing: 35 });
625</code></pre>
626
627<p>
628 <b>GoJS</b> has many other layouts, which you can read about
629 <a href="../intro/layouts.html">here</a>.
630</p>
631
632<p>
633 Adding the layout to the diagram and model so far, we can see our results:
634</p>
635
636<pre class="lang-js"><code>
637var $ = go.GraphObject.make;
638
639var myDiagram =
640 $(go.Diagram, "myDiagramDiv",
641 {
642 "undoManager.isEnabled": true,
643 layout: $(go.TreeLayout, // specify a Diagram.layout that arranges trees
644 { angle: 90, layerSpacing: 35 })
645 });
646
647// the template we defined earlier
648myDiagram.nodeTemplate =
649 $(go.Node, "Horizontal",
650 { background: "#44CCFF" },
651 $(go.Picture,
652 { margin: 10, width: 50, height: 50, background: "red" },
653 new go.Binding("source")),
654 $(go.TextBlock, "Default Text",
655 { margin: 12, stroke: "white", font: "bold 16px sans-serif" },
656 new go.Binding("text", "name"))
657 );
658
659// the same model as before
660myDiagram.model = new go.TreeModel(
661 [
662 { key: "1", name: "Don Meow", source: "cat1.png" },
663 { key: "2", parent: "1", name: "Demeter", source: "cat2.png" },
664 { key: "3", parent: "1", name: "Copricat", source: "cat3.png" },
665 { key: "4", parent: "3", name: "Jellylorum", source: "cat4.png" },
666 { key: "5", parent: "3", name: "Alonzo", source: "cat5.png" },
667 { key: "6", parent: "2", name: "Munkustrap", source: "cat6.png" }
668 ]);
669</code></pre>
670
671<!-- LIVE -->
672<div id="myDiagramDiv5" class="diagramStyling" style="width: 700px; height: 400px"></div>
673<script>
674 var $ = go.GraphObject.make;
675
676 var myDiagram =
677 $(go.Diagram, "myDiagramDiv5",
678 {
679 "undoManager.isEnabled": true,
680 layout: $(go.TreeLayout, // specify a Diagram.layout that arranges trees
681 { angle: 90, layerSpacing: 35 }),
682 });
683
684 // the template we defined earlier
685 myDiagram.nodeTemplate =
686 $(go.Node, "Horizontal",
687 { background: "#44CCFF" },
688 $(go.Picture,
689 { margin: 10, width: 50, height: 50, background: "red" },
690 new go.Binding("source")),
691 $(go.TextBlock, "Default Text",
692 { margin: 12, stroke: "white", font: "bold 16px sans-serif" },
693 new go.Binding("text", "name"))
694 );
695
696 // the same model as before
697 myDiagram.model = new go.TreeModel(
698 [
699 { key: "1", name: "Don Meow", source: "cat1.png" },
700 { key: "2", parent: "1", name: "Demeter", source: "cat2.png" },
701 { key: "3", parent: "1", name: "Copricat", source: "cat3.png" },
702 { key: "4", parent: "3", name: "Jellylorum", source: "cat4.png" },
703 { key: "5", parent: "3", name: "Alonzo", source: "cat5.png" },
704 { key: "6", parent: "2", name: "Munkustrap", source: "cat6.png" },
705 ]);
706</script>
707
708<p>
709 Our diagram is starting to look like a proper organization chart, but we could
710 do better with the links.
711</p>
712
713<h2 id="LinkTemplates">Link Templates</h2>
714
715<p>
716 We will construct a new Link template that will better suit our wide, boxy
717 nodes. A <a href="../intro/links.html">Link</a> is a different kind of Part,
718 not like a Node. The main element of a Link is the Link's shape, and must be a
719 Shape that will have its geometry computed dynamically by <b>GoJS</b>. Our
720 link is going to consist of just this shape, with its stroke a little thicker
721 than normal and dark gray instead of black. Unlike the default link template
722 we will not have an arrowhead. And we will change the Link
723 <code>routing</code> property from Normal to Orthogonal, and give it a
724 <code>corner</code> value so that right-angle turns are rounded.
725</p>
726
727<pre class="lang-js"><code>
728// define a Link template that routes orthogonally, with no arrowhead
729myDiagram.linkTemplate =
730 $(go.Link,
731 // default routing is go.Link.Normal
732 // default corner is 0
733 { routing: go.Link.Orthogonal, corner: 5 },
734 // the link path, a Shape
735 $(go.Shape, { strokeWidth: 3, stroke: "#555" })
736
737 // if we wanted an arrowhead we would also add another Shape with toArrow defined:
738 // $(go.Shape, { toArrow: "Standard", stroke: null }
739 );
740</code></pre>
741
742<p>
743 Combining our Link template with our Node template, TreeModel, and TreeLayout,
744 we finally have a full organization diagram. The complete code is repeated
745 below, and the resulting diagram follows:
746</p>
747
748<pre class="lang-js"><code>
749var $ = go.GraphObject.make;
750
751var myDiagram =
752 $(go.Diagram, "myDiagramDiv",
753 {
754 "undoManager.isEnabled": true,
755 layout: $(go.TreeLayout,
756 { angle: 90, layerSpacing: 35 })
757 });
758
759myDiagram.nodeTemplate =
760 $(go.Node, "Horizontal",
761 { background: "#44CCFF" },
762 $(go.Picture,
763 { margin: 10, width: 50, height: 50, background: "red" },
764 new go.Binding("source")),
765 $(go.TextBlock, "Default Text",
766 { margin: 12, stroke: "white", font: "bold 16px sans-serif" },
767 new go.Binding("text", "name"))
768 );
769
770// define a Link template that routes orthogonally, with no arrowhead
771myDiagram.linkTemplate =
772 $(go.Link,
773 { routing: go.Link.Orthogonal, corner: 5 },
774 $(go.Shape, // the link's path shape
775 { strokeWidth: 3, stroke: "#555" })
776 );
777
778// it's best to declare all templates before assigning the model
779myDiagram.model = new go.TreeModel(
780 [
781 { key: "1", name: "Don Meow", source: "cat1.png" },
782 { key: "2", parent: "1", name: "Demeter", source: "cat2.png" },
783 { key: "3", parent: "1", name: "Copricat", source: "cat3.png" },
784 { key: "4", parent: "3", name: "Jellylorum", source: "cat4.png" },
785 { key: "5", parent: "3", name: "Alonzo", source: "cat5.png" },
786 { key: "6", parent: "2", name: "Munkustrap", source: "cat6.png" }
787 ]);
788</code></pre>
789
790<!-- LIVE -->
791<div id="myDiagramDiv6" class="diagramStyling" style="width: 700px; height: 400px"></div>
792<script>
793 var $ = go.GraphObject.make;
794
795 var myDiagram =
796 $(go.Diagram, "myDiagramDiv6",
797 {
798 "undoManager.isEnabled": true,
799 layout: $(go.TreeLayout,
800 { angle: 90, layerSpacing: 35 }),
801 });
802
803 myDiagram.nodeTemplate =
804 $(go.Node, "Horizontal",
805 { background: "#44CCFF" },
806 $(go.Picture,
807 { margin: 10, width: 50, height: 50, background: "red" },
808 new go.Binding("source")),
809 $(go.TextBlock, "Default Text",
810 { margin: 12, stroke: "white", font: "bold 16px sans-serif" },
811 new go.Binding("text", "name"))
812 );
813
814 // define a Link template that routes orthogonally, with no arrowhead
815 myDiagram.linkTemplate =
816 $(go.Link,
817 { routing: go.Link.Orthogonal, corner: 5 },
818 $(go.Shape, // the link's path shape
819 { strokeWidth: 3, stroke: "#555" })
820 );
821
822 // it's best to declare all templates before assigning the model
823 myDiagram.model = new go.TreeModel(
824 [
825 { key: "1", name: "Don Meow", source: "cat1.png" },
826 { key: "2", parent: "1", name: "Demeter", source: "cat2.png" },
827 { key: "3", parent: "1", name: "Copricat", source: "cat3.png" },
828 { key: "4", parent: "3", name: "Jellylorum", source: "cat4.png" },
829 { key: "5", parent: "3", name: "Alonzo", source: "cat5.png" },
830 { key: "6", parent: "2", name: "Munkustrap", source: "cat6.png" },
831 ]);
832</script>
833
834<h2 id="LearnMore">Learn More</h2>
835<p>
836 You may want to read more tutorials, such as the
837 <a href="graphObject.html">GraphObject Manipulation</a> tutorial and the
838 <a href="interactivity.html">Interactivity</a> tutorial. You can also watch
839 tutorials on
840 <a href="https://www.youtube.com/channel/UC9We8EoX596-6XFjJDtZIDg">YouTube</a
841 >.
842</p>
843<p>
844 Also consider looking at the <a href="../samples/index.html">samples</a> to
845 see some of the diagrams possible with <b>GoJS</b>, or read the
846 <a href="../intro/index.html">technical introduction</a> to get an in-depth
847 look at the components of <b>GoJS</b>.
848</p>
849
850
851
852 </div>
853 </div>
854
855 <div class="bg-nwoods-primary">
856 <section class="max-w-screen-lg text-white container mx-auto py-2 px-12">
857 <p id="version" class="leading-none mb-2 my-4">GoJS</p>
858 </section>
859 </div><footer class="bg-nwoods-primary text-white">
860 <div class="container max-w-screen-lg mx-auto px-8">
861 <div class="w-full py-6">
862
863 <div class="max-w-screen-lg xl:max-w-screen-xl mx-auto px-4 sm:px-6 md:px-8">
864 <ul class="text-sm font-medium pb-14 sm:pb-20 grid grid-cols-1 sm:grid-cols-3 gap-y-10">
865 <li class="list-none row-span-2">
866 <h2 class="text-base font-semibold tracking-wide">GoJS</h2>
867 <ul class="list-none space-y-4 md:space-y-1 px-0">
868 <li>
869 <a href="../samples/index.html">Samples</a>
870 </li>
871 <li>
872 <a href="../learn/index.html">Learn</a>
873 </li>
874 <li>
875 <a href="../intro/index.html">Intro</a>
876 </li>
877 <li>
878 <a href="../api/index.html">API</a>
879 </li>
880 <li>
881 <a href="../changelog.html">Changelog</a>
882 </li>
883 <li>
884 <a href="https://github.com/NorthwoodsSoftware/GoJS">GitHub</a>
885 </li>
886 </ul>
887 </li>
888 <li class="list-none row-span-2">
889 <h2 class="text-base font-semibold tracking-wide">Support</h2>
890 <ul class="list-none space-y-4 md:space-y-1 px-0">
891 <li>
892 <a href="https://www.nwoods.com/contact.html"
893 target="_blank" rel="noopener" onclick="getOutboundLink('https://www.nwoods.com/contact.html', 'contact');">Contact</a>
894 </li>
895 <li>
896 <a href="https://forum.nwoods.com/c/gojs">Forum</a>
897 </li>
898 <li>
899 <a href="https://www.nwoods.com/app/activate.aspx?sku=gojs">Activate</a>
900 </li>
901 <li>
902 <a href="https://www.nwoods.com/sales/index.html"
903 target="_blank" rel="noopener" onclick="getOutboundLink('https://www.nwoods.com/sales/index.html', 'buy');">Buy</a>
904 </li>
905 <li>
906 <a href="https://www.youtube.com/channel/UC9We8EoX596-6XFjJDtZIDg">Videos</a>
907 </li>
908 </ul>
909 </li>
910 <li class="list-none row-span-2">
911 <h2 class="text-base font-semibold tracking-wide">Company</h2>
912 <ul class="list-none space-y-4 md:space-y-1 px-0">
913 <li>
914 <a href="https://www.nwoods.com">Northwoods</a>
915 </li>
916 <li>
917 <a href="https://www.nwoods.com/about.html">About Us</a>
918 </li>
919 <li>
920 <a href="https://www.nwoods.com/contact.html">Contact Us</a>
921 </li>
922 <li>
923 <a href="https://twitter.com/northwoodsgo">Twitter</a>
924 </li>
925
926 </ul>
927 </li>
928 </ul>
929
930
931 <p class="text-sm text-gray-100 md:mb-6">
932 Copyright 1998-2021 <a class="text-white" href="https://www.nwoods.com">Northwoods Software</a>
933 </p>
934 </div>
935 </div>
936</footer> </body>
937
938<script async src="https://www.googletagmanager.com/gtag/js?id=UA-1506307-5"></script>
939<script>
940 window.dataLayer = window.dataLayer || [];
941 function gtag(){dataLayer.push(arguments);}
942 gtag('js', new Date()); gtag('config', 'UA-1506307-5');
943 var getOutboundLink = function(url, label) {
944 gtag('event', 'click', {
945 'event_category': 'outbound',
946 'event_label': label,
947 'transport_type': 'beacon'
948 });
949 }
950
951 // topnav
952 var topButton = document.getElementById("topnavButton");
953 var topnavList = document.getElementById("topnavList");
954 topButton.addEventListener("click", function() {
955 this.classList.toggle("active");
956 topnavList.classList.toggle("hidden");
957 document.getElementById("topnavOpen").classList.toggle("hidden");
958 document.getElementById("topnavClosed").classList.toggle("hidden");
959 });
960</script>
961 <script src="../assets/js/prism.js"></script>
962 <script src="../assets/js/goDoc.js"></script>
963 <script>
964 document.addEventListener("DOMContentLoaded", function() {
965 if (window.go) document.getElementById('version').textContent = "GoJS version " + go.version;
966 if (window.goDoc) window.goDoc();
967 });
968 </script>
969</html>
\No newline at end of file