UNPKG

create-gojs-kit

Version:

A CLI for downloading GoJS samples, extensions, and docs

481 lines (434 loc) 19.7 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="Nested Panels resulting in a spreadsheet-like node." /> <meta itemprop="description" content="Nested Panels resulting in a spreadsheet-like node." /> <meta property="og:description" content="Nested Panels resulting in a spreadsheet-like node." /> <meta name="twitter:description" content="Nested Panels resulting in a spreadsheet-like node." /> <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="Spreadsheet-like Nested Table Panels" /> <meta property="og:title" content="Spreadsheet-like Nested Table Panels" /> <meta name="twitter:title" content="Spreadsheet-like Nested Table Panels" /> <meta property="og:image" content="https://gojs.net/latest/assets/images/screenshots/spreadsheet.png" /> <meta itemprop="image" content="https://gojs.net/latest/assets/images/screenshots/spreadsheet.png" /> <meta name="twitter:image" content="https://gojs.net/latest/assets/images/screenshots/spreadsheet.png" /> <meta property="og:url" content="https://gojs.net/latest/samples/spreadsheet.html" /> <meta property="twitter:url" content="https://gojs.net/latest/samples/spreadsheet.html" /> <meta name="twitter:card" content="summary_large_image" /> <meta property="og:type" content="website" /> <meta property="twitter:domain" content="gojs.net" /> <title> Spreadsheet-like Nested Table Panels | 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"> <script id="code"> function init() { myDiagram = new go.Diagram('myDiagramDiv', { nodeSelectionAdornmentTemplate: new go.Adornment('Auto') .add( new go.Shape({ fill: null, stroke: 'orange', strokeWidth: 4 }), new go.Placeholder({ margin: 2 }) ) }); function textStyle(tb, big) { tb.stroke = 'white'; tb.font = big ? '16pt sans-serif' : '10pt sans-serif'; tb.alignment = go.Spot.Left; } function borderStyle(shp) { shp.fill = 'cornflowerblue'; shp.stroke = 'blue'; shp.strokeWidth = 2; } var aggregatedValue = new go.Panel('Auto', { margin: 5 }) .add( new go.Shape().apply(borderStyle), new go.TextBlock({ margin: 10, width: 50 }) .apply(textStyle) .bind('text', '') ); // assume just a number or a string var aggregatedListH = new go.Panel('Auto', { margin: 4, stretch: go.Stretch.Fill }) .add( new go.Shape().apply(borderStyle), new go.Panel('Table', { padding: 5, alignment: go.Spot.Left, stretch: go.Stretch.Fill, defaultAlignment: go.Spot.Left, defaultStretch: go.Stretch.Horizontal }) .add( new go.TextBlock({ row: 0 }) .apply(textStyle) .bind('text', 'header'), new go.Panel('Horizontal', { row: 1, itemTemplate: aggregatedValue }) .bind('itemArray', 'values') ) ); var aggregatedListV = new go.Panel('Auto', { margin: 4, stretch: go.Stretch.Fill }) .add( new go.Shape().apply(borderStyle), new go.Panel('Vertical', { padding: 5, alignment: go.Spot.Top, defaultAlignment: go.Spot.Left }) .add( new go.TextBlock({ maxSize: new go.Size(70, NaN) }) .apply(textStyle) .bind('text', 'header'), new go.Panel('Vertical', {itemTemplate: aggregatedValue}) .bind('itemArray', 'values') ) ); var checkBoxTemplate = go.GraphObject.build('CheckBox', { 'Button.width': 14, 'Button.height': 14 }, 'checked') // checked refers to the model data property name .add( new go.TextBlock() .apply(textStyle) .bind('text', 'label') ); myDiagram.nodeTemplate = new go.Part("Table") // insert an empty row and an empty column .addRowDefinition(1, { height: 8 }) .addColumnDefinition(1, { width: 8 }) .add( new go.Panel('Auto', { row: 0, column: 0, columnSpan: 3, stretch: go.Stretch.Fill }) .add( new go.Shape() .apply(borderStyle), new go.TextBlock({ margin: 10, alignment: go.Spot.Center }) .apply(textStyle, true) .bind('text', 'title') ), // the aggregated values new go.Panel('Auto', { row: 2, column: 0, stretch: go.Stretch.Fill }) .add( new go.Shape() .apply(borderStyle), new go.Panel('Table', { padding: 4 }) .add( new go.TextBlock() .apply(textStyle, true) .bind('text', 'aggTitle'), // The B Aggregated Values new go.Panel('Auto', { column: 0, row: 1, stretch: go.Stretch.Fill, margin: new go.Margin(10, 0) }) .add( new go.Shape().apply(borderStyle), new go.Panel('Table', { padding: 4, stretch: go.Stretch.Fill, defaultStretch: go.Stretch.Fill }) .add( new go.TextBlock({ row: 0 }) .apply(textStyle, true) .bind('text', 'aggHeaderB'), new go.Panel('Horizontal', { row: 1, itemTemplate: aggregatedValue }) .bind('itemArray', 'aggValuesB') ) ), // Now the C Aggregated Values new go.Panel('Auto', { column: 0, row: 2, alignment: go.Spot.TopLeft }) .add( new go.Shape().apply(borderStyle), new go.Panel('Table', { padding: 4, stretch: go.Stretch.Fill, defaultStretch: go.Stretch.Fill }) .add( new go.TextBlock({ row: 0, column: 0, columnSpan: 2 }) .apply(textStyle, true) .bind('text', 'aggSubtitle'), new go.Panel('Vertical', { row: 1, column: 0, alignment: go.Spot.Left, itemTemplate: aggregatedListH }) .bind('itemArray', 'aggValuesH'), new go.Panel('Horizontal', { row: 1, column: 1, alignment: go.Spot.Left, itemTemplate: aggregatedListV }) .bind('itemArray', 'aggValuesV') ) ) ) ), // the checkboxes new go.Panel('Auto', { row: 2, column: 2, stretch: go.Stretch.Fill }) .add( new go.Shape() .apply(borderStyle), new go.Panel('Vertical', { padding: 4, alignment: go.Spot.Top, stretch: go.Stretch.Vertical, defaultAlignment: go.Spot.Left }) .add( new go.TextBlock() .apply(textStyle, true) .bind('text', 'choices'), new go.Panel('Vertical', { itemTemplate: checkBoxTemplate }) .bind('itemArray', 'checkBoxes') ) ) ); myDiagram.model.nodeDataArray = [ { title: 'The Main Title', aggTitle: 'A-Aggregated Values (from B and C)', aggHeaderB: 'B-Aggregated Values (from B1-B2)', aggValuesB: [101.01, 102.02], aggSubtitle: 'C-Aggregated Values (from D, E, F, and G)', aggValuesH: [ { header: 'D-Aggregated Values (from D1..Dx)', values: [1.01, 2.02, 3.03, 4.04] }, { header: 'E-Aggregated Values (from E1..Ex)', values: [11.01, 12.02] }, { header: 'F-Aggregated Values (from F1..Fx)', values: [21.01, 22.02, 23.03, 24.04, 25.05] } ], aggValuesV: [ { header: 'G-Aggregated Values (from G1..Gx)', values: [31.01, 32.02, 33.03] } ], choices: 'Check Boxes', checkBoxes: [ { label: 'Checkbox 1', checked: true }, { label: 'Checkbox 2', checked: false }, { label: 'Checkbox 3', checked: true }, { label: 'Checkbox 4' } ] } ]; myDiagram.model.copiesArrays = true; myDiagram.model.copiesArrayObjects = true; } window.addEventListener('DOMContentLoaded', init); </script> <div id="sample"> <div id="myDiagramDiv" style="border: solid 1px black; width: 100%; height: 700px"></div> <p> An example of a single <a>Diagram.nodeTemplate</a> which contains many nested auto <a>Panel</a>s. The deepest nested <a>Panel</a>s have <a>Panel.itemTemplate</a> set to either checkboxes or auto <a>Panel</a>s with a blue rectangle and a textblock inside. Panels will then have <a>Panel.itemArray</a> bound to Arrays of numbers or checkbox labels. </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>Item Arrays</h4> <p> It is sometimes useful to display a variable number of elements in a node by data binding to a JavaScript Array. In GoJS, this is simply achieved by binding (or setting) <a href="../api/symbols/Panel.html#itemArray" target="api">Panel.itemArray</a>. The <a href="../api/symbols/Panel.html" target="api">Panel</a> will create an element in the panel for each value in the Array. More information can be found in the <a href="../intro/itemArrays.html">GoJS Intro</a>. </p> <p> <a href="../samples/index.html#itemarrays">Related samples</a> </p> <hr> <!-- blacklist tags that do not correspond to a specific GoJS feature --> <h4>Buttons</h4> <p> GoJS defines several <a href="../api/symbols/Panel.html" target="api">Panel</a>s for common uses. These include "Button", "TreeExpanderButton", "SubGraphExpanderButton", "PanelExpanderButton", "ContextMenuButton", and "CheckBoxButton". "ContextMenuButton"s are typically used inside of "ContextMenu" Panels; "CheckBoxButton"s are used in the implementation of "CheckBox" Panels. </p> <p> These predefined panels can be used as if they were <a href="../api/symbols/Panel.html" target="api">Panel</a>-derived classes in calls to <a href="../api/symbols/GraphObject.html#build" target="api">GraphObject.build</a>. They are implemented as simple visual trees of <a href="../api/symbols/GraphObject.html" target="api">GraphObject</a>s in <a href="../api/symbols/Panel.html" target="api">Panel</a>s, with pre-set properties and event handlers. </p> <p> More information can be found in the <a href="../intro/buttons.html">GoJS Intro</a>. </p> <p> <a href="../samples/index.html#buttons">Related samples</a> </p> <hr> <!-- blacklist tags that do not correspond to a specific GoJS feature --> <h4>Geometry Path Strings</h4> <p> The <b>GoJS</b> <a href="../api/symbols/Geometry.html" target="api">Geometry</a> class controls the "shape" of a <a href="../api/symbols/Shape.html" target="api">Shape</a>, whereas the <a href="../api/symbols/Shape.html#fill" target="api">Shape.fill</a> and <a href="../api/symbols/Shape.html#stroke" target="api">Shape.stroke</a> and other shape properties control the colors and appearance of the shape. For common shape figures, there are predefined geometries that can be used by setting <a href="../api/symbols/Shape.html#figure" target="api">Shape.figure</a>. However one can also define custom geometries. </p> <p> One can construct any Geometry by allocating and initializing a <a href="../api/symbols/Geometry.html" target="api">Geometry</a> of at least one <a href="../api/symbols/PathFigure.html" target="api">PathFigure</a> holding some <a href="../api/symbols/PathSegment.html" target="api">PathSegment</a>s. But you may find that using the string representation of a Geometry is easier to write and save in a database. Use the static method <a href="../api/symbols/Geometry.html#parse" target="api">Geometry.parse</a> or the <a href="../api/symbols/Shape.html#geometryString" target="api">Shape.geometryString</a> property to transform a geometry path string into a <a href="../api/symbols/Geometry.html" target="api">Geometry</a> object. </p> <p> More information can be found in the <a href="../intro/geometry.html">GoJS Intro</a>. </p> <p> <a href="../samples/index.html#geometries">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>