<!DOCTYPE html>
<html>
<head>
<title>Snap to grid</title>
<meta charset="UTF-8" />
</head>
<body onload="init()" style="margin: 0; padding: 0; overflow: hidden">
<div id="app">
<div
id="diagram"
style="border: solid 1px black; width: 100%; height: calc(100vh)"
></div>
</div>
<script src="https://unpkg.com/gojs"></script>
<script id="code">
function init() {
var $ = go.GraphObject.make; // for conciseness in defining templates
myDiagram = $(
go.Diagram,
"diagram", // create a Diagram for the DIV HTML element
{
initialScale: 2.0,
"draggingTool.isGridSnapEnabled": true,
"grid.visible": true,
}
);
// define a simple Node template
myDiagram.nodeTemplate = $(
go.Node,
"Auto", // the Shape will go around the TextBlock
new go.Binding("location", "location"),
$(
go.Shape,
"RoundedRectangle",
{ strokeWidth: 0, fill: "white" },
// Shape.fill is bound to Node.data.color
new go.Binding("fill", "color")
),
$(
go.TextBlock,
{ margin: 8, font: "bold 14px sans-serif", stroke: "#333" }, // Specify a margin to add some room around the text
// TextBlock.text is bound to Node.data.key
new go.Binding("text", "key")
)
);
// but use the default Link template, by not setting Diagram.linkTemplate
// create the model data that will be represented by Nodes and Links
myDiagram.model = new go.GraphLinksModel([
{
key: "Alpha",
color: "lightblue",
location: new go.Point(0, 0),
},
{ key: "Beta", color: "orange", location: new go.Point(195, 0) },
]);
myDiagram.model.linkKeyProperty = "key";
}
</script>
</body>
</html>
When you select both nodes and start dragging over the grid, each nodes snaps individually.
Would it be possible to snap the selected collection synchronously based on a common point so that the original distance between the nodes would not be affected while dragging? We are using the GuidedDraggingTool and the same thing happens when the parts are being snapped to a guide.
In general it is forbidden to modify the values of any Point, Size, Rect, Margin, or Spot that is returned by getting any property. Think of instances of those classes being immutable once “used”.
<!DOCTYPE html>
<html>
<head>
<title>Snap to grid</title>
<meta charset="UTF-8" />
</head>
<body onload="init()" style="margin: 0; padding: 0; overflow: hidden">
<div id="app">
<div
id="diagram"
style="border: solid 1px black; width: 100%; height: calc(100vh)"
></div>
</div>
<script src="https://unpkg.com/gojs"></script>
<script id="code">
function init() {
var $ = go.GraphObject.make; // for conciseness in defining templates
myDiagram = $(
go.Diagram,
"diagram", // create a Diagram for the DIV HTML element
{
initialScale: 2.0,
"draggingTool.isGridSnapEnabled": true,
"draggingTool.doMouseMove": function () {
const p = this.diagram.lastInput.documentPoint.copy();
const grid = this.diagram.grid;
p.snapToGridPoint(grid.gridOrigin, grid.gridCellSize);
this.diagram.lastInput.documentPoint = p;
go.DraggingTool.prototype.doMouseMove.call(this);
},
"grid.visible": true,
}
);
// define a simple Node template
myDiagram.nodeTemplate = $(
go.Node,
"Auto", // the Shape will go around the TextBlock
new go.Binding("location", "location"),
$(
go.Shape,
"RoundedRectangle",
{ strokeWidth: 0, fill: "white" },
// Shape.fill is bound to Node.data.color
new go.Binding("fill", "color")
),
$(
go.TextBlock,
{ margin: 8, font: "bold 14px sans-serif", stroke: "#333" }, // Specify a margin to add some room around the text
// TextBlock.text is bound to Node.data.key
new go.Binding("text", "key")
)
);
// but use the default Link template, by not setting Diagram.linkTemplate
// create the model data that will be represented by Nodes and Links
myDiagram.model = new go.GraphLinksModel([
{
key: "Alpha",
color: "lightblue",
location: new go.Point(0, 0),
},
{ key: "Beta", color: "orange", location: new go.Point(195, 0) },
]);
myDiagram.model.linkKeyProperty = "key";
}
</script>
</body>
</html>
But the problem does not go away:
You see that when I start dragging, the Beta node snaps first and not simultaneously with the Alpha node. Am I missing something?
I do get the behavior that when first starting to move all selected nodes that are not already aligned to grid points are moved so that they are aligned. But after that I find that all nodes move together by equal amounts, maintaining their distances relative to each other.
I suppose you could modify the override so that it doesn’t do any move unless it moves a node to a different cell. That would avoid the initial making-sure-everything-is-aligned until the first move to a different cell.
But there’s no way to avoid nodes that are not aligned to move relative to other selected nodes that are aligned, soon or later.