UNPKG

create-gojs-kit

Version:

A CLI for downloading GoJS samples, extensions, and docs

429 lines (384 loc) 18.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="A diagram with Graduated panels at the edges acting as rulers" /> <meta itemprop="description" content="A diagram with Graduated panels at the edges acting as rulers" /> <meta property="og:description" content="A diagram with Graduated panels at the edges acting as rulers" /> <meta name="twitter:description" content="A diagram with Graduated panels at the edges acting as rulers" /> <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="Diagram with Side and Top Rulers with Markers Showing Mouse Point" /> <meta property="og:title" content="Diagram with Side and Top Rulers with Markers Showing Mouse Point" /> <meta name="twitter:title" content="Diagram with Side and Top Rulers with Markers Showing Mouse Point" /> <meta property="og:image" content="https://gojs.net/latest/assets/images/screenshots/rulereddiagram.png" /> <meta itemprop="image" content="https://gojs.net/latest/assets/images/screenshots/rulereddiagram.png" /> <meta name="twitter:image" content="https://gojs.net/latest/assets/images/screenshots/rulereddiagram.png" /> <meta property="og:url" content="https://gojs.net/latest/samples/ruleredDiagram.html" /> <meta property="twitter:url" content="https://gojs.net/latest/samples/ruleredDiagram.html" /> <meta name="twitter:card" content="summary_large_image" /> <meta property="og:type" content="website" /> <meta property="twitter:domain" content="gojs.net" /> <title> Diagram with Side and Top Rulers with Markers Showing Mouse Point | 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', { 'undoManager.isEnabled': true, // enable undo & redo scrollMode: go.ScrollMode.Infinite, // allow the diagram to be scrolled beyond content 'grid.visible': true , // show that the ticks of the rulers always line up with the grid lines layout: new go.ForceDirectedLayout() }); // the templates don't really matter for this sample myDiagram.nodeTemplate = new go.Node('Auto') .add( new go.Shape('RoundedRectangle', { strokeWidth: 0, portId: '', fromLinkable: true, toLinkable: true }) .bind('fill', 'color'), new go.TextBlock({ margin: 8 }) .bind('text') ); myDiagram.model = new go.GraphLinksModel( [ { key: 1, text: 'Alpha', color: 'lightblue' }, { key: 2, text: 'Beta', color: 'orange' }, { key: 3, text: 'Gamma', color: 'lightgreen' }, { key: 4, text: 'Delta', color: 'pink' } ], [ { from: 1, to: 2 }, { from: 1, to: 3 }, { from: 2, to: 2 }, { from: 3, to: 4 }, { from: 4, to: 1 } ]); // Keep references to the scales and indicators to easily update them const gradScaleHoriz = new go.Part('Graduated', { graduatedTickUnit: 10, layerName: 'ViewportBackground', alignment: go.Spot.TopLeft, isAnimated: false }) .add( new go.Shape({ geometryString: 'M0 0 H400' }), new go.Shape({ geometryString: 'M0 0 V4', interval: 1 }), new go.Shape({ geometryString: 'M0 0 V7', interval: 5 }), new go.Shape({ geometryString: 'M0 0 V15', interval: 10 }), new go.TextBlock({ font: '10px sans-serif', interval: 10, alignmentFocus: go.Spot.TopLeft, segmentOffset: new go.Point(0, 7) }) ); const gradScaleVert = new go.Part('Graduated', { graduatedTickUnit: 10, layerName: 'ViewportBackground', alignment: go.Spot.TopLeft, isAnimated: false }) .add( new go.Shape({ geometryString: 'M0 0 V400' }), new go.Shape({ geometryString: 'M0 0 V4', interval: 1, alignmentFocus: go.Spot.Bottom }), new go.Shape({ geometryString: 'M0 0 V7', interval: 5, alignmentFocus: go.Spot.Bottom }), new go.Shape({ geometryString: 'M0 0 V15', interval: 10, alignmentFocus: go.Spot.Bottom }), new go.TextBlock({ font: '10px sans-serif', segmentOrientation: go.Orientation.Opposite, interval: 10, alignmentFocus: go.Spot.BottomLeft, segmentOffset: new go.Point(0, -7) }) ); const gradIndicatorHoriz = new go.Part({ pickable: false, layerName: 'Grid', visible: false, isAnimated: false, locationSpot: go.Spot.Top }) .add( new go.Shape({ geometryString: 'M0 0 V20', strokeWidth: 2, stroke: 'red' }) ); const gradIndicatorVert = new go.Part({ pickable: false, layerName: 'Grid', visible: false, isAnimated: false, locationSpot: go.Spot.Left }) .add( new go.Shape({ geometryString: 'M0 0 H20', strokeWidth: 2, stroke: 'red' }) ); // Add listeners to keep the scales/indicators in sync with the viewport myDiagram.addDiagramListener('InitialLayoutCompleted', setupScalesAndIndicators); myDiagram.addDiagramListener('ViewportBoundsChanged', e => { updateScales(); updateIndicators(); }); myDiagram.mouseEnter = () => showIndicators(true); myDiagram.mouseLeave = () => showIndicators(false); // Override doMouseMove to keep indicators in sync myDiagram.doMouseMove = function() { // method override must be function, not => go.Diagram.prototype.doMouseMove.call(this); updateIndicators(); } function setupScalesAndIndicators() { myDiagram.commit(d => { // Add each node to the diagram d.add(gradScaleHoriz); d.add(gradScaleVert); d.add(gradIndicatorHoriz); d.add(gradIndicatorVert); updateScales(); updateIndicators(); }, null); // null says to skip UndoManager recording of changes } function updateScales(vb) { if (!vb) vb = myDiagram.viewportBounds; if (!vb.isReal()) return; myDiagram.commit(diag => { // Update properties of horizontal scale to reflect viewport gradScaleHoriz.elt(0).width = vb.width * diag.scale; gradScaleHoriz.graduatedMin = vb.x; gradScaleHoriz.graduatedMax = vb.right; // Update properties of vertical scale to reflect viewport gradScaleVert.elt(0).height = vb.height * diag.scale; gradScaleVert.graduatedMin = vb.y; gradScaleVert.graduatedMax = vb.bottom; }, null); } function updateIndicators() { const vb = myDiagram.viewportBounds; if (!vb.isReal()) return; myDiagram.commit(diag => { const mouseCoords = diag.lastInput.documentPoint; // Keep the indicators in line with the mouse as viewport changes or mouse moves gradIndicatorHoriz.location = new go.Point(Math.max(mouseCoords.x, vb.x), vb.y); gradIndicatorHoriz.scale = 1 / diag.scale; gradIndicatorVert.location = new go.Point(vb.x, Math.max(mouseCoords.y, vb.y)); gradIndicatorVert.scale = 1 / diag.scale; }, null); } // Show indicators on mouseEnter of the diagram div; hide on mouseLeave function showIndicators(show) { myDiagram.commit(diag => { gradIndicatorHoriz.visible = show; gradIndicatorVert.visible = show; }, null); } // print the diagram by opening a new window holding SVG images of the diagram contents for each page function printDiagram() { const svgWindow = window.open(); if (!svgWindow) return; // failure to open a new Window svgWindow.document.title = 'GoJS Rulered Diagram'; svgWindow.document.body.style.margin = '0px'; const printSize = new go.Size(700, 960); const bnds = myDiagram.documentBounds.copy().unionRect(myDiagram.viewportBounds); let x = bnds.x; let y = bnds.y; while (y < bnds.bottom) { while (x < bnds.right) { const pagerect = new go.Rect(x, y, printSize.width, printSize.height); updateScales(pagerect); const svg = myDiagram.makeSvg({ scale: 1.0, position: new go.Point(x, y), size: printSize, showGrid: true, showTemporary: true }); svgWindow.document.body.appendChild(svg); x += printSize.width; } x = bnds.x; y += printSize.height; } // invoke the browser's print command setTimeout(() => { svgWindow.print(); svgWindow.updateScales(); svgWindow.close(); }, 1); } document.getElementById('myPrintButton').addEventListener('click', printDiagram); } window.addEventListener('DOMContentLoaded', init); </script> <div id="sample"> <div id="myDiagramDiv" style="border: solid 1px black; width:100%; height:400px"></div> <p> This sample demonstrates a diagram with rulers at its edges and indicators which display the mouse's position. </p> <p> The rulers are implemented using <a href="../intro/graduatedPanels.html">Graduated Panels</a>. The main element of each panel is sized according to the width/height of the viewport, with the <a>Panel.graduatedMin</a> and <a>Panel.graduatedMax</a> being set to the edges of the viewport. </p> <p> Event listeners and Tool overrides are used to keep the rulers and indicators in sync as the viewport bounds change or the mouse moves around the diagram. <ul> <li> <code>ViewportBoundsChanged</code> listeners are used to keep the rulers and indicators against the edge of the diagram and to update the min and max values of the rulers. </li> <li> An <code>InitialLayoutCompleted</code> listener is used for initial placement after the diagram has positioned the rest of the nodes. </li> <li> <a>ToolManager.doMouseMove</a>, <a>LinkingTool.doMouseMove</a>, <a>DraggingTool.doMouseMove</a>, and <a>DragSelectingTool.doMouseMove</a> are overridden to update the mouse indicators after executing their default behavior. Each is overridden so that whichever tool is active will properly adjust the indicators in addition to its normal functionality. </li> <li> Finally, the Diagram's <a>Diagram.mouseEnter</a> and <a>Diagram.mouseLeave</a> event handlers show and hide the indicators as the mouse moves into or out of the diagram's HTMLDivElement. </li> </ul> </p> <p> The rulers and the indicators are implemented using simple <a>Part</a>s, not <a>Node</a>s, so that they are not treated as nodes by some layouts and so that they do not show up in the collection of <a>Diagram.nodes</a>. They are put in the "Grid" <a>Layer</a> so that any changes to them are not recorded by the UndoManager, because the "Grid" Layer has all of its Parts ignored by the UndoManager. </p> <button id="myPrintButton">Print</button> </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>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> <!-- blacklist tags that do not correspond to a specific GoJS feature --> <h4>Grid Patterns</h4> <p> <b>GoJS</b> provides functionality to display a grid of lines drawn at regular intervals. Grid Panels can also force dragged parts to be aligned on grid points, and resize parts to be multiples of the grid cell size. </p> <p> Grids are implemented using a type of <a href="../api/symbols/Panel.html" target="api">Panel</a>, <a href="../api/symbols/PanelLayout.html#Grid" target="api">Panel.Grid</a>. Grid Panels, like most other types of Panels, can be used within <a href="../api/symbols/Node.html" target="api">Node</a>s or any other kind of <a href="../api/symbols/Part.html" target="api">Part</a>. However when they are used as the <a href="../api/symbols/Diagram.html#grid" target="api">Diagram.grid</a>, they are effectively infinite in extent. </p> <p> More information can be found in the <a href="../intro/grids.html">GoJS Intro</a>. </p> <p> <a href="../samples/index.html#grid">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>