gojs
Version:
Interactive diagrams, charts, and graphs, such as trees, flowcharts, orgcharts, UML, BPMN, or business diagrams
110 lines (103 loc) • 4.96 kB
HTML
<html>
<head>
<meta charset="UTF-8">
<title>Absolute positioning within the viewport</title>
<meta name="description" content="A diagram that does not scroll or zoom and has a fixed area in which to move parts." />
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Copyright 1998-2020 by Northwoods Software Corporation. -->
<script src="../release/go.js"></script>
<script src="../assets/js/goSamples.js"></script> <!-- this is only for the GoJS Samples framework -->
<script id="code">
function init() {
if (window.goSamples) goSamples(); // init for these samples -- you don't need to call this
var $ = go.GraphObject.make;
myDiagram =
$(go.Diagram, "myDiagramDiv",
{
fixedBounds: new go.Rect(0, 0, 500, 300), // document is always 500x300 units
allowHorizontalScroll: false, // disallow scrolling or panning
allowVerticalScroll: false,
allowZoom: false, // disallow zooming
"animationManager.isEnabled": false,
"undoManager.isEnabled": true,
"ModelChanged": function(e) { // just for demonstration purposes,
if (e.isTransactionFinished) { // show the model data in the page's TextArea
document.getElementById("mySavedModel").textContent = e.model.toJson();
}
}
});
// the background Part showing the fixed bounds of the diagram contents
myDiagram.add(
$(go.Part,
{ layerName: "Grid", position: myDiagram.fixedBounds.position },
$(go.Shape, { fill: "oldlace", strokeWidth: 0, desiredSize: myDiagram.fixedBounds.size })
));
// this function is the Node.dragComputation, to limit the movement of the parts
// use GRIDPT instead of PT if DraggingTool.isGridSnapEnabled and movement should snap to grid
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();
v.subtractMargin(diagram.padding);
// get the bounds of the part being dragged
var b = part.actualBounds;
var loc = part.location;
// now limit the location appropriately
var x = Math.max(v.x, Math.min(pt.x, v.right - b.width)) + (loc.x - b.x);
var y = Math.max(v.y, Math.min(pt.y, v.bottom - b.height)) + (loc.y - b.y);
return new go.Point(x, y);
}
myDiagram.nodeTemplate =
$(go.Node, "Auto",
{ dragComputation: stayInFixedArea },
// get the size from the model data
new go.Binding("desiredSize", "size", go.Size.parse),
// get and set the position in the model data
new go.Binding("position", "pos", go.Point.parse).makeTwoWay(go.Point.stringify),
// temporarily put selected nodes in Foreground layer
new go.Binding("layerName", "isSelected", function(s) { return s ? "Foreground" : ""; }).ofObject(),
$(go.Shape, "Rectangle",
{ strokeWidth: 0 }, // avoid extra thickness from the stroke
new go.Binding("fill", "color")),
$(go.TextBlock,
new go.Binding("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" }
]);
}
</script>
</head>
<body onload="init()">
<div id="sample">
<div id="myDiagramDiv" style="width:100%; height:400px"></div>
<p>
Absolute positioning within the viewport, with no scrolling (or panning) or zooming allowed.
</p>
<p>
There is a special colored background Part that 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>
<textarea id="mySavedModel" style="width:100%;height:250px"></textarea>
</div>
</body>
</html>