UNPKG

create-gojs-kit

Version:

A CLI for downloading GoJS samples, extensions, and docs

683 lines (638 loc) 26.4 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"/> <meta name="description" content="A larger org chart with an Overview and searching capability." /> <meta itemprop="description" content="A larger org chart with an Overview and searching capability." /> <meta property="og:description" content="A larger org chart with an Overview and searching capability." /> <meta name="twitter:description" content="A larger org chart with an Overview and searching capability." /> <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="Organizational Chart Diagram with Overview and Search" /> <meta property="og:title" content="Organizational Chart Diagram with Overview and Search" /> <meta name="twitter:title" content="Organizational Chart Diagram with Overview and Search" /> <meta property="og:image" content="https://gojs.net/latest/assets/images/screenshots/orgchartstatic.png" /> <meta itemprop="image" content="https://gojs.net/latest/assets/images/screenshots/orgchartstatic.png" /> <meta name="twitter:image" content="https://gojs.net/latest/assets/images/screenshots/orgchartstatic.png" /> <meta property="og:url" content="https://gojs.net/latest/samples/orgChartStatic.html" /> <meta property="twitter:url" content="https://gojs.net/latest/samples/orgChartStatic.html" /> <meta name="twitter:card" content="summary_large_image" /> <meta property="og:type" content="website" /> <meta property="twitter:domain" content="gojs.net" /> <title> Organizational Chart Diagram with Overview and Search | GoJS Diagramming Library </title> </head> <body> <!-- This top nav is not part of the sample code --> <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="flex flex-col prose"> <div class="w-full max-w-screen-xl mx-auto"> <!-- * * * * * * * * * * * * * --> <!-- Start of GoJS sample code --> <script src="https://cdn.jsdelivr.net/npm/gojs@3.1.0"></script> <div id="allSampleContent" class="p-4 w-full"> <style type="text/css"> #myOverviewDiv { position: absolute; width: 200px; height: 100px; top: 10px; left: 10px; background-color: #f2f2f2; z-index: 300; /* make sure its in front */ border: solid 1px #7986cb; } </style> <link href="https://fonts.googleapis.com/css?family=Roboto:400,500" rel="stylesheet" type="text/css" /> <script id="code"> function init() { // some constants that will be reused within templates const mt8 = new go.Margin(8, 0, 0, 0); const mr8 = new go.Margin(0, 8, 0, 0); const ml8 = new go.Margin(0, 0, 0, 8); const roundedRectangleParams = { parameter1: 2, // set the rounded corner spot1: go.Spot.TopLeft, spot2: go.Spot.BottomRight // make content go all the way to inside edges of rounded corners }; myDiagram = new go.Diagram('myDiagramDiv', { // Put the diagram contents at the top center of the viewport initialDocumentSpot: go.Spot.Top, initialViewportSpot: go.Spot.Top, // OR: Scroll to show a particular node, once the layout has determined where that node is // "InitialLayoutCompleted": e => { // var node = e.diagram.findNodeForKey(28); // if (node !== null) e.diagram.commandHandler.scrollToPart(node); // }, layout: new go.TreeLayout({ // use a TreeLayout to position all of the nodes isOngoing: false, // don't relayout when expanding/collapsing panels treeStyle: go.TreeStyle.LastParents, // properties for most of the tree: angle: 90, layerSpacing: 80, // properties for the "last parents": alternateAngle: 0, alternateAlignment: go.TreeAlignment.Start, alternateNodeIndent: 15, alternateNodeIndentPastParent: 1, alternateNodeSpacing: 15, alternateLayerSpacing: 40, alternateLayerSpacingParentOverlap: 1, alternatePortSpot: new go.Spot(0.001, 1, 20, 0), alternateChildPortSpot: go.Spot.Left }) }); // This function provides a common style for most of the TextBlocks. function textStyle(node, field) { node.font = '12px Roboto, sans-serif'; node.stroke = 'rgba(0, 0, 0, .60)'; node.visible = false; // only show textblocks when there is corresponding data for them node.bind('visible', field, val => val !== undefined); } // define Converters to be used for Bindings function theNationFlagConverter(nation) { return 'https://nwoods.com/images/emojiflags/' + nation + '.png'; } // define the Node template myDiagram.nodeTemplate = new go.Node('Auto', { locationSpot: go.Spot.Top, isShadowed: true, shadowBlur: 1, shadowOffset: new go.Point(0, 1), shadowColor: 'rgba(0, 0, 0, .14)', // selection adornment to match shape of nodes selectionAdornmentTemplate: new go.Adornment('Auto') .add( new go.Shape('RoundedRectangle', { fill: null, stroke: '#7986cb', strokeWidth: 3 }) .set(roundedRectangleParams), new go.Placeholder() ) // end Adornment }) .add( new go.Shape('RoundedRectangle', { name: 'SHAPE', fill: '#ffffff', strokeWidth: 0 }) .set(roundedRectangleParams) // gold if highlighted, white otherwise .bindObject('fill', 'isHighlighted', h => h ? 'gold' : '#ffffff'), new go.Panel('Vertical') .add( new go.Panel('Horizontal', { margin: 8 }) .add( new go.Picture({ // flag image, only visible if a nation is specified margin: mr8, visible: false, desiredSize: new go.Size(50, 50) }) .bind('source', 'nation', theNationFlagConverter) .bind('visible', 'nation', nat => nat !== undefined), new go.Panel('Table') .add( new go.TextBlock({ row: 0, alignment: go.Spot.Left, font: '16px Roboto, sans-serif', stroke: 'rgba(0, 0, 0, .87)', maxSize: new go.Size(160, NaN) }) .bind('text', 'name'), new go.TextBlock({ row: 1, alignment: go.Spot.Left, maxSize: new go.Size(160, NaN) }) .apply(textStyle, 'title') .bind('text', 'title'), go.GraphObject.build('PanelExpanderButton', { row: 0, column: 1, rowSpan: 2, margin: ml8 }, 'INFO') ) ), new go.Shape('LineH', { stroke: 'rgba(0, 0, 0, .60)', strokeWidth: 1, height: 1, stretch: go.Stretch.Horizontal }) .bindObject('visible', undefined, null, null, 'INFO'), // only visible when info is expanded new go.Panel('Vertical', { name: 'INFO', // identify to the PanelExpanderButton stretch: go.Stretch.Horizontal, // take up whole available width margin: 8, defaultAlignment: go.Spot.Left // thus no need to specify alignment on each element }) .add( new go.TextBlock() .apply(textStyle, 'headOf') .bind('text', 'headOf', head => 'Head of: ' + head), new go.TextBlock() .apply(textStyle, 'boss') .bind('margin', 'headOf', head => mt8) // some space above if there is also a headOf value .bind('text', 'boss', boss => { var boss = myDiagram.model.findNodeDataForKey(boss); if (boss !== null) return 'Reporting to: ' + boss.name; return ''; }) ) ) ); // define the Link template, a simple orthogonal line myDiagram.linkTemplate = new go.Link({ routing: go.Routing.Orthogonal, corner: 5, selectable: false }) .add( new go.Shape({ strokeWidth: 3, stroke: '#424242' }) // dark gray, rounded corner links ); // set up the nodeDataArray, describing each person/position var nodeDataArray = [ { key: 0, name: 'Ban Ki-moon 반기문', nation: 'SouthKorea', title: 'Secretary-General of the United Nations', headOf: 'Secretariat' }, { key: 1, boss: 0, name: "Patricia O'Brien", nation: 'Ireland', title: 'Under-Secretary-General for Legal Affairs and United Nations Legal Counsel', headOf: 'Office of Legal Affairs' }, { key: 3, boss: 1, name: 'Peter Taksøe-Jensen', nation: 'Denmark', title: 'Assistant Secretary-General for Legal Affairs' }, { key: 9, boss: 3, name: 'Other Employees' }, { key: 4, boss: 1, name: 'Maria R. Vicien - Milburn', nation: 'Argentina', title: 'General Legal Division Director', headOf: 'General Legal Division' }, { key: 10, boss: 4, name: 'Other Employees' }, { key: 5, boss: 1, name: 'Václav Mikulka', nation: 'CzechRepublic', title: 'Codification Division Director', headOf: 'Codification Division' }, { key: 11, boss: 5, name: 'Other Employees' }, { key: 6, boss: 1, name: 'Sergei Tarassenko', nation: 'Russia', title: 'Division for Ocean Affairs and the Law of the Sea Director', headOf: 'Division for Ocean Affairs and the Law of the Sea' }, { key: 12, boss: 6, name: 'Alexandre Tagore Medeiros de Albuquerque', nation: 'Brazil', title: 'Chairman of the Commission on the Limits of the Continental Shelf', headOf: 'The Commission on the Limits of the Continental Shelf' }, { key: 17, boss: 12, name: 'Peter F. Croker', nation: 'Ireland', title: 'Chairman of the Committee on Confidentiality', headOf: 'The Committee on Confidentiality' }, { key: 31, boss: 17, name: 'Michael Anselme Marc Rosette', nation: 'Seychelles', title: 'Vice Chairman of the Committee on Confidentiality' }, { key: 32, boss: 17, name: 'Kensaku Tamaki', nation: 'Japan', title: 'Vice Chairman of the Committee on Confidentiality' }, { key: 33, boss: 17, name: 'Osvaldo Pedro Astiz', nation: 'Argentina', title: 'Member of the Committee on Confidentiality' }, { key: 34, boss: 17, name: 'Yuri Borisovitch Kazmin', nation: 'Russia', title: 'Member of the Committee on Confidentiality' }, { key: 18, boss: 12, name: 'Philip Alexander Symonds', nation: 'Australia', title: 'Chairman of the Committee on provision of scientific and technical advice to coastal States', headOf: 'Committee on provision of scientific and technical advice to coastal States' }, { key: 35, boss: 18, name: 'Emmanuel Kalngui', nation: 'Cameroon', title: 'Vice Chairman of the Committee on provision of scientific and technical advice to coastal States' }, { key: 36, boss: 18, name: 'Sivaramakrishnan Rajan', nation: 'India', title: 'Vice Chairman of the Committee on provision of scientific and technical advice to coastal States' }, { key: 37, boss: 18, name: 'Francis L. Charles', nation: 'TrinidadAndTobago', title: 'Member of the Committee on provision of scientific and technical advice to costal States' }, { key: 38, boss: 18, name: 'Mihai Silviu German', nation: 'Romania', title: 'Member of the Committee on provision of scientific and technical advice to costal States' }, { key: 19, boss: 12, name: 'Lawrence Folajimi Awosika', nation: 'Nigeria', title: 'Vice Chairman of the Commission on the Limits of the Continental Shelf' }, { key: 20, boss: 12, name: 'Harald Brekke', nation: 'Norway', title: 'Vice Chairman of the Commission on the Limits of the Continental Shelf' }, { key: 21, boss: 12, name: 'Yong-Ahn Park', nation: 'SouthKorea', title: 'Vice Chairman of the Commission on the Limits of the Continental Shelf' }, { key: 22, boss: 12, name: 'Abu Bakar Jaafar', nation: 'Malaysia', title: 'Chairman of the Editorial Committee', headOf: 'Editorial Committee' }, { key: 23, boss: 12, name: 'Galo Carrera Hurtado', nation: 'Mexico', title: 'Chairman of the Training Committee', headOf: 'Training Committee' }, { key: 24, boss: 12, name: 'Indurlall Fagoonee', nation: 'Mauritius', title: 'Member of the Commission on the Limits of the Continental Shelf' }, { key: 25, boss: 12, name: 'George Jaoshvili', nation: 'Georgia', title: 'Member of the Commission on the Limits of the Continental Shelf' }, { key: 26, boss: 12, name: 'Wenzhang Lu', nation: 'China', title: 'Member of the Commission on the Limits of the Continental Shelf' }, { key: 27, boss: 12, name: 'Isaac Owusu Orudo', nation: 'Ghana', title: 'Member of the Commission on the Limits of the Continental Shelf' }, { key: 28, boss: 12, name: 'Fernando Manuel Maia Pimentel', nation: 'Portugal', title: 'Member of the Commission on the Limits of the Continental Shelf' }, { key: 7, boss: 1, name: 'Renaud Sorieul', nation: 'France', title: 'International Trade Law Division Director', headOf: 'International Trade Law Division' }, { key: 13, boss: 7, name: 'Other Employees' }, { key: 8, boss: 1, name: 'Annebeth Rosenboom', nation: 'Netherlands', title: 'Treaty Section Chief', headOf: 'Treaty Section' }, { key: 14, boss: 8, name: 'Bradford Smith', nation: 'UnitedStates', title: 'Substantive Legal Issues Head', headOf: 'Substantive Legal Issues' }, { key: 29, boss: 14, name: 'Other Employees' }, { key: 15, boss: 8, name: 'Andrei Kolomoets', nation: 'Russia', title: 'Technical/Legal Issues Head', headOf: 'Technical/Legal Issues' }, { key: 30, boss: 15, name: 'Other Employees' }, { key: 16, boss: 8, name: 'Other Employees' }, { key: 2, boss: 0, name: 'Heads of Other Offices/Departments' } ]; // create the Model with data for the tree, and assign to the Diagram myDiagram.model = new go.TreeModel({ nodeParentKeyProperty: 'boss', // this property refers to the parent node data nodeDataArray: nodeDataArray }); // Overview myOverview = new go.Overview('myOverviewDiv', { observed: myDiagram, // tell it which Diagram to show and pan contentAlignment: go.Spot.Center }); } // the Search functionality highlights all of the nodes that have at least one data property match a RegExp function searchDiagram() { // called by button var input = document.getElementById('mySearch'); if (!input) return; myDiagram.focus(); myDiagram.startTransaction('highlight search'); if (input.value) { // search four different data properties for the string, any of which may match for success // create a case insensitive RegExp from what the user typed var safe = input.value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); var regex = new RegExp(safe, 'i'); var results = myDiagram.findNodesByExample( { name: regex }, { nation: regex }, { title: regex }, { headOf: regex } ); myDiagram.highlightCollection(results); // try to center the diagram at the first node that was found if (results.count > 0) myDiagram.commandHandler.scrollToPart(results.first()); } else { // empty string only clears highlighteds collection myDiagram.clearHighlighteds(); } myDiagram.commitTransaction('highlight search'); } window.addEventListener('DOMContentLoaded', init); </script> <div id="sample" style="position: relative"> <div id="myDiagramDiv" style="background-color: #f2f2f2; border: solid 1px black; width: 100%; height: 700px"></div> <div id="myOverviewDiv"></div> <!-- Styled in a <style> tag at the top of the html page --> <p> This sample shows an organizational chart diagram and uses an in-laid GoJS <a>Overview</a> to aid the user in navigation. The diagram uses a <a>TreeLayout</a> featuring <a>TreeStyle.LastParents</a> to allow for different alignments on the last parents. The data was taken from the UN web site in August 2009. </p> <p> A search box demonstrates one way of finding and highlighting nodes whose data includes particular strings. Note that one can see all of the highlighted nodes in the Overview. </p> <input type="search" id="mySearch" onkeypress="if (event.keyCode === 13) searchDiagram()" /> <button onclick="searchDiagram()">Search</button> <p> To learn how to build an org chart from scratch with GoJS, see the <a href="../learn/index.html">Getting Started tutorial</a>. </p> <p> If you want to have some "assistant" nodes on the side, above the regular reports, see the <a href="orgChartAssistants.html">Org Chart Assistants</a> sample, which is a copy of this sample that uses a custom <a>TreeLayout</a> to position "assistants" that way. </p> <p> Flag images are from <a href="https://openmoji.org/">OpenMoji</a> – the open-source emoji and icon project. License: CC BY-SA 4.0. </p> </div> </div> <!-- * * * * * * * * * * * * * --> <!-- End of GoJS sample code --> </div> <div id="allTagDescriptions" class="p-4 w-full max-w-screen-xl mx-auto"> <hr/> <h3 class="text-xl">GoJS Features in this sample</h3> <!-- blacklist tags that do not correspond to a specific GoJS feature --> <h4>Table Panels</h4> <p> The "Table" Panel, <a href="../api/symbols/Panel.html#static-Table" target="api">Panel.Table</a>, arranges objects in rows and columns. Each object in a Table Panel is put into the cell indexed by the value of <a href="../api/symbols/GraphObject.html#row" target="api">GraphObject.row</a> and <a href="../api/symbols/GraphObject.html#column" target="api">GraphObject.column</a>. The panel will look at the rows and columns for all of the objects in the panel to determine how many rows and columns the table should have. More information can be found in the <a href="../intro/tablePanels.html">GoJS Intro</a>. </p> <p> <a href="../samples/index.html#tables">Related samples</a> </p> <hr> <!-- blacklist tags that do not correspond to a specific GoJS feature --> <h4>Tree Layout</h4> <p> This predefined layout is used for placing Nodes of a tree-structured graph in layers (rows or columns). For discussion and examples of the most commonly used properties of the <a href="../api/symbols/TreeLayout.html">TreeLayout</a>, see the <a href="../intro/trees.html">Trees</a> page in the Introduction. More information can be found in the <a href="../intro/layouts.html#TreeLayout">GoJS Intro</a>. </p> <p> <a href="../samples/index.html#treelayout">Related samples</a> </p> <hr> <!-- blacklist tags that do not correspond to a specific GoJS feature --> <h4>Overview Diagrams</h4> <p> An <a href="../api/symbols/Overview.html" target="api">Overview</a> is a subclass of <a href="../api/symbols/Diagram.html" target="api">Diagram</a> that is used to display all of the <a href="../api/symbols/Part.html" target="api">Part</a>s of another diagram and to show where that diagram's viewport is relative to all of those parts. The user can also scroll the overviewed diagram by clicking or dragging within the overview. </p> <p> The initialization of an <a href="../api/symbols/Overview.html" target="api">Overview</a> is just a matter of setting <a href="../api/symbols/Overview.html#observed" target="api">Overview.observed</a> to refer to the <a href="../api/symbols/Diagram.html" target="api">Diagram</a> that you want it to show. So there needs to be a DIV for your main diagram, for which you create a Diagram in the normal manner, and a separate DIV for your overview, for which you create the Overview in a very simple manner. </p> <p> More information can be found in the <a href="../intro/overview.html">GoJS Intro</a>. </p> <p> <a href="../samples/index.html#overview">Related samples</a> </p> <hr> </div> </div> </body> <!-- This script is part of the gojs.net website, and is not needed to run the sample --> <script src="../assets/js/goSamples.js"></script> </html>