create-gojs-kit
Version:
A CLI for downloading GoJS samples, extensions, and docs
288 lines (256 loc) • 11.7 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"/>
<meta name="description" content="A diagram that does not scroll or zoom and has a fixed area in which to move parts." />
<meta itemprop="description" content="A diagram that does not scroll or zoom and has a fixed area in which to move parts." />
<meta property="og:description" content="A diagram that does not scroll or zoom and has a fixed area in which to move parts." />
<meta name="twitter:description" content="A diagram that does not scroll or zoom and has a fixed area in which to move parts." />
<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="Absolute Positioning of Parts in Div Element" />
<meta property="og:title" content="Absolute Positioning of Parts in Div Element" />
<meta name="twitter:title" content="Absolute Positioning of Parts in Div Element" />
<meta property="og:image" content="https://gojs.net/latest/assets/images/screenshots/absolute.png" />
<meta itemprop="image" content="https://gojs.net/latest/assets/images/screenshots/absolute.png" />
<meta name="twitter:image" content="https://gojs.net/latest/assets/images/screenshots/absolute.png" />
<meta property="og:url" content="https://gojs.net/latest/samples/absolute.html" />
<meta property="twitter:url" content="https://gojs.net/latest/samples/absolute.html" />
<meta name="twitter:card" content="summary_large_image" />
<meta property="og:type" content="website" />
<meta property="twitter:domain" content="gojs.net" />
<title>
Absolute Positioning of Parts in Div Element | 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>
<link rel="stylesheet" href="../assets/css/prism.css"/>
<script src="../assets/js/prism.js"></script>
<div id="allSampleContent" class="p-4 w-full">
<script id="code">
function init() {
myDiagram =
new go.Diagram('myDiagramDiv', {
fixedBounds: new go.Rect(0, 0, 500, 300), // document is always 500x300 units
contentAlignment: go.Spot.Center,
allowHorizontalScroll: false, // disallow scrolling or panning
allowVerticalScroll: false,
allowZoom: false, // disallow zooming
'animationManager.isEnabled': false,
'undoManager.isEnabled': true,
ModelChanged: e => {
// just for demonstration purposes,
if (e.isTransactionFinished) {
// show the model data in the page's TextArea
document.getElementById('mySavedModel').innerHTML = e.model.toJson();
if (window.Prism) window.Prism.highlightAll();
}
}
});
// the background Part showing the fixed bounds of the diagram contents
myDiagram.add(
new go.Part({
layerName: 'ViewportBackground',
alignment: go.Spot.Center,
isShadowed: true,
padding: 1
})
.add(
new go.Panel('Auto')
.add(
new go.Shape({strokeWidth: 0}),
new go.Shape({
fill: new go.Brush('Linear', {
0: go.Brush.lightenBy('oldlace', 0.5),
0.5: 'oldlace',
1: go.Brush.darkenBy('oldlace', 0.01),
start: go.Spot.TopLeft,
end: go.Spot.BottomRight
}),
strokeWidth: 1,
stroke: 'transparent',
desiredSize: myDiagram.fixedBounds.size,
margin: 1
})
)
));
// This function is the Node.dragComputation, to limit the movement of the parts.
function stayInFixedArea(part, pt, gridpt) {
var diagram = part.diagram;
if (diagram === null) return pt;
// compute the document area without padding
var v = diagram.documentBounds.copy().subtractMargin(diagram.padding);
// get the bounds of the part being dragged
var bnd = part.actualBounds;
var loc = part.location;
// now limit the location appropriately
var l = v.x + (loc.x - bnd.x);
var r = v.right - (bnd.right - loc.x);
var t = v.y + (loc.y - bnd.y);
var b = v.bottom - (bnd.bottom - loc.y);
if (l <= gridpt.x && gridpt.x <= r && t <= gridpt.y && gridpt.y <= b) return gridpt;
var p = gridpt.copy();
if (diagram.toolManager.draggingTool.isGridSnapEnabled) {
// find a location that is inside V but also keeps the part's bounds within V
var cw = diagram.grid.gridCellSize.width;
if (cw > 0) {
while (p.x > r) p.x -= cw;
while (p.x < l) p.x += cw;
}
var ch = diagram.grid.gridCellSize.height;
if (ch > 0) {
while (p.y > b) p.y -= ch;
while (p.y < t) p.y += ch;
}
return p;
} else {
p.x = Math.max(l, Math.min(p.x, r));
p.y = Math.max(t, Math.min(p.y, b));
return p;
}
}
myDiagram.nodeTemplate =
new go.Node('Auto', {
dragComputation: stayInFixedArea
})
.bind('desiredSize', 'size', go.Size.parse) // get the size from the model data
.bindTwoWay('position', 'pos', go.Point.parse, go.Point.stringify) // get and set the position
.bindObject('layerName', 'isSelected', s => s ? 'Foreground' : '') // temporarily put selected nodes in Foreground layer
.add(
new go.Shape('Rectangle', {
strokeWidth: 1
}) // avoid extra thickness from the stroke
.bind('fill', 'color')
.bind('stroke', 'color', value => go.Brush.darken(value)),
new go.TextBlock()
.bind('text', 'color')
);
myDiagram.model = new go.GraphLinksModel(
[
{ key: 'Alpha', pos: '0 0', size: '50 50', color: 'lightblue' },
{ key: 'Beta', pos: '276 19', size: '100 100', color: 'orange' },
{ key: 'Gamma', pos: '44 214', size: '100 50', color: 'lightgreen' },
{ key: 'Delta', pos: '239 171', size: '50 100', color: 'pink' }
],
[
{ from: 'Alpha', to: 'Beta' },
{ from: 'Alpha', to: 'Gamma' },
{ from: 'Gamma', to: 'Delta' },
{ from: 'Delta', to: 'Alpha' }
]
);
}
window.addEventListener('DOMContentLoaded', init);
</script>
<div id="sample">
<div id="myDiagramDiv" style="width: 100%; height: 400px; border: 1px solid black;"></div>
<p>
Absolute positioning within the viewport (represented by the paper-colored
rectangle with the shadow), with no scrolling, panning, or zooming allowed.
</p>
<p>
The special colored background Part shows the fixed area where Parts may
be. It is in the "Grid" Layer so that it is not selectable and is
always behind the regular Parts.
</p>
<p>
Parts may not be dragged outside of the fixed document area of the diagram.
This is implemented by a custom <a>Part.dragComputation</a> function.
</p>
<p>Note that the user may still scroll or zoom the whole page.</p>
<p>
The model data, automatically updated after each change or undo or redo:
</p>
<pre class="lang-js" style="max-height: 300px"><code id="mySavedModel"></code></pre>
</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>
</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>