UNPKG

34.6 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 Layouts -- 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>Diagram Layouts</h1>
137<p>
138In general terms, a "layout" is a way of sizing and positioning a collection of objects.
139HTML has its own layouts for its HTML elements.
140In <b>GoJS</b> you have already seen many examples of Panel layout, such as Auto or Table,
141which sizes and positions <a>GraphObject</a>s within a <a>Panel</a>.
142<b>GoJS</b> also provides Diagram layouts, which position <a>Node</a>s and route <a>Link</a>s
143within a <a>Diagram</a> or a <a>Group</a>.
144</p>
145
146<p>
147Naturally the principal purpose of each diagram <a>Layout</a> is to position nodes, typically by calling <a>Part.move</a>.
148But layouts also may also result in custom routing of the links, by setting properties on each <a>Link</a>.
149For example <a>TreeLayout</a> also ensures that links are routed in the expected direction by setting
150<a>Link.fromSpot</a> and <a>Link.toSpot</a> depending on the <a>TreeLayout.angle</a>.
151(However, that behavior can be disabled by setting <a>TreeLayout.setsPortSpot</a> and <a>TreeLayout.setsChildPortSpot</a>.
152The same is true for some other layouts.)
153</p>
154
155<p>
156Diagram layouts can be accomplished in several manners.
157Manual layouts occur because the user moves nodes, thereby establishing new positions for those nodes.
158Such layouts might be saved in some persistent data format and later loaded using data binding or assignments in code.
159Programmatic layouts happen when some code executes to set the <a>Part</a> position or location.
160Automatic layouts are programmatic layouts that are implemented by the <a>Layout</a> class or its subclasses.
161</p>
162
163<h2 id="DefaultLayout">Default Layout</h2>
164<p>
165The value of <a>Diagram.layout</a> defaults to an instance of <a>Layout</a>.
166This kind of layout is unlike all of the other layout subclasses, in that it only sets the position of nodes
167that do not already have a position -- i.e. where the X or Y of the <a>GraphObject.actualBounds</a> is NaN.
168It leaves unmodified all nodes that do have a defined position, and it ignores all links.
169</p>
170
171<p>
172Many of the examples you have seen so far do not set <a>Diagram.layout</a> and thus use the default layout.
173Some of the examples data bind the <a>Part.location</a> or <a>GraphObject.position</a> to a data property.
174Those examples are basically using manual layout, but with the node positions coming from the node data rather than from
175arrangement by the user.
176</p>
177
178<p>
179However many of the examples just allow the standard behavior of the <a>Layout</a> class to assign positions to the nodes
180in the order in which they are seen by the layout.
181Those examples are exhibiting automatic layout behavior.
182</p>
183
184<h2 id="AutomaticLayouts">Automatic Layouts</h2>
185<p>
186<b>GoJS</b> offers several kinds of automatic layouts, including:
187</p>
188<ul>
189 <li><a>GridLayout</a></li>
190 <li><a>TreeLayout</a></li>
191 <li><a>ForceDirectedLayout</a></li>
192 <li><a>LayeredDigraphLayout</a></li>
193 <li><a>CircularLayout</a></li>
194</ul>
195
196<p>
197There are samples for each of these layouts, demonstrating the effects of setting various detailed layout properties:
198</p>
199<ul>
200 <li><a href="../samples/gLayout.html" target="samples">GridLayout Sample</a></li>
201 <li><a href="../samples/tLayout.html" target="samples">TreeLayout Sample</a></li>
202 <li><a href="../samples/fdLayout.html" target="samples">ForceDirectedLayout Sample</a></li>
203 <li><a href="../samples/ldLayout.html" target="samples">LayeredDigraphLayout Sample</a></li>
204 <li><a href="../samples/cLayout.html" target="samples">CircularLayout Sample</a></li>
205</ul>
206
207<p>
208In the introduction pages and samples you will see many examples that make use of automatic layout by setting the <a>Diagram.layout</a> property. <a href="https://github.com/NorthwoodsSoftware/GoJS/search?utf8=%E2%9C%93&amp;q=%22layout%3A+%26%28go%22&amp;type=Code">Search the sources of the samples for many more examples.</a>
209</p>
210
211<h3 id="LayoutUsage">Layout Usage</h3>
212
213<p>
214You can set <a>Diagram.layout</a> in a JavaScript statement:
215</p>
216<pre class="lang-js"><code>diagram.layout = new go.ForceDirectedLayout();</code></pre>
217<p>
218Or you can initialize that property using <a>GraphObject,make</a>:
219</p>
220<pre class="lang-js"><code>
221var diagram = $(go.Diagram, "myDiagramDiv",
222 {
223 layout: $(go.TreeLayout,
224 { angle: 90, nodeSpacing: 10, layerSpacing: 30 })
225 });
226</code></pre>
227<p>
228We recommend using <b>GraphObject.make</b> whenever you can because of the error checking that it does for property names.
229</p>
230
231<h3 id="GridLayout">Grid Layout</h3>
232
233<p>A simple layout for placing Nodes in a grid-like arrangement.</p>
234
235<pre class="lang-js" id="gridlayout" style="display: none;"><code>
236 diagram.layout = $(go.GridLayout);
237 diagram.contentAlignment = go.Spot.Center;
238
239 // define a simple Node template
240 diagram.nodeTemplate =
241 $(go.Node, "Spot", // the Shape will go around the TextBlock
242 $(go.Shape, "Ellipse",
243 { fill: 'palegreen', stroke: '#333', strokeWidth: 3, width: 40, height: 40 }
244 ),
245 $(go.TextBlock,
246 { margin: 3, font: 'bold 14px sans-serif', stroke: '#333' }, // some room around the text
247 // TextBlock.text is bound to Node.data.key
248 new go.Binding("text", "key"))
249 );
250
251diagram.linkTemplate =
252 $(go.Link,
253 // Default routing is go.Link.Normal
254 // Default corner is 0
255 { corner: 5 },
256 $(go.Shape, { strokeWidth: 3, stroke: "#333" })
257 );
258
259 // create the model data that will be represented by Nodes and Links
260 diagram.model = new go.GraphLinksModel(
261 [
262 { key: "1" },
263 { key: "2" },
264 { key: "3" },
265 { key: "4" },
266 { key: "5" },
267 { key: "6" },
268 { key: "7" },
269 { key: "8" },
270 { key: "9" },
271 { key: "10" },
272 { key: "11" },
273 ],
274 [
275 ]);
276</code></pre>
277<script>goCode("gridlayout", 400, 120)</script>
278
279<p>
280See the <a href="../samples/gLayout.html" target="samples">GridLayout Sample</a> for a demonstration of layout options.
281The <a href="../samples/swimlanes.html" target="samples">Swim Lanes</a> sample demonstrates a customization of <a>GridLayout</a>.
282See more samples that make use of <a>GridLayout</a> in the <a href="../samples/index.html#gridlayout">samples index</a>.
283</p>
284
285<h id="TreeLayout">Tree Layout</h>
286
287<p>This layout positions nodes of a tree-structured graph in layers (rows or columns).</p>
288
289<pre class="lang-js" id="treelayout" style="display: none;"><code>
290 diagram.layout = $(go.TreeLayout);
291 diagram.contentAlignment = go.Spot.Center;
292
293 // define a simple Node template
294 diagram.nodeTemplate =
295 $(go.Node, "Spot", // the Shape will go around the TextBlock
296 $(go.Shape, "Ellipse",
297 { fill: 'palegreen', stroke: '#333', strokeWidth: 3, width: 40, height: 40 }
298 ),
299 $(go.TextBlock,
300 { margin: 3, font: 'bold 14px sans-serif', stroke: '#333' }, // some room around the text
301 // TextBlock.text is bound to Node.data.key
302 new go.Binding("text", "key"))
303 );
304
305diagram.linkTemplate =
306 $(go.Link,
307 // Default routing is go.Link.Normal
308 // Default corner is 0
309 { corner: 5 },
310 $(go.Shape, { strokeWidth: 3, stroke: "#333" })
311 );
312
313 // create the model data that will be represented by Nodes and Links
314 diagram.model = new go.GraphLinksModel(
315 [
316 { key: "1" },
317 { key: "2" },
318 { key: "3" },
319 { key: "4" },
320 { key: "5" },
321 { key: "6" }
322 ],
323 [
324 { from: "1", to: "2" },
325 { from: "1", to: "3" },
326 { from: "3", to: "4" },
327 { from: "3", to: "5" },
328 { from: "3", to: "6" }
329 ]);
330</code></pre>
331<script>goCode("treelayout", 400, 200)</script>
332
333<p>
334See the <a href="../samples/tLayout.html" target="samples">TreeLayout sample</a> for a demonstration of layout options.
335The <a href="../samples/orgChartEditor.html" target="samples">Org Chart Editor</a>,
336<a href="../samples/parseTree.html" target="samples">Parse Tree</a>,
337<a href="../samples/swimBands.html" target="samples">Layer Bands</a>, and
338<a href="../samples/virtualizedTreeLayout.html" target="samples">Virtualized Tree</a>
339samples demonstrate customization of <a>TreeLayout</a>.
340See more samples that make use of <a>TreeLayout</a> in the <a href="../samples/index.html#treelayout">samples index</a>.
341</p>
342
343<h3 id="ForceDirectedLayout">Force-Directed Layout</h3>
344
345<p>Force-directed layout treats the graph as if it were a system of physical bodies with forces acting on them and between them.</p>
346
347<pre class="lang-js" id="fdlayout" style="display: none;"><code>
348 diagram.layout = $(go.ForceDirectedLayout);
349 diagram.initialAutoScale = go.Diagram.Uniform;
350 diagram.contentAlignment = go.Spot.Center;
351
352 // define a simple Node template
353 diagram.nodeTemplate =
354 $(go.Node, "Spot", // the Shape will go around the TextBlock
355 $(go.Shape, "Ellipse",
356 { fill: 'palegreen', stroke: '#333', strokeWidth: 3, width: 40, height: 40 }
357 ),
358 $(go.TextBlock,
359 { margin: 3, font: 'bold 14px sans-serif', stroke: '#333' }, // some room around the text
360 // TextBlock.text is bound to Node.data.key
361 new go.Binding("text", "key"))
362 );
363
364diagram.linkTemplate =
365 $(go.Link,
366 // Default routing is go.Link.Normal
367 // Default corner is 0
368 { corner: 5 },
369 $(go.Shape, { strokeWidth: 3, stroke: "#333" })
370 );
371
372 // create the model data that will be represented by Nodes and Links
373 diagram.model = new go.GraphLinksModel(
374 [
375 { key: "1" },
376 { key: "2" },
377 { key: "3" },
378 { key: "4" },
379 { key: "5" },
380 { key: "6" },
381 { key: "7" },
382 { key: "8" },
383 { key: "9" },
384 { key: "10" },
385 { key: "11" },
386 ],
387 [
388 { from: "6", to: "2" },
389 { from: "3", to: "4" },
390 { from: "3", to: "5" },
391 { from: "3", to: "6" },
392 { from: "6", to: "1" },
393 { from: "6", to: "7" },
394 { from: "4", to: "8" },
395 { from: "4", to: "9" },
396 { from: "4", to: "10" },
397 { from: "4", to: "11" },
398 ]);
399</code></pre>
400<script>goCode("fdlayout", 400, 200)</script>
401
402<p>
403See the <a href="../samples/fdLayout.html" target="samples">ForceDirectedLayout sample</a> for a demonstration of layout options.
404That sample also demonstrates a simple customization of <a>ForceDirectedLayout</a>.
405The <a href="../samples/virtualizedForceLayout.html" target="samples">Virtualized Force Directed</a> sample
406demonstrates a more complicated customization of <a>ForceDirectedLayout</a>.
407See more samples that make use of <a>ForceDirectedLayout</a> in the <a href="../samples/index.html#forcedirectedlayout">samples index</a>.
408</p>
409
410<h3 id="LayeredDigraphLayout">Layered Digraph Layout</h3>
411
412<p>This arranges nodes of directed graphs into layers (rows or columns).</p>
413
414<pre class="lang-js" id="ldllayout" style="display: none;"><code>
415 diagram.layout = $(go.LayeredDigraphLayout);
416 diagram.contentAlignment = go.Spot.Center;
417
418 // define a simple Node template
419 diagram.nodeTemplate =
420 $(go.Node, "Spot", // the Shape will go around the TextBlock
421 $(go.Shape, "Ellipse",
422 { fill: 'palegreen', stroke: '#333', strokeWidth: 3, width: 40, height: 40 }
423 ),
424 $(go.TextBlock,
425 { margin: 3, font: 'bold 14px sans-serif', stroke: '#333' }, // some room around the text
426 // TextBlock.text is bound to Node.data.key
427 new go.Binding("text", "key"))
428 );
429
430diagram.linkTemplate =
431 $(go.Link,
432 // Default routing is go.Link.Normal
433 // Default corner is 0
434 { corner: 5 },
435 $(go.Shape, { strokeWidth: 3, stroke: "#333" })
436 );
437
438 // create the model data that will be represented by Nodes and Links
439 diagram.model = new go.GraphLinksModel(
440 [
441 { key: "1" },
442 { key: "2" },
443 { key: "3" },
444 { key: "4" },
445 { key: "5" },
446 { key: "6" },
447 { key: "7" },
448 ],
449 [
450 { from: "1", to: "2" },
451 { from: "1", to: "3" },
452 { from: "3", to: "4" },
453 { from: "3", to: "5" },
454 { from: "3", to: "6" },
455 { from: "2", to: "5" },
456 { from: "1", to: "5" },
457 { from: "1", to: "7" },
458 { from: "6", to: "7" },
459 ]);
460</code></pre>
461<script>goCode("ldllayout", 400, 300)</script>
462
463<p>
464See the <a href="../samples/ldLayout.html" target="samples">LayeredDigraphLayout sample</a> for a demonstration of layout options.
465The <a href="../samples/genogram.html" target="samples">Genogram</a> sample demonstrates a complex customization of <a>LayeredDigraphLayout</a>.
466See more samples that make use of <a>LayeredDigraphLayout</a> in the <a href="../samples/index.html#layereddigraphlayout">samples index</a>.
467</p>
468
469<h3 id="CircularLayout">Circular Layout</h3>
470
471<p>This layout positions nodes in a circular or elliptical arrangement.</p>
472
473<pre class="lang-js" id="circularLayout" style="display: none;"><code>
474 diagram.layout = $(go.CircularLayout);
475 diagram.contentAlignment = go.Spot.Center;
476
477 // define a simple Node template
478 diagram.nodeTemplate =
479 $(go.Node, "Spot", // the Shape will go around the TextBlock
480 $(go.Shape, "Ellipse",
481 { fill: 'palegreen', stroke: '#333', strokeWidth: 3, width: 40, height: 40 }
482 ),
483 $(go.TextBlock,
484 { margin: 3, font: 'bold 14px sans-serif', stroke: '#333' }, // some room around the text
485 // TextBlock.text is bound to Node.data.key
486 new go.Binding("text", "key"))
487 );
488
489diagram.linkTemplate =
490 $(go.Link,
491 // Default routing is go.Link.Normal
492 // Default corner is 0
493 { corner: 5 },
494 $(go.Shape, { strokeWidth: 3, stroke: "#333" })
495 );
496
497 // create the model data that will be represented by Nodes and Links
498 diagram.model = new go.GraphLinksModel(
499 [
500 { key: "1" },
501 { key: "2" },
502 { key: "3" },
503 { key: "4" },
504 { key: "5" },
505 { key: "6" },
506 { key: "7" },
507 ],
508 [
509 { from: "1", to: "2" },
510 { from: "1", to: "3" },
511 { from: "3", to: "4" },
512 { from: "3", to: "5" },
513 { from: "3", to: "6" },
514 { from: "2", to: "5" },
515 { from: "1", to: "5" },
516 { from: "1", to: "7" },
517 { from: "6", to: "7" },
518 ]);
519</code></pre>
520<script>goCode("circularLayout", 400, 200)</script>
521
522<p>
523See the <a href="../samples/cLayout.html" target="samples">CircularLayout sample</a> for a demonstration of layout options.
524The <a href="../samples/friendWheel.html" target="samples">Friend Wheel</a> sample demonstrates a simple customization of <a>CircularLayout</a>.
525See more samples that make use of <a>CircularLayout</a> in the <a href="../samples/index.html#circularlayout">samples index</a>.
526</p>
527
528
529<h3 id="CustomLayouts">Custom Layouts</h3>
530
531<p>
532 GoJS allows for the creation of custom layouts.
533 The intro page on <a href="extensions.html">GoJS extensions</a> gives a simple example of a custom layout.
534 See more samples that make use of custom layouts in the <a href="../samples/index.html#customlayout">samples index</a>.
535</p>
536<p>
537 There are also many layouts that are extensions -- not predefined in the <code>go.js</code> or <code>go-debug.js</code> library,
538 but available as source code in one of the three extension directories, with some documentation, and with corresponding samples.
539</p>
540<ul>
541 <li><a>DoubleTreeLayout</a>: sample at <a href="../samples/doubleTree.html" target="samples">DoubleTreeLayout Sample</a>, defined in <a href="../extensions/DoubleTreeLayout.js">DoubleTreeLayout.js</a></li>
542 <li><a>FishboneLayout</a>: sample at <a href="../extensions/Fishbone.html" target="samples">FishboneLayout Sample</a>, defined in <a href="../extensions/FishboneLayout.js">FishboneLayout.js</a></li>
543 <li><a>PackedLayout</a>: sample at <a href="../extensions/PackedLayout.html" target="samples">PackedLayout Sample</a>, defined in <a href="../extensionsTS/PackedLayout.js">PackedLayout.js</a></li>
544 <li><a>ParallelLayout</a>: sample at <a href="../extensions/Parallel.html" target="samples">ParallelLayout Sample</a>, defined in <a href="../extensions/ParallelLayout.js">ParallelLayout.js</a></li>
545 <li><a>SepentineLayout</a>: sample at <a href="../extensions/Serpentine.html" target="samples">SerpentineLayout Sample</a>, defined in <a href="../extensions/SerpentineLayout.js">SerpentineLayout.js</a></li>
546 <li><a>SpiralLayout</a>: sample at <a href="../extensions/Spiral.html" target="samples">SpiralLayout Sample</a>, defined in <a href="../extensions/SpiralLayout.js">SpiralLayout.js</a></li>
547 <li><a>SwimLaneLayout</a>: sample at <a href="../extensions/SwimLaneLayout.html" target="samples">SwimLaneLayout Sample</a>, defined in <a href="../extensionsTS/SwimLaneLayout.js">SwimLaneLayout.js</a></li>
548 <li><a>TableLayout</a>: sample at <a href="../extensions/Table.html" target="samples">TableLayout Sample</a>, defined in <a href="../extensions/TableLayout.js">TableLayout.js</a></li>
549 <li><a>TreeMapLayout</a>: sample at <a href="../extensions/TreeMap.html" target="samples">TreeMapLayout Sample</a>, defined in <a href="../extensions/TreeMapLayout.js">TreeMapLayout.js</a></li>
550</ul>
551
552
553<h2 id="LayoutInvalidation">Layout Invalidation</h2>
554<p>
555A layout is considered "valid" when it has performed its positioning of its nodes and perhaps routed its links.
556However some kinds of changes cause a layout to become "invalid", thereby causing it to be performed again in the near future.
557Because layouts can be computationally expensive, automatic layouts are not performed as soon as a layout is invalidated.
558Instead they are typically performed at the end of a transaction.
559</p>
560<p>
561The most common reasons for a layout to be invalidated are because a node or a link has been added or removed from the collection
562of nodes and links that a layout is responsible for, or because a node or a link has changed visibility, or because a node has changed size.
563If you do not want an automatic layout to happen when such a change occurs, it may be easiest to set <a>Layout.isOngoing</a> to false.
564</p>
565<p>
566Another common situation is where you have set <a>Diagram.layout</a> to some kind of layout but you want to load a diagram (model)
567that contains manually positioned or adjusted node locations. The <a>Binding</a> of <a>Part.location</a> to the model data is effective,
568but the locations are lost when a layout is performed immediately after loading. This situation can be avoided by setting
569<a>Layout.isInitial</a> to false. After the initial layout the layout might still be invalidated by adding or removing or changing
570the visibility of a node or a link or by a change in node size, unless you have also set <a>Layout.isOngoing</a> to false.
571When both <a>Layout.isInitial</a> and <a>Layout.isOngoing</a> are false, you can still explicitly cause a layout to happen by either
572calling <a>Layout.invalidateLayout</a> or by calling <a>Diagram.layoutDiagram</a> with a <code>true</code> argument.
573</p>
574<p>
575For example, in editors it is commonplace to have TwoWay Bindings on <a>Node.location</a> to save manually adjusted node locations.
576This means that saved models will have saved locations for all of the nodes.
577But if you create a new model without all of the node data objects having real locations,
578you will want a layout to be performed initially when the model is loaded.
579You can accomplish this by setting <a>Layout.isInitial</a> to false
580(and optionally <a>Layout.isOngoing</a> to false, if that is what you want when users add or remove nodes or links)
581and then implementing an "InitialLayoutCompleted" <a>DiagramEvent</a> listener that decides whether a layout is needed.
582The decision could be to look at a flag that you add to the <a>Model.modelData</a>.
583Or you could look at all of the nodes to make sure their locations have real values:
584</p>
585<pre class="lang-js"><code>
586$(go.Diagram, . . .,
587 {
588 . . .,
589 layout: $(go.TreeLayout, { isInitial: false, isOngoing: false }, . . .),
590 "InitialLayoutCompleted": function(e) {
591 // if not all Nodes have real locations, force a layout to happen
592 if (!e.diagram.nodes.all(function(n) { return n.location.isReal(); })) {
593 e.diagram.layoutDiagram(true);
594 }
595 }
596 })
597</code></pre>
598<p>
599But if you do not want a change to a particular Node or Link to cause an automatic layout, yet you do want that invalidation for other Nodes or Links,
600you can set the <a>Part.layoutConditions</a> property to the combination of <a>Part</a> "Layout..." flags that suits your needs.
601It is most common to not want a layout for the <a>Part,LayoutNodeSized</a> condition:
602</p>
603<pre class="lang-js"><code>
604 $(go.Node, . . .,
605 { layoutConditions: go.Part.LayoutStandard & ~go.Part.LayoutNodeSized },
606 . . .
607 )
608</code></pre>
609<p>
610Parts that remain not visible or that are in layers that are <a>Layer.isTemporary</a> also never invalidate any Layout.
611</p>
612<p>
613Finally, you can set <a>Part.isLayoutPositioned</a> to false in order for the Layout to completely ignore that Part.
614But you will have to make sure that that Part does have a real <a>Part.location</a>, since no layout will set it for you.
615Without a real location the part will not be visible anywhere in the diagram.
616Furthermore if a node has isLayoutPositioned set to false, Layouts will not only ignore that node but also all links connecting with that node.
617Because the node will not be moved by the layout, it might overlap with the laid-out nodes and links.
618You can also set or bind <a>Part.isLayoutPositioned</a> to false on Links in order to have the layout ignore those links.
619This is demonstrated in <a href="../samples/orgChartExtras.html" target="samples">Org Chart Extras</a>.
620</p>
621
622 </div>
623 </div>
624
625 <div class="bg-nwoods-primary">
626 <section class="max-w-screen-lg text-white container mx-auto py-2 px-12">
627 <p id="version" class="leading-none mb-2 my-4">GoJS</p>
628 </section>
629 </div><footer class="bg-nwoods-primary text-white">
630 <div class="container max-w-screen-lg mx-auto px-8">
631 <div class="w-full py-6">
632
633 <div class="max-w-screen-lg xl:max-w-screen-xl mx-auto px-4 sm:px-6 md:px-8">
634 <ul class="text-sm font-medium pb-14 sm:pb-20 grid grid-cols-1 sm:grid-cols-3 gap-y-10">
635 <li class="list-none row-span-2">
636 <h2 class="text-base font-semibold tracking-wide">GoJS</h2>
637 <ul class="list-none space-y-4 md:space-y-1 px-0">
638 <li>
639 <a href="../samples/index.html">Samples</a>
640 </li>
641 <li>
642 <a href="../learn/index.html">Learn</a>
643 </li>
644 <li>
645 <a href="../intro/index.html">Intro</a>
646 </li>
647 <li>
648 <a href="../api/index.html">API</a>
649 </li>
650 <li>
651 <a href="../changelog.html">Changelog</a>
652 </li>
653 <li>
654 <a href="https://github.com/NorthwoodsSoftware/GoJS">GitHub</a>
655 </li>
656 </ul>
657 </li>
658 <li class="list-none row-span-2">
659 <h2 class="text-base font-semibold tracking-wide">Support</h2>
660 <ul class="list-none space-y-4 md:space-y-1 px-0">
661 <li>
662 <a href="https://www.nwoods.com/contact.html"
663 target="_blank" rel="noopener" onclick="getOutboundLink('https://www.nwoods.com/contact.html', 'contact');">Contact</a>
664 </li>
665 <li>
666 <a href="https://forum.nwoods.com/c/gojs">Forum</a>
667 </li>
668 <li>
669 <a href="https://www.nwoods.com/app/activate.aspx?sku=gojs">Activate</a>
670 </li>
671 <li>
672 <a href="https://www.nwoods.com/sales/index.html"
673 target="_blank" rel="noopener" onclick="getOutboundLink('https://www.nwoods.com/sales/index.html', 'buy');">Buy</a>
674 </li>
675 <li>
676 <a href="https://www.youtube.com/channel/UC9We8EoX596-6XFjJDtZIDg">Videos</a>
677 </li>
678 </ul>
679 </li>
680 <li class="list-none row-span-2">
681 <h2 class="text-base font-semibold tracking-wide">Company</h2>
682 <ul class="list-none space-y-4 md:space-y-1 px-0">
683 <li>
684 <a href="https://www.nwoods.com">Northwoods</a>
685 </li>
686 <li>
687 <a href="https://www.nwoods.com/about.html">About Us</a>
688 </li>
689 <li>
690 <a href="https://www.nwoods.com/contact.html">Contact Us</a>
691 </li>
692 <li>
693 <a href="https://twitter.com/northwoodsgo">Twitter</a>
694 </li>
695
696 </ul>
697 </li>
698 </ul>
699
700
701 <p class="text-sm text-gray-100 md:mb-6">
702 Copyright 1998-2021 <a class="text-white" href="https://www.nwoods.com">Northwoods Software</a>
703 </p>
704 </div>
705 </div>
706</footer> </body>
707
708<script async src="https://www.googletagmanager.com/gtag/js?id=UA-1506307-5"></script>
709<script>
710 window.dataLayer = window.dataLayer || [];
711 function gtag(){dataLayer.push(arguments);}
712 gtag('js', new Date()); gtag('config', 'UA-1506307-5');
713 var getOutboundLink = function(url, label) {
714 gtag('event', 'click', {
715 'event_category': 'outbound',
716 'event_label': label,
717 'transport_type': 'beacon'
718 });
719 }
720
721 // topnav
722 var topButton = document.getElementById("topnavButton");
723 var topnavList = document.getElementById("topnavList");
724 topButton.addEventListener("click", function() {
725 this.classList.toggle("active");
726 topnavList.classList.toggle("hidden");
727 document.getElementById("topnavOpen").classList.toggle("hidden");
728 document.getElementById("topnavClosed").classList.toggle("hidden");
729 });
730</script>
731 <script src="../assets/js/prism.js"></script>
732 <script src="../release/go.js"></script>
733 <script src="../assets/js/goDoc.js"></script>
734 <script>
735 document.addEventListener("DOMContentLoaded", function() {
736 if (window.go) document.getElementById('version').textContent = "GoJS version " + go.version;
737 if (window.goDoc) window.goDoc();
738 var d = window.diagrams;
739 for (var i = 0; i < d.length; i++) {
740 var dargs = d[i];
741 goCodeExecute(dargs[0], dargs[1], dargs[2], dargs[3], dargs[4]);
742 }
743 if (window.extra) window.extra();
744 });
745 </script>
746</html>