I want to get the shortest port distance between two node for every node we have two ports

Hi Walter,
I didn’t find any idea how I will get nodeobject using “ExternalObjectsDropped”.
can you give me some hints.

There are lots of examples of that in the samples and in the documentation.
https://gojs.net/latest/intro/collections.html#MoreIterationExamples

I do not understand what you are asking.

Have you read GoJS Ports in Nodes-- Northwoods Software and GoJS Link Connection Points on Nodes -- Northwoods Software ?

Also, this might be useful, in case it applies to your app: GoJS Link Connection Points on Nodes -- Northwoods Software

Does your node template declare two elements to be ports named “T” and “B” because they set GraphObject.portId to those identifiers?

Note how the node template I gave you a long time ago (in htmlDragDrop2.html) does that, except the identifiers it uses are “i” and “o”.

GraphObject.getDocumentPoint can be called on any GraphObject to get its position in document coordinates. So you just need to find the distances between the ports to see which pair have the shortest distance. Call Point.distanceSquaredPoint and don’t bother to call Math.sqrt. Presumably you will only check pairs of ports that are valid to connect in your app.

The code in the htmlDragDrop2.html demonstrates this, although it assumes it is only looking for the closest port with a particular port identifier.

Thanks, Walter.
But still I have doubt the below code just I have taken from your example
// first look for existing unconnected output ports on other nodes to automatically connect from
var newinport = newnode.findPort(“i”);
var newinpt = newinport.getDocumentPoint(go.Spot.Center);
// find closest available output port
var fromport = findClosestPort(“o”, newinpt, 100, newnode);
if (fromport !== null) {
myDiagram.model.addLinkData({ from: fromport.part.key, to: newnode.key });
}

      // now look again for existing unconnected input ports on other nodes to automatically connect to
      var newoutport = newnode.findPort("o");
      var newoutpt = newoutport.getDocumentPoint(go.Spot.Center);
      // find closest available input port
      var toport = findClosestPort("i", newoutpt, 100, newnode, fromport ? fromport.part : null);
      if (toport !== null) {
        myDiagram.model.addLinkData({ from: newnode.key, to: toport.part.key });
      }

here we are checking find closest available output port and input port. because we have two port in the node now let suppose I have three ports in a node A,B,C,
so, In that case do we need to call findClosetPort() function 3’s time for A,B,C port. .

If those three ports are all output ports, then yes, I believe that is correct.

But once you get three results, you still need to decide which of the three are closest to your input port. I think it would be better to change findClosestPort not to be given a particular output port identifier, but to check all of the output ports on each node that it examines.

Hi Walter,
as of now we don’t have such thing like input/output ports. after dropping the node we need to look nearest port that’s the only thing and connect automatically to that port.
and we can have up to n number of ports in the node.
so, in the findclosestPort() function according to that I will pass all the ports one by one and will check the nearest port but in the below function
public findClosestPort(pid, pt, dist, ignore1, ignore2) {
var nearby = this.diagram.findObjectsNear(pt, dist);
}
when I am doing this even though when I am dropping the first node , I am getting nearby.count=12 that’s means I need to loop through 12 times which is not good. so is there any approach here so I will relevant information in my nearby object.

nearby.each(function (port) {
var node = port.part;
})

Thank You

This function, given a Point PT in document coordinates, finds the closest port of a Node that is within DIST units and that is not the IGNORE Node.

function findClosestPort(pt, dist, ignore) {
    var closestdist = Infinity;
    var closestport = null;
    e.diagram.findPartsNear(pt, dist).each(function(part) {
      if (part !== ignore && part instanceof go.Node) {
        part.ports.each(function(port) {
          var d = port.getDocumentPoint(go.Spot.Center).distanceSquaredPoint(pt);
          if (d < closestdist) {
            closestdist = d;
            closestport = port;
          }
        });
      }
    });
    return closestport;
  }

You said that you could have any number of ports in a node, and you didn’t distinguish between input ports and output ports, so the code I gave you should handle that case.

If you need to find two (or more?) such closest ports in different nodes, you can call it twice, adapting the code to handle up to two optional nodes to ignore. Then if you find two qualifying ports, you can decide to create links from/to them.

HI Walter,
but in that code I am not getting any port details. when I am checking port.portId I am not getting any things it’s giving null every time.
and given a Point PT in document coordinates the pt will be node location correct?

If there is more than one port in a node, they will all have non-null values for GraphObject.portId except there may be one that is the default port when it is the whole Node.

Yes, you could use an existing Node.location, but I was expecting you to use InputEvent.documentPoint.

Hi Walter,
Yes I got it and its working now , but I have only one problem now
how I can get it toPortId dynamically even though I can take against fromPortId but its not the correct way is there any way I will get toPort Id,

let p = this.findClosestPort(droppt, 100, newnode);
if (p != null) {
this.diagram.model.addLinkData({ from: p.part.key, fromPort: p.portId, to: newnode.key,toPort:"" });
}
function findClosestPort(pt, dist, ignore) {
var closestdist = Infinity;
var closestport = null;
e.diagram.findPartsNear(pt, dist).each(function(part) {
if (part !== ignore && part instanceof go.Node) {
part.ports.each(function(port) {
var d = port.getDocumentPoint(go.Spot.Center).distanceSquaredPoint(pt);
if (d < closestdist) {
closestdist = d;
closestport = port;
}
});
}
});
return closestport;
}