UNPKG

20.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
7<link rel="stylesheet" href="../assets/css/style.css"/>
8<!-- Copyright 1998-2021 by Northwoods Software Corporation. --> <title> GoJS Trees -- 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
134
135
136<h1>Trees and TreeLayout</h1>
137<p>
138There is no limit to the kinds of graphs that you can build in <b>GoJS</b>.
139But the most common kind of graph forms a "tree".
140A tree is a graph where each node may have at most one "tree parent" and at most one link connecting to that parent node,
141and where there are no cycles within the graph.
142</p>
143<p>
144Because trees occur so frequently in diagrams,
145there is also a tree layout that offers many customizations specifically for trees.
146</p>
147
148<h2 id="ManualLayoutOfTreeStructure">Manual layout of a tree structure</h2>
149<p>
150You can of course position the nodes manually, either by hand or programmatically.
151In this first example, the node locations are stored in the node data,
152and there is a Binding of <a>Part.location</a> to the node data property.
153</p>
154<pre class="lang-js" id="tree"><code>
155 diagram.nodeTemplate =
156 $(go.Node, "Auto",
157 new go.Binding("location", "loc", go.Point.parse),
158 $(go.Shape, "Ellipse", { fill: "white" }),
159 $(go.TextBlock,
160 new go.Binding("text", "key"))
161 );
162
163 diagram.linkTemplate =
164 $(go.Link,
165 { routing: go.Link.Orthogonal, corner: 5 },
166 $(go.Shape));
167
168 var nodeDataArray = [
169 { key: "Alpha", loc: "0 60" },
170 { key: "Beta", loc: "100 15" },
171 { key: "Gamma", loc: "200 0" },
172 { key: "Delta", loc: "200 30" },
173 { key: "Epsilon", loc: "100 90" },
174 { key: "Zeta", loc: "200 60" },
175 { key: "Eta", loc: "200 90" },
176 { key: "Theta", loc: "200 120" }
177 ];
178 var linkDataArray = [
179 { from: "Alpha", to: "Beta" },
180 { from: "Beta", to: "Gamma" },
181 { from: "Beta", to: "Delta" },
182 { from: "Alpha", to: "Epsilon" },
183 { from: "Epsilon", to: "Zeta" },
184 { from: "Epsilon", to: "Eta" },
185 { from: "Epsilon", to: "Theta" }
186 ];
187 diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
188</code></pre>
189<script>goCode("tree", 600, 200)</script>
190<p>
191You can also get the same results by using a <a>TreeModel</a>.
192</p>
193<pre class="lang-js" id="tree2"><code>
194 diagram.nodeTemplate =
195 $(go.Node, "Auto",
196 new go.Binding("location", "loc", go.Point.parse),
197 $(go.Shape, "Ellipse", { fill: "white" }),
198 $(go.TextBlock,
199 new go.Binding("text", "key"))
200 );
201
202 diagram.linkTemplate =
203 $(go.Link,
204 { routing: go.Link.Orthogonal, corner: 5 },
205 $(go.Shape));
206
207 var nodeDataArray = [
208 { key: "Alpha", loc: "0 60" },
209 { key: "Beta", loc: "100 15", parent: "Alpha" },
210 { key: "Gamma", loc: "200 0", parent: "Beta" },
211 { key: "Delta", loc: "200 30", parent: "Beta" },
212 { key: "Epsilon", loc: "100 90", parent: "Alpha" },
213 { key: "Zeta", loc: "200 60", parent: "Epsilon" },
214 { key: "Eta", loc: "200 90", parent: "Epsilon" },
215 { key: "Theta", loc: "200 120", parent: "Epsilon" }
216 ];
217 diagram.model = new go.TreeModel(nodeDataArray);
218</code></pre>
219<script>goCode("tree2", 600, 200)</script>
220
221<h2 id="AutomaticTreeLayout">Automatic TreeLayout</h2>
222<p>
223It is most common to use <a>TreeLayout</a> for laying out trees.
224Just assign <a>Diagram.layout</a> to a new instance of <a>TreeLayout</a>.
225This example also defines the <code>setupTree</code> function that is used in later examples on this page.
226</p>
227<pre class="lang-js" id="treeLayout"><code>
228function setupTree(diagram) {
229 diagram.nodeTemplate =
230 $(go.Node, "Auto",
231 $(go.Shape, "Ellipse", { fill: "white" }),
232 $(go.TextBlock,
233 new go.Binding("text", "key"))
234 );
235
236 diagram.linkTemplate =
237 $(go.Link,
238 { routing: go.Link.Orthogonal, corner: 5 },
239 $(go.Shape));
240
241 var nodeDataArray = [
242 { key: "Alpha" },
243 { key: "Beta", parent: "Alpha" },
244 { key: "Gamma", parent: "Beta" },
245 { key: "Delta", parent: "Beta" },
246 { key: "Epsilon", parent: "Alpha" },
247 { key: "Zeta", parent: "Epsilon" },
248 { key: "Eta", parent: "Epsilon" },
249 { key: "Theta", parent: "Epsilon" }
250 ];
251 diagram.model = new go.TreeModel(nodeDataArray);
252}
253
254 setupTree(diagram);
255 // automatic tree layout
256 diagram.layout = $(go.TreeLayout);
257</code></pre>
258<script>goCode("treeLayout", 600, 200)</script>
259
260<script>
261function setupTree(diagram) {
262 var $ = go.GraphObject.make;
263
264 diagram.nodeTemplate =
265 $(go.Node, "Auto",
266 $(go.Shape, "Ellipse", { fill: "white" }),
267 $(go.TextBlock,
268 new go.Binding("text", "key"))
269 );
270
271 diagram.linkTemplate =
272 $(go.Link,
273 { routing: go.Link.Orthogonal, corner: 5 },
274 $(go.Shape));
275
276 var nodeDataArray = [
277 { key: "Alpha" },
278 { key: "Beta", parent: "Alpha" },
279 { key: "Gamma", parent: "Beta" },
280 { key: "Delta", parent: "Beta" },
281 { key: "Epsilon", parent: "Alpha" },
282 { key: "Zeta", parent: "Epsilon" },
283 { key: "Eta", parent: "Epsilon" },
284 { key: "Theta", parent: "Epsilon" }
285 ];
286 diagram.model = new go.TreeModel(nodeDataArray);
287}
288</script>
289
290<h2 id="CommonTreeLayoutProperties">Common TreeLayout properties</h2>
291<p>
292The <a>TreeLayout.angle</a> property controls the general direction of tree growth.
293This must be zero (towards the right), 90 (downward), 180 (leftward), or 270 (upward).
294</p>
295<pre class="lang-js" id="angle"><code>
296 setupTree(diagram);
297 diagram.layout = $(go.TreeLayout, { angle: 90 });
298</code></pre>
299<script>goCode("angle", 600, 200)</script>
300
301<p>
302The <code>setupTree</code> function was defined above.
303</p>
304
305<p>
306The <a>TreeLayout.alignment</a> property controls how the parent node is positioned relative to its children.
307This must be one of the Alignment... constants defined on <a>TreeLayout</a>.
308</p>
309<pre class="lang-js" id="alignment"><code>
310 setupTree(diagram);
311 diagram.layout = $(go.TreeLayout, { angle: 90, alignment: go.TreeLayout.AlignmentStart });
312</code></pre>
313<script>goCode("alignment", 600, 200)</script>
314
315<p>
316For tree layouts, all of the nodes are placed into "layers" according to the length of the chain of links from the root node.
317These layers are not to be confused with Diagram <a>Layer</a>s, which control the Z-ordering of the nodes.
318The <a>TreeLayout.layerSpacing</a> property controls how close the layers are to each other.
319The <a>TreeLayout.nodeSpacing</a> property controls how close nodes are to each other in the same layer.
320</p>
321<pre class="lang-js" id="spacing"><code>
322 setupTree(diagram);
323 diagram.layout = $(go.TreeLayout, { layerSpacing: 20, nodeSpacing: 0 });
324</code></pre>
325<script>goCode("spacing", 600, 200)</script>
326
327<p>
328The children of each node can be sorted. By default the <a>TreeLayout.comparer</a> function compares the
329<a>Part.text</a> property. So if that property is data bound by the node template, and if you set the
330<a>TreeLayout.sorting</a> property to sort in either ascending or descending order,
331each parent node will have all of its children sorted in that order by their text strings.
332(In this example that means alphabetical ordering of the English names of the letters of the Greek alphabet.)
333</p>
334<pre class="lang-js" id="sort"><code>
335 setupTree(diagram);
336 diagram.nodeTemplate =
337 $(go.Node, "Auto",
338 new go.Binding("text", "key"), // bind Part.text to support sorting
339 $(go.Shape, "Ellipse", { fill: "lightblue" }),
340 $(go.TextBlock,
341 new go.Binding("text", "key"))
342 );
343 diagram.layout = $(go.TreeLayout, { sorting: go.TreeLayout.SortingAscending });
344</code></pre>
345<script>goCode("sort", 600, 200)</script>
346<p>
347But you can provide your own function for ordering the children, such as:
348</p>
349<pre class="lang-js"><code>
350 $(go.Diagram, . . .,
351 {
352 layout:
353 $(go.TreeLayout,
354 {
355 sorting: go.TreeLayout.SortingAscending,
356 comparer: function(a, b) {
357 // A and B are TreeVertexes
358 var av = a.node.data.index;
359 var bv = b.node.data.index;
360 if (av < bv) return -1;
361 if (av > bv) return 1;
362 return 0;
363 },
364 . . .
365 })
366 . . .
367 })
368</code></pre>
369
370 </div>
371 </div>
372
373 <div class="bg-nwoods-primary">
374 <section class="max-w-screen-lg text-white container mx-auto py-2 px-12">
375 <p id="version" class="leading-none mb-2 my-4">GoJS</p>
376 </section>
377 </div><footer class="bg-nwoods-primary text-white">
378 <div class="container max-w-screen-lg mx-auto px-8">
379 <div class="w-full py-6">
380
381 <div class="max-w-screen-lg xl:max-w-screen-xl mx-auto px-4 sm:px-6 md:px-8">
382 <ul class="text-sm font-medium pb-14 sm:pb-20 grid grid-cols-1 sm:grid-cols-3 gap-y-10">
383 <li class="list-none row-span-2">
384 <h2 class="text-base font-semibold tracking-wide">GoJS</h2>
385 <ul class="list-none space-y-4 md:space-y-1 px-0">
386 <li>
387 <a href="../samples/index.html">Samples</a>
388 </li>
389 <li>
390 <a href="../learn/index.html">Learn</a>
391 </li>
392 <li>
393 <a href="../intro/index.html">Intro</a>
394 </li>
395 <li>
396 <a href="../api/index.html">API</a>
397 </li>
398 <li>
399 <a href="../changelog.html">Changelog</a>
400 </li>
401 <li>
402 <a href="https://github.com/NorthwoodsSoftware/GoJS">GitHub</a>
403 </li>
404 </ul>
405 </li>
406 <li class="list-none row-span-2">
407 <h2 class="text-base font-semibold tracking-wide">Support</h2>
408 <ul class="list-none space-y-4 md:space-y-1 px-0">
409 <li>
410 <a href="https://www.nwoods.com/contact.html"
411 target="_blank" rel="noopener" onclick="getOutboundLink('https://www.nwoods.com/contact.html', 'contact');">Contact</a>
412 </li>
413 <li>
414 <a href="https://forum.nwoods.com/c/gojs">Forum</a>
415 </li>
416 <li>
417 <a href="https://www.nwoods.com/app/activate.aspx?sku=gojs">Activate</a>
418 </li>
419 <li>
420 <a href="https://www.nwoods.com/sales/index.html"
421 target="_blank" rel="noopener" onclick="getOutboundLink('https://www.nwoods.com/sales/index.html', 'buy');">Buy</a>
422 </li>
423 <li>
424 <a href="https://www.youtube.com/channel/UC9We8EoX596-6XFjJDtZIDg">Videos</a>
425 </li>
426 </ul>
427 </li>
428 <li class="list-none row-span-2">
429 <h2 class="text-base font-semibold tracking-wide">Company</h2>
430 <ul class="list-none space-y-4 md:space-y-1 px-0">
431 <li>
432 <a href="https://www.nwoods.com">Northwoods</a>
433 </li>
434 <li>
435 <a href="https://www.nwoods.com/about.html">About Us</a>
436 </li>
437 <li>
438 <a href="https://www.nwoods.com/contact.html">Contact Us</a>
439 </li>
440 <li>
441 <a href="https://twitter.com/northwoodsgo">Twitter</a>
442 </li>
443
444 </ul>
445 </li>
446 </ul>
447
448
449 <p class="text-sm text-gray-100 md:mb-6">
450 Copyright 1998-2021 <a class="text-white" href="https://www.nwoods.com">Northwoods Software</a>
451 </p>
452 </div>
453 </div>
454</footer> </body>
455
456<script async src="https://www.googletagmanager.com/gtag/js?id=UA-1506307-5"></script>
457<script>
458 window.dataLayer = window.dataLayer || [];
459 function gtag(){dataLayer.push(arguments);}
460 gtag('js', new Date()); gtag('config', 'UA-1506307-5');
461 var getOutboundLink = function(url, label) {
462 gtag('event', 'click', {
463 'event_category': 'outbound',
464 'event_label': label,
465 'transport_type': 'beacon'
466 });
467 }
468
469 // topnav
470 var topButton = document.getElementById("topnavButton");
471 var topnavList = document.getElementById("topnavList");
472 topButton.addEventListener("click", function() {
473 this.classList.toggle("active");
474 topnavList.classList.toggle("hidden");
475 document.getElementById("topnavOpen").classList.toggle("hidden");
476 document.getElementById("topnavClosed").classList.toggle("hidden");
477 });
478</script>
479 <script src="../assets/js/prism.js"></script>
480 <script src="../release/go.js"></script>
481 <script src="../assets/js/goDoc.js"></script>
482 <script>
483 document.addEventListener("DOMContentLoaded", function() {
484 if (window.go) document.getElementById('version').textContent = "GoJS version " + go.version;
485 if (window.goDoc) window.goDoc();
486 var d = window.diagrams;
487 for (var i = 0; i < d.length; i++) {
488 var dargs = d[i];
489 goCodeExecute(dargs[0], dargs[1], dargs[2], dargs[3], dargs[4]);
490 }
491 if (window.extra) window.extra();
492 });
493 </script>
494</html>