Hi,
I need to be able to show a link when two nodes get close together and if the user stops dragging create the link. What are my options?
Thanks
Hi,
I need to be able to show a link when two nodes get close together and if the user stops dragging create the link. What are my options?
Thanks
Create a custom DraggingTool.
function LinkingDraggingTool() {
go.DraggingTool.call(this);
var $ = go.GraphObject.make;
this._tempLink =
$(go.Link,
{ layerName: "Tool" },
$(go.Shape, { stroke: "blue", strokeWidth: 3 }),
$(go.Shape, { stroke: "blue", strokeWidth: 3, toArrow: "OpenTriangle" })
);
this._tempNode =
$(go.Node,
{ layerName: "Tool" },
{ fromLinkable: true }
);
}
go.Diagram.inherit(LinkingDraggingTool, go.DraggingTool);
LinkingDraggingTool.prototype.doDeactivate = function() {
go.DraggingTool.prototype.doDeactivate.call(this);
this.diagram.remove(this._tempLink);
this.diagram.remove(this._tempNode);
}
LinkingDraggingTool.prototype.findNearestNode = function(pt, draggednode) {
var linkingTool = this.diagram.toolManager.linkingTool;
var draggeds = this.draggedParts;
var near = this.diagram.findObjectsNear(pt, 50,
// only consider undragged Nodes for which a new link would be valid
function(x) {
var p = x.part;
if (p instanceof go.Node &&
!draggeds.contains(p) &&
linkingTool.isValidLink(draggednode, draggednode.port, p, p.port)) return p;
return null;
});
// find Node whose location is closest to PT
var dist = Infinity;
var nearest = null;
near.each(function(n) {
var d2 = n.location.distanceSquaredPoint(pt);
if (d2 < dist) {
dist = d2;
nearest = n;
}
});
return nearest;
};
LinkingDraggingTool.prototype.doDragOver = function(pt, over) {
if (this.copiedParts !== null) return;
var draggednode = this.draggedParts.first().key;
var nearest = this.findNearestNode(pt, draggednode);
if (nearest !== null && draggednode instanceof go.Node) {
this._tempNode.location = nearest.actualBounds.center;
this.diagram.add(this._tempNode);
this._tempLink.fromNode = draggednode;
this._tempLink.toNode = this._tempNode;
this.diagram.add(this._tempLink);
} else {
this.diagram.remove(this._tempLink);
}
};
LinkingDraggingTool.prototype.doDropOnto = function(pt, over) {
if (this.copiedParts !== null) return;
var draggednode = this.draggedParts.first().key;
var nearest = this.findNearestNode(pt, draggednode);
if (nearest !== null && draggednode instanceof go.Node) {
// this happens within the DraggingTool's transaction
var model = this.diagram.model;
// assume the model is a GraphLinksModel
model.addLinkData({
from: model.getKeyForNodeData(draggednode.data),
to: model.getKeyForNodeData(nearest.data)
});
}
};
This makes a few assumptions about your model and your nodes – such as using a GraphLinksModel, there only being one port on each Node, and the appearance of the temporary Link. You’ll have to adapt it for your particular circumstances.
Here’s the whole test app:
function init() {
var $ = go.GraphObject.make;
myDiagram =
$(go.Diagram, "myDiagramDiv",
{
initialContentAlignment: go.Spot.Center,
"undoManager.isEnabled": true,
draggingTool: new LinkingDraggingTool()
});
myDiagram.nodeTemplate =
$(go.Node, "Auto",
$(go.Shape,
{ portId: "", fromLinkable: true, toLinkable: true },
new go.Binding("fill", "color")),
$(go.TextBlock,
{ margin: 8 },
new go.Binding("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" }
]);
}
Thanks Walter for the quick reply. I’ve implemented your sample in this fiddle and it doesn’t seem to do what I’m looking for.
Fiddle: GoJS Sample for JSFIDDLE - JSFiddle - Code Playground
What I’m wanting is when you drag a node and it gets “close enough” to another node a link will automatically be displayed connecting the two nodes. Then if:
Why did you comment out the installation of the custom DraggingTool?
Oh jees, how embarrassing. I was debugging and trying to get a simple diagram to just show and forgot that code commented out. That’s perfect, thanks!
Here’s the working fiddle for future generations: GoJS Sample for JSFIDDLE - JSFiddle - Code Playground
Also, if you want a LinkingDraggingTool that works with copied nodes, see: Auto link node dragged from palette to node on canvas