Change the spot position of a link

You have node A and node B that are already connected by a link. I want to drag the link and modify the position of the start and end points of the link respectively. When I drag the nodes, the spot on the link changes to match the position of the node, sometimes connecting to the bottom of the node and sometimes connecting to the right. However, when I drag the link and drop it at the desired location on the node, the spot on the node does not change.

Would the LinkShiftingTool extension help?

This extension is close to what I want, but what I want is to be able to drag a link and just specify the top, bottom, right and left of the node, and if I have one link on a side of the node, it will position the node in the center of the side, and if I have multiple links, it will distribute them appropriately.

I’m still trying to understand what you want. I believe you are only talking about links that already exist – you do not want to change the link-drawing process (i.e. the LinkingTool’s behavior).

Did you sometimes want to let links route to the closest side? And sometimes you want the user to be able to say that a particular link should connect with a node only on a particular side? If so, do you ever want to let the user change the routing behavior back to the default routing behavior?

I think you want to sometimes set the Link.toSpot or Link.fromSpot to be a particular Spot…Side value. You can get back the normal routing behavior by setting it back to Spot.Default. The question is how users get to control that. You seem to want them to interact with a selected Link, yes?

Perhaps you can adapt that LinkShiftingTool so that the toSpot or fromSpot that it sets is just the appropriate side spot value such as Spot.TopSide instead of a computed spot based on the fractional distance along the side.

Also it isn’t clear to me whether the users are about to reconnect links to other nodes (i.e. Link.relinkableFrom and/or relinkableTo, to be able to use the RelinkingTool). If they are not allowed to do that, then maybe there are different ways to design the handles on selected links.

GOJS automatically draws links appropriately and pleasingly. However, when there are multiple nodes and links, sometimes links become difficult to see when they pass over a node or link. In these cases, the user can manually drag the link to adjust it. However, modifying the link does not change the endpoint of the link attached to the node from the spot on the node where it was first located, making it difficult to change the link to make it look better. To solve this, we want to change the spot on the node. When you move the node, the endpoints of the links move to the top, bottom, and left sides of the node as appropriate. If there are multiple links on one side of the node, they are positioned appropriately. I want the user to be able to create this by dragging. The extension you described is appropriate, but it can be positioned too freely on one side of the node. I want them to be distributed according to the number of links: 1/2 point, 1/3 point, and so on. I’m not familiar with English, so my explanation may be lacking. I apologize.

Your English is fine.

Have you tried what I suggested? Change the code in the LinkShiftingTool.doReshape method so that instead of:

    const spot = new go.Spot(Math.max(0, Math.min(1, (lp.x - portb.x) / (portb.width || 1))),
                             Math.max(0, Math.min(1, (lp.y - portb.y) / (portb.height || 1))));

it chooses one of Spot.TopSide, Spot.LeftSide, Spot.RightSide, or Spot.BottomSide, as seems appropriate to you.

The code of the LinkShiftingTool.doReshape method you mentioned is already the same as the one you showed in your example. Which part do I need to modify?

Replace that code. Instead of constructing a new computed Spot, just use one of the four “…Side” Spots.

Does your node/port have fromSpot and toSpot set to Spot.AllSides?

If so, try calling Node.invalidateConnectedLinks, with no arguments, on that node.

Thanks. You really helped me solve the problem.