Port to port automatic link after drag the node from the html palette

I have html palette when I will drop a node it should automatically connect the based on the distance.

image

node port should connect automatically based on the distance.

This code works for diagram-to-diagram drag-and-drops, not for HTML drag-and-drops. But it shows what you want to do once you have added the new node at a particular location in the target diagram.

$(go.Diagram, . . .,
  {
    "ExternalObjectsDropped": function(e) {
      e.diagram.commit(function(diag) {
        diag.selection.each(function(node) {
          if (node instanceof go.Node) {
            // you probably want to change the arguments to findPartsNear to suit your needs
            diag.findPartsNear(node.location, 100, true, true)
                .each(function(near) {
              if (near === node) return;
              // Figure out whether to connect NODE with NEAR, and if so,
              // which ports to connect.  Then add the links you want.
              // This assumes there are no specific ports:
              diag.model.addLinkData({ from: node.key, to: near.key });
            });
          }
        })
      })
    },
    . . .

Hi walter,
I am using Html palette in that I am using below function here I am getting event info
and as you suggest for every node I have two ports but I am able to get nearest node but how I will figure out nearest port
div1.addEventListener(“drop”, (event) => {

});

You can call GraphObject.getDocumentPoint (perhaps with go.Spot.Center as the argument) on each port element to find out where they are in document coordinates. Then you can decide to use the closest one.

However, you may have some syntactic or semantic reasons that you would not want to connect with the closest port. Or not make a link at all…

no I want to make a link but my question for html palette I am using
div1.addEventListener(“drop”, (event) => {

});

but yours example you are using
“ExternalObjectsDropped”: function(e) {
}
so my question is here I will not get e when I will drop from the html palette is there any can I use same code find out the nearest node port and link them to each other.

Thanks for the help.

Use the code in the HTML Drag Drop sample to get a point within the canvas that you can convert into document coordinates by calling Diagram.transformViewToDoc.
HTML Drag and Drop, and external Clipboard pasting
GoJS/htmlDragDrop.html at master · NorthwoodsSoftware/GoJS · GitHub

Hi walter ,
one general question can we achieve easily every thing using html palette whatever we can do with go palette. because so far I have seen lot of difficulties with html palette.

In your example we are finding the nears node but how we can calculate the distance between two node let suppose if we have 3 nears node around 100 cm location but which one is the nearest among of three.

$(go.Diagram, . . .,
{
“ExternalObjectsDropped”: function(e) {
e.diagram.commit(function(diag) {
diag.selection.each(function(node) {
if (node instanceof go.Node) {
// you probably want to change the arguments to findPartsNear to suit your needs
diag.findPartsNear(node.location, 100, true, true)
.each(function(near) {
if (near === node) return;
// Figure out whether to connect NODE with NEAR, and if so,
// which ports to connect. Then add the links you want.
// This assumes there are no specific ports:
diag.model.addLinkData({ from: node.key, to: near.key });
});
}
})
})
},

actually mine code is below and I am using html palette and here I have one more doubt part.isSelected property I am getting wrong .
so when I will drop thrid node bottom it is connect with first node above but it should connect to second node I doubt I am not calculating correct distance
image

var droppt = this.diagram.lastInput.documentPoint;
var nearby = this.diagram.findPartsNear(droppt, 300,true,true);

if (nearby.count > 1) {

        var dist = Infinity;

        var closest = null;
        nearby.each(function (part) {
            console.log(part.selectable);

            // !part.isSelected   don't include dropped nodes!

            //console.log(part.isSelected);

           let distance= part.actualBounds.center.distanceSquaredPoint(droppt) < dist

           let isNodePart=part instanceof go.Node;

            if (isNodePart&& part.data.key!=dropedNodeKey) {

                dist = part.actualBounds.center.distanceSquaredPoint(droppt);

                closest = part;

            }

        })

Thanks

That is for you to decide: whether to minimize the center-to-center distance of the nodes, or the space between them, or the distance between nearest ports, or some other way to measure. And you need to decide about ties and floating-point errors.

Hi walter,
I am using below code for getting all the nearest node and comparing each and every node distance with the last dropped node
I have doubt here when I am calculating the distance
let distance = part.actualBounds.center.distanceSquaredPoint(droppt) < dist
what does it means for center

automaticConnection() {
this.diagram.startTransaction(“add link”);
let modelData = this.diagram.model.nodeDataArray;
let index = this.diagram.model.nodeDataArray.length;
var dropedNodeKey = this.diagram.model.nodeDataArray[index - 1].key;
var droppt = this.diagram.lastInput.documentPoint;
var nearby = this.diagram.findPartsNear(droppt, 300, true, true);
if (nearby.count > 1) {
var dist = Infinity;
var closest = null;
nearby.each(function (part) {
let distance = part.actualBounds.center.distanceSquaredPoint(droppt) < dist
let isNodePart = part instanceof go.Node;
if (isNodePart && part.data.key != dropedNodeKey) {
dist = part.actualBounds.center.distanceSquaredPoint(droppt);
closest = part;
}
})
if (closest !== null) {
this.diagram.model.addLinkData({ from: closest.data.key, to: dropedNodeKey, });
}
}
this.diagram.commitTransaction(“add link”);
}
image

what is happening here when I will drop 2nd node it will connect to with the first node that’s correct but when I will drop 3rd node it should connect with the 2nd node. but again it is connecting with the first node that’s the problem.

can you look my code and check distance calculation part how I am doing is correct or wrong

You need to step through the code to debug it.

Notice how you compare the distance with the dist variable, but then you never use that result in the (misnamed) distance variable.

Hi walter I am checking distance variable in the if condition but while calculating the distance 1st and 2nd from the third node I am getting nearest node first and but actually the second node is the nearest node …
my question is while I will calculate the distance using part.actualBounds.center.distanceSquared form where It will considered
let distance = part.actualBounds.center.distanceSquaredPoint(droppt) < dist
can you give some link if we have any while drop the node from palette the node port should connect with nearest node.
public automaticConnection() {

    this.diagram.toolManager.draggingTool.isGridSnapEnabled = true;

    this.diagram.startTransaction("add link");

    let modelData = this.diagram.model.nodeDataArray;

    let index = this.diagram.model.nodeDataArray.length;

    var dropedNodeKey = this.diagram.model.nodeDataArray[index - 1].key;

    var droppt = this.diagram.lastInput.documentPoint;

    var nearby = this.diagram.findPartsNear(droppt, 300, true, true);

    let _part;

    //var toKey = "";

    if (nearby.count > 1) {

        var dist = Infinity;

        var closest = null;

        nearby.each(function (part) {

            _part = part;

            console.log(part.selectable);

            let distance = part.actualBounds.center.distanceSquaredPoint(droppt) < dist

            let isNodePart = part instanceof go.Node;

            if (distance && isNodePart && part.data.key != dropedNodeKey) {

                dist = part.actualBounds.center.distanceSquaredPoint(droppt);

                closest = part;

            }

        })

        if (closest !== null) {

            let nearestPort = this.diagram.model.nodeDataArray.filter(element => element.key == closest.data.key)

            let fkey = nearestPort[0].key;

            let f1 = this.diagram.model.nodeDataArray[0].ports[1].portId;

            let f2 = this.diagram.model.nodeDataArray[1].ports[0].portId;

            //this.diagram.model.addLinkData({ from: closest.data.key, fromPort: f1, to: dropedNodeKey, toPort: f2 });

            this.diagram.model.addLinkData({ from: closest.data.key, to: dropedNodeKey, });

        }

    }

I don’t have a sample exactly like what you are asking for, but here’s one that’s moderately similar:
https://gojs.net/extras/dropAutoLinks.html
As with almost all of our samples, the full code is on the page itself.

Thanks walter
Actually That’s the one I am taking reference in my code I have showed you. There is only one difference I am using html ondrop event… Is there any others method to find the closest node after drag the node into the canvas.

Thank You.

There’s a new example:
I want to get the shortest port distance between two node for every node we have two ports - GoJS - Northwoods Software (nwoods.com)