create-gojs-kit
Version:
A CLI for downloading GoJS samples, extensions, and docs
741 lines (675 loc) • 26.3 kB
HTML
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, viewport-fit=cover"/>
<link rel="preconnect" href="https://rsms.me/">
<link rel="stylesheet" href="../assets/css/style.css">
<!-- Copyright 1998-2025 by Northwoods Software Corporation. -->
<meta itemprop="name" content="Collections" />
<meta property="og:title" content="Collections" />
<meta name="twitter:title" content="Collections" />
<meta property="og:image" content="https://gojs.net/latest/assets/images/fp/defaultCard.png" />
<meta itemprop="image" content="https://gojs.net/latest/assets/images/fp/defaultCard.png" />
<meta name="twitter:image" content="https://gojs.net/latest/assets/images/fp/defaultCard.png" />
<meta property="og:url" content="https://gojs.net/latest/intro/collections.html" />
<meta property="twitter:url" content="https://gojs.net/latest/intro/collections.html" />
<meta name="twitter:card" content="summary_large_image" />
<meta property="og:type" content="website" />
<meta property="twitter:domain" content="gojs.net" />
<title>
Collections | GoJS
</title>
<link rel="stylesheet" href="../assets/css/prism.css"/>
</head>
<script>
window.diagrams = [];
window.goCode = function (pre, w, h, parentid, animation) {
window
.diagrams
.push([pre, w, h, parentid, animation]);
}
</script>
<body>
<nav id="navTop" class=" w-full h-[var(--topnav-h)] z-30 bg-white border-b border-b-gray-200">
<div class="max-w-screen-xl mx-auto flex flex-wrap items-start justify-between px-4">
<a class="text-white bg-nwoods-primary font-bold !leading-[calc(var(--topnav-h)_-_1px)] my-0 px-2 text-4xl lg:text-5xl logo"
href="../">
GoJS
</a>
<div class="relative">
<button id="topnavButton" class="h-[calc(var(--topnav-h)_-_1px)] px-2 m-0 text-gray-900 bg-inherit shadow-none md:hidden hover:!bg-inherit hover:!text-nwoods-accent hover:!shadow-none" aria-label="Navigation">
<svg class="h-7 w-7 block" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
<path d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</button>
<div id="topnavList" class="hidden md:block">
<div class="absolute right-0 z-30 flex flex-col items-end rounded border border-gray-200 p-4 pl-12 shadow bg-white text-gray-900 font-semibold
md:flex-row md:space-x-4 md:items-start md:border-0 md:p-0 md:shadow-none md:bg-inherit">
<a href="../learn/">Learn</a>
<a href="../samples/">Samples</a>
<a href="../intro/">Intro</a>
<a href="../api/">API</a>
<a href="../download.html">Download</a>
<a href="https://forum.nwoods.com/c/gojs/11" target="_blank" rel="noopener">Forum</a>
<a id="tc" href="https://nwoods.com/contact.html"
target="_blank" rel="noopener" onclick="getOutboundLink('https://nwoods.com/contact.html', 'contact');">Contact</a>
<a id="tb" href="https://nwoods.com/sales/index.html"
target="_blank" rel="noopener" onclick="getOutboundLink('https://nwoods.com/sales/index.html', 'buy');">Buy</a>
</div>
</div>
</div>
</div>
</nav>
<script>
window.addEventListener("DOMContentLoaded", function () {
// topnav
var topButton = document.getElementById("topnavButton");
var topnavList = document.getElementById("topnavList");
if (topButton && topnavList) {
topButton.addEventListener("click", function (e) {
topnavList
.classList
.toggle("hidden");
e.stopPropagation();
});
document.addEventListener("click", function (e) {
// if the clicked element isn't the list, close the list
if (!topnavList.classList.contains("hidden") && !e.target.closest("#topnavList")) {
topButton.click();
}
});
// set active <a> element
var url = window
.location
.href
.toLowerCase();
var aTags = topnavList.getElementsByTagName('a');
for (var i = 0; i < aTags.length; i++) {
var lowerhref = aTags[i]
.href
.toLowerCase();
if (lowerhref.endsWith('.html'))
lowerhref = lowerhref.slice(0, -5);
if (url.startsWith(lowerhref)) {
aTags[i]
.classList
.add('active');
break;
}
}
}
});
</script>
<div class="sticky top-0 left-0 z-10 px-2 w-full bg-white border-b border-b-gray-200 md:hidden">
<button id="sidenavButton" class="flex p-2 text-gray-900 bg-inherit shadow-none items-center text-sm font-semibold hover:!bg-inherit hover:!text-nwoods-accent hover:!shadow-none" aria-label="Navigation">
<svg class="h-7 w-7 block mr-2" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
<path d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
<span>Menu</span>
</button>
</div>
<script>
window.addEventListener("DOMContentLoaded", function () {
// sidenav
var sideButton = document.getElementById("sidenavButton");
var sidenav = document.getElementById("sidenav");
if (sideButton && sidenav) {
sideButton.addEventListener("click", function (e) {
sidenav
.classList
.toggle("hidden");
e.stopPropagation();
});
document.addEventListener("click", function (e) {
// if the clicked element isn't the list, close the list
if (!sidenav.classList.contains("hidden") && !e.target.closest("#sidenavList")) {
sideButton.click();
}
});
}
});
</script>
<div class="flex flex-row md:min-h-screen w-full max-w-screen-xl mx-auto">
<aside id="sidenav"
class="hidden fixed top-0 left-0 z-10 w-full bg-black/10 min-h-screen max-h-screen overflow-x-hidden overflow-y-auto shrink-0
md:block md:sticky md:w-52 md:min-h-0 md:bg-inherit md:border-r md:border-r-gray-200 md:overscroll-auto">
<nav id="sidenavList" class="flex flex-col bg-white w-52 min-h-screen pl-2 pt-4 pb-24 md:w-full md:min-h-0">
<a href="index.html">Basics</a>
<a href="buildingObjects.html">Building Parts</a>
<a href="usingModels.html">Using Models</a>
<a href="dataBinding.html">Data Binding</a>
<a href="react.html">GoJS with React</a>
<a href="svelte.html">GoJS with Svelte</a>
<a href="angular.html">GoJS with Angular</a>
<a href="textBlocks.html">TextBlocks</a>
<a href="shapes.html">Shapes</a>
<a href="pictures.html">Pictures</a>
<a href="panels.html">Panels</a>
<a href="tablePanels.html">Table Panels</a>
<a href="brush.html">Brushes</a>
<a href="sizing.html">Sizing Objects</a>
<a href="itemArrays.html">Item Arrays</a>
<a href="changedEvents.html">Changed Events</a>
<a href="transactions.html">Transactions</a>
<a href="viewport.html">Coordinates</a>
<a href="initialView.html">Initial View</a>
<a href="collections.html">Collections</a>
<a href="links.html">Links</a>
<a href="linkLabels.html">Link Labels</a>
<a href="connectionPoints.html">Link Points</a>
<a href="ports.html">Ports</a>
<a href="nodes.html">Nodes</a>
<a href="typings.html">Typings</a>
<a href="debugging.html">Debugging</a>
<a href="layouts.html">Layouts</a>
<a href="routers.html">Routers</a>
<a href="trees.html">Trees</a>
<a href="subtrees.html">SubTrees</a>
<a href="groups.html">Groups</a>
<a href="subgraphs.html">SubGraphs</a>
<a href="sizedGroups.html">Sized Groups</a>
<a href="selection.html">Selection</a>
<a href="highlighting.html">Highlighting</a>
<a href="theming.html">Theming</a>
<a href="tooltips.html">ToolTips</a>
<a href="contextMenus.html">Context Menus</a>
<a href="events.html">Diagram Events</a>
<a href="tools.html">Tools</a>
<a href="commands.html">Commands</a>
<a href="accessibility.html">Accessibility</a>
<a href="buttons.html">Buttons</a>
<a href="permissions.html">Permissions</a>
<a href="validation.html">Validation</a>
<a href="animation.html">Animation</a>
<a href="HTMLInteraction.html">HTML Interaction</a>
<a href="layers.html">Layers & Z-ordering</a>
<a href="palette.html">Palette</a>
<a href="overview.html">Overview</a>
<a href="replacingDeleting.html">Replacing and Deleting</a>
<a href="templateMaps.html">Template Maps</a>
<a href="legends.html">Legends and Titles</a>
<a href="extensions.html">Extensions</a>
<a href="geometry.html">Geometry Strings</a>
<a href="grids.html">Grid Patterns</a>
<a href="graduatedPanels.html">Graduated Panels</a>
<a href="SVGContext.html">Rendering to SVG</a>
<a href="makingSVG.html">Snapshot to SVG</a>
<a href="makingImages.html">Diagram Images</a>
<a href="printing.html">Printing</a>
<a href="serverSideImages.html">Server-side Images</a>
<a href="nodeScript.html">GoJS in Node.js</a>
<a href="testing.html">Testing</a>
<a href="performance.html">Performance</a>
<a href="platforms.html">Platforms</a>
<a href="deployment.html">Deployment</a>
</nav>
</aside>
<script>
var navList = document.getElementById('sidenavList');
if (navList !== null) {
var url = window.location.href;
var lindex = url.lastIndexOf('/');
url = url
.slice(lindex + 1)
.toLowerCase();
var aTags = navList.getElementsByTagName('a');
var currentindex = -1;
for (var i = 0; i < aTags.length; i++) {
var lowerhref = aTags[i]
.href
.toLowerCase();
if (lowerhref.indexOf('/' + url) !== -1) {
currentindex = i;
aTags[i]
.classList
.add('active');
break;
}
}
}
</script>
<div class="px-4 pb-16 w-full overflow-hidden prose">
<h1>Collections</h1>
<p>
<b>GoJS</b> provides its own collection classes: <a>List</a>, <a>Set</a>, and <a>Map</a>.
The latter two are very similar to the ECMAScript <b>Set</b> and <b>Map</b> classes,
but iteration is quite different, using an <a>Iterator</a> instead of the ECMAScript <b>Iterator</b> protocol.
</p>
<p>
These collection classes have several advantages over using JavaScript arrays as lists or objects as maps.
They can be made read-only to avoid undesired modifications.
If you are writing in TypeScript, they optionally enforce compile-time type checking of the item types.
</p>
<p>
In <b>GoJS</b> most of the properties and methods that return collections describing the structure of the diagram return an <a>Iterator</a>.
That is because the implementation of the collections are internal -- you only need to know how to iterate over the result collection.
Other methods or properties will allow you to modify the diagram.
An example is <a>Diagram.nodes</a>, which returns the current collection of <a>Node</a>s and <a>Group</a>s in the diagram as an <a>Iterator</a>.
The collection is automatically modified as the programmer adds or removes node data in the model or by direct calls to
<a>Diagram.add</a> or <a>Diagram.remove</a>.
</p>
<p>
However there are a few properties that return collections that are allowed to be modified.
Examples include collections on classes that are usually frozen after initialization:
<a>Geometry.figures</a>, <a>PathFigure.segments</a>, and <a>Brush.colorStops</a>.
Other examples include collections that are modified very infrequently, usually only upon diagram initialization:
<a>ToolManager.mouseDownTools</a> (and the other lists of tools) and <a>Diagram.nodeTemplateMap</a>
(and other template maps).
</p>
<p>
See samples that make use of collections in the <a href="../samples/index.html#collections">samples index</a>.
</p>
<h2 id="List">List</h2>
<p>
A <a>List</a> is an ordered collection of values that are indexed by integers from zero to one less than the <a>List.count</a>.
</p>
<pre class="lang-js"><code>
const l = new go.List();
l.add("A");
l.add("B");
l.add("C");
assert(l.count === 3);
assert(l.elt(0) === "A");
assert(l.has("B"));
assert(l.indexOf("B") === 1);
l.setElt(1, "z"); // replace an item
assert(l.elt(1) === "z");
l.removeAt(1); // remove an item
assert(l.count === 2);
assert(l.elt(1) === "C");
</code></pre>
<p>
However, if you are writing in TypeScript, GoJS collections classes (<code>List</code>, <code>Map</code>, <code>Set</code>) are now generic, and will help you enforce types:
</p>
<pre class="lang-ts"><code>
// TypeScript:
const l = new go.List<string>(); // Create a list of only strings
l.add("A");
l.add(23); // produces an error during compilation or highlights it in an IDE
l.add({}); // produces an error during compilation or highlights it in an IDE
</code></pre>
<p>
To iterate over a <a>List</a>, get its <a>List.iterator</a> and call <a>Iterator.next</a>
on it to advance its position in the list. Its <a>Iterator.value</a> will be a list item;
its <a>Iterator.key</a> will be the corresponding index in the list. Or, more commonly,
just call <a>List.each</a>.
</p>
<pre class="lang-js"><code>
const l = new go.List();
l.add("A");
l.add("B");
l.add("C");
const it = l.iterator;
while (it.next()) {
console.log(it.key + ": " + it.value);
}
// This outputs:
// 0: A
// 1: B
// 2: C
// Or, if you just want to iterate over the items in the list:
l.each(item => console.log(item));
</code></pre>
<h2 id="Set">Set</h2>
<p>
A <a>Set</a> is an unordered collection of values that does not allow duplicate values.
This class is similar to the <code>Set</code> object that is defined in ECMAScript 2015 (ES6).
</p>
<pre class="lang-js"><code>
const s = new go.Set();
s.add("A");
s.add("B");
s.add("C");
s.add("B"); // duplicate is ignored
assert(s.count === 3);
assert(s.has("B"));
s.delete("B"); // remove an item
assert(s.count === 2);
assert(!s.has("B"));
</code></pre>
<p>
When writing TypeScript, it is a generic class so that the compiler can enforce types:
</p>
<pre class="lang-ts"><code>
// TypeScript:
const s = new go.Set<string>(); // Create a set of only strings
s.add("A");
s.add(23); // produces an error during compilation or highlights it in an IDE
s.add({}); // produces an error during compilation or highlights it in an IDE
</code></pre>
<p>
Iterating over the items in a <a>Set</a> is just like iterating over a <a>List</a>,
except that the order of the items may vary.
</p>
<pre class="lang-js"><code>
const s = new go.Set();
s.add("A");
s.add("B");
s.add("C");
s.add("B"); // duplicate is ignored
const it = s.iterator;
while (it.next()) {
console.log(it.value);
}
// This might output, perhaps in different order:
// A
// B
// C
// Or, equivalent code using Set.each:
s.each(item => console.log(item));
</code></pre>
<p>
Furthermore, as of version 3, <a>Set</a> implements the ECMAScript <b>Iterable</b> protocol,
by defining the <code>[Symbol.iterator]</code> property.
This allows using the <code>for (let item of set) ...</code> statement.
</p>
<pre class="lang-js"><code>
const s = new go.Set();
s.add("A");
s.add("B");
s.add("C");
// iteration using for ... of:
for (let item of s) console.log(item);
</code></pre>
<p>
Thus <a>Set</a>s can be used with spread syntax. For example:
</p>
<pre class="lang-js"><code>
const s = new go.Set();
s.add("A");
s.add("B");
s.add("C");
const arr = [...set, "Z"];
// which is an Array of length 4: ["A", "B", "C", "Z"]
</code></pre>
<h2 id="Map">Map</h2>
<p>
A <a>Map</a> is an unordered collection of key-value pairs that are indexed by the keys.
This class is similar to the <code>Map</code> object that is defined in ECMAScript 2015 (ES6).
</p>
<pre class="lang-js"><code>
const m = new go.Map();
m.set("A", 1); // associate "A" with 1
m.set("B", 2);
m.set("C", 3);
assert(s.count === 3);
assert(s.has("B"));
assert(s.get("B") === 2);
m.set("B", 222); // replace the value for "B"
assert(s.get("B") === 222);
s.delete("B"); // remove an item
assert(s.count === 2);
assert(!s.has("B"));
assert(s.get("B") === null);
</code></pre>
<p>
When writing TypeScript, it is a generic class so that the compiler can enforce types:
</p>
<pre class="lang-ts"><code>
// TypeScript:
const m = new go.Map<string, number>(); // Create a map of strings to numbers
m.set("A", 1);
m.set(23, 23); // produces an error during compilation or highlights it in an IDE
m.set({}, 23); // produces an error during compilation or highlights it in an IDE
</code></pre>
<p>
Iterating over the items in a <a>Map</a> is just like iterating over a <a>List</a>,
but offering access to both the keys and the values.
As with <a>Set</a>s the order of the items may vary.
</p>
<pre class="lang-js"><code>
const m = new go.Map();
m.set("A", 1); // associate "A" with 1
m.set("B", 2);
m.set("C", 3);
m.set("B", 222); // replace the value for "B"
// Normal iteration lets you get both the key and its corresponding value:
const it = m.iterator;
while (it.next()) {
console.log(it.key + ": " + it.value);
}
// This might output, perhaps in different order:
// A: 1
// B: 222
// C: 3
// Or, equivalently using Map.each:
m.each(kvp => console.log(kvp.key + ": " + kvp.value));
// To get a collection of the keys, use Map.iteratorKeys:
const kit = m.iteratorKeys;
while (kit.next()) {
console.log(kit.value);
}
// This might output, perhaps in different order:
// A
// B
// C
// To get a collection of the values, use Map.iteratorValues:
const vit = m.iteratorValues;
while (vit.next()) {
console.log(vit.value);
}
// This might output, perhaps in different order:
// 1
// 222
// 3
</code></pre>
<p>
Typically one uses <a>Map.iteratorKeys</a> or <a>Map.iteratorValues</a>
when needing to pass a collection on to other methods that take an <a>Iterator</a>.
</p>
<p>
As of version 3, <a>Map</a> implements the ECMAScript <b>Iterable</b> protocol,
by defining the <code>[Symbol.iterator]</code> property.
This allows using the <code>for (let item of map) ...</code> statement.
</p>
<pre class="lang-js"><code>
const m = new go.Map();
m.add("A", 1); // associate "A" with 1
m.add("B", 2);
m.add("C", 3);
m.add("B", 222); // replace the value for "B"
// ECMAScript iteration over the key and value pairs:
for (let kvp of map) console.log(`${kvp[0]}: ${kvp[1]}`);
// This might output, perhaps in different order:
// A: 1
// B: 222
// C: 3
for (let k of map.iteratorKeys) console.log(k);
// This might output, perhaps in different order:
// A
// B
// C
for (let v of map.iteratorValues) console.log(v);
// This might output, perhaps in different order:
// 1
// 222
// 3
</code></pre>
<h2 id="MoreIterationExamples">More Iteration Examples</h2>
<p>
It is commonplace to iterate over the selected <a>Part</a>s of a <a>Diagram</a>:
<pre class="lang-js"><code>
for (let part of diagram.selection) {
// part is now a Node or a Group or a Link or maybe a simple Part
if (part instanceof go.Node) { . . . }
else if (part instanceof go.Link) { . . . }
}
</code></pre>
Alternatively:
<pre class="lang-js"><code>
diagram.selection.each(part => {
// part is now a Node or a Group or a Link or maybe a simple Part
if (part instanceof go.Node) { . . . }
else if (part instanceof go.Link) { . . . }
});
</code></pre>
</p>
<p>
Sometimes one needs to iterate over the <a>Node</a>s in a <a>Diagram</a>:
<pre class="lang-js"><code>
for (let n of diagram.nodes) {
// n is now a Node or a Group
if (n.category === "Special") { . . . }
}
</code></pre>
</p>
<p>
You can also iterate over the port elements in a <a>Node</a>, or the <a>Link</a>s connected to a port element:
<pre class="lang-js"><code>
for (let port of node.ports) {
// port is now a GraphObject within the Node
for (let link of node.findLinksConnected(port.portId)) {
// link is now a Link connected with the port
if (link.data.xyz === 17) { . . . }
}
}
</code></pre>
</p>
<p>
Or perhaps you need to iterate over the elements of a <a>Panel</a>:
<pre class="lang-js"><code>
for (let elt of panel.elements) {
// elt is now a GraphObject that is an immediate child of the Panel
if (elt instanceof go.TextBlock) { . . . }
else if (elt instanceof go.Panel) { . . . recurse . . . }
}
</code></pre>
</p>
<p>
If you want to find <a>Node</a>s that are immediate members of a <a>Group</a>:
<pre class="lang-js"><code>
for (let part of group.memberParts) {
// part is now a Part within the Group
if (part instanceof go.Node) { . . . maybe work with part.data . . . }
}
</code></pre>
</p>
</div>
</div>
<footer class="bg-white text-gray-900 border-t border-t-gray-200">
<div class="w-full max-w-screen-lg mx-auto px-4 py-6">
<p id="version" class="text-xs text-gray-900 m-0"></p>
<div class="text-sm px-0 mb-4 grid grid-cols-2 sm:grid-cols-3 gap-y-10">
<div>
<h2 class="text-base font-semibold text-nwoods-primary">GoJS</h2>
<ul class="list-none space-y-4 md:space-y-1 px-0">
<li>
<a href="../samples/index.html">Samples</a>
</li>
<li>
<a href="../learn/index.html">Learn</a>
</li>
<li>
<a href="../intro/index.html">Intro</a>
</li>
<li>
<a href="../api/index.html">API</a>
</li>
<li>
<a href="../changelog.html">Changelog</a>
</li>
<li>
<a href="https://github.com/NorthwoodsSoftware/GoJS" target="_blank" rel="noopener">GitHub</a>
</li>
</ul>
</div>
<div>
<h2 class="text-base font-semibold text-nwoods-primary">Support</h2>
<ul class="list-none space-y-4 md:space-y-1 px-0">
<li>
<a href="https://nwoods.com/contact.html"
target="_blank" rel="noopener" onclick="getOutboundLink('https://nwoods.com/contact.html', 'contact');">Contact</a>
</li>
<li>
<a href="https://forum.nwoods.com/c/gojs" target="_blank" rel="noopener">Forum</a>
</li>
<li>
<a href="https://nwoods.com/app/activate.aspx?sku=gojs" target="_blank" rel="noopener">Activate</a>
</li>
<li>
<a href="https://nwoods.com/sales/index.html"
target="_blank" rel="noopener" onclick="getOutboundLink('https://nwoods.com/sales/index.html', 'buy');">Buy</a>
</li>
<li>
<a href="https://nwoods.com/register.html" target="_blank" rel="noopener">Register</a>
</li>
</ul>
</div>
<div>
<h2 class="text-base font-semibold text-nwoods-primary">Company</h2>
<ul class="list-none space-y-4 md:space-y-1 px-0">
<li>
<a target="_blank" href="https://nwoods.com" target="_blank" rel="noopener">Northwoods</a>
</li>
<li>
<a target="_blank" href="https://nwoods.com/about.html" target="_blank" rel="noopener">About Us</a>
</li>
<li>
<a target="_blank" href="https://nwoods.com/contact.html" target="_blank" rel="noopener">Contact Us</a>
</li>
<li>
<a target="_blank" href="https://nwoods.com/consulting.html" target="_blank" rel="noopener">Consulting</a>
</li>
<li>
<a target="_blank" href="https://twitter.com/northwoodsgo" target="_blank" rel="noopener">Twitter</a>
</li>
</ul>
</div>
</div>
<p class="text-sm text-gray-900 md:mb-6">
Copyright 1998-2025 <a href="https://nwoods.com">Northwoods Software</a>
</p>
</div>
</footer>
</body>
<script async src="https://www.googletagmanager.com/gtag/js?id=G-S5QK8VSK84"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag('js', new Date());
gtag('config', 'G-S5QK8VSK84');
var getOutboundLink = function (url, label) {
gtag('event', 'click', {
'event_category': 'outbound',
'event_label': label,
'transport_type': 'beacon'
});
}
const params = new URL(document.location).searchParams
let a = params.get('a');
if (a) localStorage.setItem('a', a);
a = localStorage.getItem('a');
if (a) {
const links = [...document.body.getElementsByTagName("a")].filter((l) => l.href.includes('nwoods.com'));
for (const l of links) {
const url = new URL(l.href);
url.searchParams.set('a', a);
l.href = url;
}
}
</script>
<script src="../assets/js/prism.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gojs@3.1.0"></script>
<script src="../assets/js/goDoc.js"></script>
<script>
document.addEventListener("DOMContentLoaded", function () {
if (window.go)
document
.getElementById('version')
.textContent = "GoJS version " + go.version;
if (window.goDoc)
window.goDoc();
var d = window.diagrams;
for (var i = 0; i < d.length; i++) {
var dargs = d[i];
goCodeExecute(dargs[0], dargs[1], dargs[2], dargs[3], dargs[4]);
}
if (window.extra)
window.extra();
}
);
</script>
</html>