How to Start Linking via LinkingTool Correctly?

When I tried the following code stated in docs:

  var tool = myDiagram.toolManager.linkingTool;
  tool.startObject = ...;
  myDiagram.currentTool = tool;
  tool.doActivate();

It’s correct to start the tool the first time. In the subsequent action, starting the tool to make another link from another port, it still uses the the previously selected port.

Is there any configuration missing?

How do you set the LinkingTool.startObject?

The startObject is set by the following code:

      actionDown: function (e, part) {
        const diagram = e.diagram;
        e.handled = true;

        if (diagram.currentTool)
          diagram.currentTool.doCancel();

        diagram.toolManager.linkingTool.startObject = part.findObject("PORT");
        diagram.currentTool = diagram.toolManager.linkingTool;
        diagram.currentTool.doActivate();
      },

The port is contained in the part.

I setup a timer to log the diagram.toolManager.linkingTool.startObject of the two actions periodically. The log shows two different object (determined by __gohashid).

Maybe it’s depending on whether fromLinkable and toLinkable are true. I just tried this, and it works as I think you would expect:

    myDiagram.nodeTemplate =
      $(go.Node, "Auto",
        {
          click: function(e, node) {
              var diag = e.diagram;
              e.handled = true;
              diag.currentTool.doCancel();
              var tool = diag.toolManager.linkingTool;
              tool.startObject = node.findPort("");
              diag.currentTool = tool;
              tool.doActivate();
           }
        },
        $(go.Shape,
          {
            fill: "white", portId: "", cursor: "pointer",
            fromLinkable: true, toLinkable: true
          },
          new go.Binding("fill", "color")),
        $(go.TextBlock,
          { margin: 8 },
          new go.Binding("text"))
      );

The fromLinkable and toLinkable is already set though, It still didnt work.

To describe more specifically, the link will connects the two ports correctly after dropped, while the temporary port is still placed on the previous selected port (not current startObject).

The code I gave above does not exhibit that problem. Could you please provide a stand-alone sample that allows me to reproduce the problem? Please delete everything that is not necessary to cause the problem.

I cannot make a simple example to describe the issue… However, I found that if I don’t make a custom link template for LinkingTool.temporaryLink. The code works just fine.

OK, so what was your LinkingTool.temporaryLink? Note that that is not a template, but must be an actual Link that will be added and removed from the diagram as the LinkingTool is used.

You can find the definition of the default temporaryLink in the setupLinkingToolTemporaryNodesAndLink function in https://gojs.net/latest/extensions/templates.js

I figure out that it may be related to curve: go.Link.JumpOver setting. I reused the link template for LinkingTool.temporaryLink so I said it’s a template. Without such setting, the link behaved as expected.

I’d still like to see your temporaryLink definition. Did it have any Bindings?

Actually, I’ve switched to a clean implementation (without data bindings) when I found that using default links solved the problem. The issue still exists if curve: go.Link.JumpOver is set…

Hmmm. I still don’t have any problem when the user draws a new link by clicking on the node, thereby explicitly invoking the LinkingTool as in the code I posted above, with an addition in Diagram initialization that set LinkingTool.temporaryLink:

            "linkingTool.temporaryLink":
              $(go.Link, { routing: go.Link.Orthogonal, curve: go.Link.JumpOver },
                $(go.Shape, { strokeWidth: 2 }),
                $(go.Shape, { toArrow: "OpenTriangle" })
              )

But we’ll look into problems with curve: go.Link.JumpOver.

I tried to make a simple example to describe the issue but failed. In a simple example, there’re no problems about curve: go.Link.JumpOver. I still don’t know why…

Maybe it’s related to the link templates with heavy data bindings and curve: go.Link.JumpOver is set?

If you come up with more information, we’d like to learn about it so that we can track down a possible bug.

Wait – is it a problem to have curve: go.Link.JumpOver in the LinkingTool.temporaryLink, or in the link template, or both?

Only in LinkingTool.temporaryLink. I set curve: go.Link.JumpOver normally in my link template.

Maybe your problem has nothing to do with Link.curve, and maybe I didn’t see the problem because the nodes were too close to each other when I tried it. Try adding this line to initialize the LinkingTool when starting it programmatically:

      $(go.Node, . . .,
        {
          click: function(e, node) {
              var diag = e.diagram;
              e.handled = true;
              diag.currentTool.doCancel();

              // programmatically start the LinkingTool at this node's default port
              var tool = diag.toolManager.linkingTool;
              tool.startObject = node.findPort(""); // or whichever one you want...
              tool.temporaryToNode.location = diag.lastInput.documentPoint;
              diag.currentTool = tool;  // now it is running, but not activated
              tool.doActivate();
           }
        },
        . . .

Actually, the position of fromNode is wrong, not toNode. However, setting the position of temporaryFromNode doesn’t help…

Are you using something like the code I posted above? The code doesn’t have to be invoked from a click event handler – that’s just a convenient way that my test example starts the LinkingTool.

I am unable to see any problem with the position or size of the LinkingTool.temporaryFromNode or LinkingTool.temporaryFromPort when starting the LinkingTool programmatically in that way.