UNPKG

create-gojs-kit

Version:

A CLI for downloading GoJS samples, extensions, and docs

547 lines (515 loc) 22 kB
<!DOCTYPE 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="Layers" /> <meta property="og:title" content="Layers" /> <meta name="twitter:title" content="Layers" /> <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/layers.html" /> <meta property="twitter:url" content="https://gojs.net/latest/intro/layers.html" /> <meta name="twitter:card" content="summary_large_image" /> <meta property="og:type" content="website" /> <meta property="twitter:domain" content="gojs.net" /> <title> Layers | 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 &amp; 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>Layers and Z-ordering</h1> <p> All <a>Part</a>s that are in a <a>Diagram</a> actually belong to a <a>Layer</a> in the diagram. You can control the visibility, Z-order, and various user permissions for all of the parts in each layer. </p> <p> Parts can be individually modified to toggle their visibility using <a>Part.visible</a> or <a>Part.opacity</a>. Parts can be individually Z-ordered within layers using <a>Part.zOrder</a>. </p> <h2 id="StandardLayers">Standard Layers</h2> <p> Every Diagram starts off with several standard layers. These are their <a>Layer.name</a>s, in order from furthest behind to most in front: </p> <ul> <li><b>"Grid"</b>, holding the <a>Diagram.grid</a> and any other static Parts that you wish to be behind everything</li> <li><b>"ViewportBackground"</b>, holding Parts aligned to the viewport rather than in the document</li> <li><b>"Background"</b></li> <li><b>""</b>, the default layer</li> <li><b>"Foreground"</b></li> <li><b>"ViewportForeground"</b>, holding Parts aligned to the viewport rather than in the document</li> <li><b>"Adornment"</b>, holding <a>Adornment</a>s for selection and various Tools</li> <li><b>"Tool"</b>, holding Parts used in the execution of various Tools</li> </ul> <p> The Layers "ViewportBackground" and "ViewportForeground" are for adding Parts that do not move with the Diagram scale or position, because they are aligned to the viewport, so such Parts stay fixed to a specific point in the viewport. See the <a href="./legends.html#StaticParts">Legends intro page</a> for more discussion. </p> <p> Each Part is placed in a Layer according to its <a>Part.layerName</a>. The default value is the empty string. Use <a>Diagram.findLayer</a> to find a Layer given a layer name. Change which layer a part is in by setting <a>Part.layerName</a>. </p> <p> Changes to Parts in the "Grid", "Adornment", "Tool", and "Viewport..." Layers are automatically ignored by the <a>UndoManager</a>, because <a>Layer.isTemporary</a> is true. Those Parts are also not selectable. </p> <h2 id="LayersExample">Layers Example</h2> <p> This example adds several <a>Layer</a>s to the diagram, each named by a color, and then creates a bunch of colored parts at random locations. Every <a>Part.layerName</a> is data-bound to the "color" property of the node data. </p> <p> In addition there are checkboxes for each layer, controlling the visibility of the respective layer. You can see how all of the parts of the same color appear and disappear according to the value of the checkbox. Furthermore you can see how they all have the same depth in the Z-ordering. </p> <p> Finally, each Part has a <a>Part.selectionChanged</a> function which puts the part in the "Foreground" layer when it is selected and back in its normal color layer when it is not selected. </p> <pre class="lang-js" id="layers"><code> // These new layers come in front of the standard regular layers, // but behind the "Foreground" layer: const forelayer = diagram.findLayer("Foreground"); diagram.addLayerBefore(new go.Layer({ name: "blue" }), forelayer); diagram.addLayerBefore(new go.Layer({ name: "green" }), forelayer); diagram.addLayerBefore(new go.Layer({ name: "orange" }), forelayer); diagram.nodeTemplate = // no links or grouping, so can use the simpler Part class new go.Part("Spot", { selectionChanged: p => { p.layerName = (p.isSelected ? "Foreground" : p.data.color); }, layerChanged: (p, oldLayer, newLayer) => { if (newLayer !== null) p.elt(1).text = newLayer.name; } }) .bind("layerName", "color") .bind("location", "loc") .add( new go.Shape({ width: 80, height: 80 }) .bind("fill", "color"), new go.TextBlock({ stroke: "white", font: "bold 12px sans-serif" }) ); const array = []; for (let i = 0; i &lt; 12; i++) { const data = { loc: new go.Point(Math.random()*520, Math.random()*200) }; switch (Math.floor(Math.random()*3)) { case 0: data.color = "blue"; break; case 1: data.color = "green"; break; case 2: data.color = "orange"; break; default: data.color = "Foreground"; break; } array.push(data); } diagram.model.nodeDataArray = array; diagram.undoManager.isEnabled = true; // define this function so that the checkbox event handlers can call it toggleVisible = (layername, e) => { diagram.commit(d => { const layer = d.findLayer(layername); if (layer !== null) layer.visible = e.currentTarget.checked; }, 'toggle ' + layername); }; </code></pre> <script> goCode('layers', 610, 290); </script> Layer visibility:<br /> <input type="checkbox" checked="checked" onclick="toggleVisible('blue', event)" />blue <input type="checkbox" checked="checked" onclick="toggleVisible('green', event)" />green <input type="checkbox" checked="checked" onclick="toggleVisible('orange', event)" />orange <input type="checkbox" checked="checked" onclick="toggleVisible('Foreground', event)" />Foreground <h2 id="ZOrderExample">ZOrder Example</h2> <p> This example adds several <a>Part</a>s to one Layer (the default) in the diagram. Every <a>Part.zOrder</a> is data-bound to the "zOrder" property of the node data, as is its text. </p> <p> Buttons on the Part can be used to modify the z-order of each. </p> <pre class="lang-js" id="zOrder"><code> function changeZOrder(amt, obj) { diagram.commit(d => { const data = obj.part.data; d.model.set(data, "zOrder", data.zOrder + amt); }, 'modified zOrder'); } diagram.nodeTemplate = new go.Part("Spot") .bind("layerName", "color") .bind("location", "loc") .bind("zOrder") .add( new go.Shape({ width: 100, height: 100, stroke: 'rgb(50,50,50)', fill: 'rgb(50,100,255)' }), new go.TextBlock({ font: "52px sans-serif", stroke: 'whitesmoke' }) .bind("text", "zOrder"), go.GraphObject.build("Button", { alignment: go.Spot.BottomLeft, alignmentFocus: go.Spot.BottomLeft, click: (e, obj) => changeZOrder(-1, obj) }) .add( new go.Shape("LineH", { width: 14, height: 14 }) ), go.GraphObject.build("Button", { alignment: go.Spot.BottomRight, alignmentFocus: go.Spot.BottomRight, click: (e, obj) => changeZOrder(1, obj) }) .add( new go.Shape("PlusLine", { width: 14, height: 14 }) ) ); const array = []; for (let i = 0; i < 12; i++) { const data = { loc: new go.Point(Math.random()*500, Math.random()*200) }; data.zOrder = (Math.floor(Math.random()*20)) array.push(data); } diagram.model.nodeDataArray = array; diagram.undoManager.isEnabled = true; </code></pre> <script> goCode('zOrder', 610, 310); </script> </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>