temporaryLinks not updating in change from 2.2.19 to 2.20

I was just wondering if anyone else came across this issue when using link tool to create lines.

I was experimenting with a tool in the extensions from work. it’s not in the git repo but it uses the LinkingTool as a base class.

The tool worked work by creating a line from the start position of wherever you clicked. Using the latest gojs it would not update the start position. You see the initial point but it draws from the very first time you click on canvas. The start point refuses to update after multiple line creations. Eventually, I found that it was the temporaryLinks.points.first() that was never updating.

At first I thought maybe work was removing the tool and instantiating a new tool each time but I found if I set temporaryLinks = new go.List at the beginning of canStart the expected functionality worked.

Out of curiosity, I rolled back my gojs version to 2.2.0 and I got the same functionality as work where wherever my first click becomes the new start point for the line.

I narrowed it down to 2.2.19 and 2.2.20 as the 2.2.19 being the last build where it works as I expect and then 2.2.20 where the behavior changes.

The build notes say for 2.2.20 say:

“Improved LinkingTool.doActivate to assign the location of the [LinkingBaseTool.temporaryToNode”

The description of that change in the change log is:

Improved LinkingTool.doActivate to assign the location of the LinkingBaseTool.temporaryToNode (or the LinkingBaseTool.temporaryFromNode, if drawing a link in the reverse direction) so as to avoid momentarily seeing where the temporary node had been the last time the user tried to draw a new link.

The change was due to this bug report: Weird linkingtool behavior

So my question is: what does your custom LinkingTool do?
Do you see that behavior if you don’t replace the standard ToolManager.linkingTool with your customized one?

The company is using a much earlier release. I’m just exploring on my own and learning the tools to get an understanding how the tools work. I’m working in a fresh canvas with just the one tool. I confirmed their diagram settings match mine and it reproduces. with or without any diagram settings.

The specific tool is named “DisconnectedLineTool” allowing you to click and drag to draw a line to wherever you release. My issue is specifically related to after I make the first click on the digram the temporaryLinks.Points.first() never changes no matter what I do from then on.

The only methods being override are canStart, doMouseMove, and insertLink.

The issue occurs after canStart and before the other 2 functions are called.

The below code is the main portion of the canStart once you pass the conditional statement to early pass which for the tool to work are all true.

      const $ = go.GraphObject.make;
      this._fakeStartPort = this.startObject = $(go.Shape, {
        width: 0,
        height: 0,
        portId: '',
        fromLinkable: true
      });
      const node = $(go.Node, {
        layerName: 'Tool',
        locationSpot: go.Spot.Center,
        // this point is true point where I made new first click !== to temporaryLink.Points.first()
        location: this.diagram.firstInput.documentPoint  
      }, this.startObject);
      this.diagram.add(node);
      node.ensureBounds();

The initial node appears correctly. If the first line I draw goes from center to bottom corner. That draws correct. The second line and all subsequent I attempt to draw for example from top right corner to center. The shape/node appear in top right corner but the line actually extends from the center where I start the last line. When I draw and release I will have a second line going from center to wherever I dragged and released instead of top right to center. The original node/shape that appeared in top right corner vanishes then.

It creates a really jarring effect cause I see it set the node correctly then the animated line as I move mouse around jumps and originates at the first time I clicked on canvas.

I suspect if company upgrades this will be an issue for them as well.

Should I just at the beginning of canStart keep continuing to set temporaryLink.Points = new List() to force it to use the starting point we set. When I tested and it worked was just a long shot.

What is the purpose of this custom tool? Is it to allow the user to draw a new Link that is disconnected from any ports/nodes?

If so, consider this sample: Draggable Link

Or are you just trying to draw a new Node that happens to be a line (not a link) that has a start point and and an end point?

If so, consider Line Drawing and Reshaping Sample or Line Drawing and Reshaping Sample, with arrowheads

Unfortunately, rearchitecting their tools isn’t an option at this stage.

It sounds like this is expected behavior to always retain the very first click on a diagram throughout life of of diagram for this temporaryLinks. Probably should not be named Temporary.

I don’t understand it was hoping too.

Seems like a change that would go into a major release. Its been working “correctly” the old way since 2.0.0.

Just upsetting I spent hours trying to figure out what the problem is and to me it still looks like a bug for 2.2.20.

Solution is to not upgrade past 2.2.19.

The change was to fix a bug that a customer had reported.
If your code is somehow depending on the buggy behavior, I’m sorry about that.

Note that the excerpt of the code that you posted seems to have come from the first sample I suggested: Draggable Link
That code has not changed in years, and I have just tested that it works in versions <= 2.2.19 as well as versions >= 2.2.20.

Understandable, hopefully this doesn’t cause issues for others.

Although, if it does should be easy enough to tell them just to use pre 2.2.20.

I don’t see anything buggy about temporaryLinks not persisting across tool invocations.

It’s not “my tool” it is gojs paying customer tool. I will keep that in mind though.

Thank you.

Here’s the code that is in the first sample that I pointed you at:

    var port = this.findLinkablePort();
    if (port === null) {
      const $ = go.GraphObject.make;
      this._fakeStartPort = this.startObject =
        $(go.Shape, { width: 1, height: 1, portId: "", fromLinkable: true });
      var node =
        $(go.Node,
          { layerName: "Tool", locationSpot: go.Spot.Center, location: diagram.firstInput.documentPoint },
          this.startObject);
      diagram.add(node);
      node.ensureBounds();
    }

Try changing the equivalent code in your customer’s custom tool to something like:

    var port = this.findLinkablePort();
    if (port === null) {
      const $ = go.GraphObject.make;
      this._fakeStartPort = this.startObject =
        $(go.Shape, { width: 1, height: 1, portId: "", fromLinkable: true });
      var node =
        $(go.Node,
          { layerName: "Tool", locationSpot: go.Spot.Center, location: diagram.firstInput.documentPoint },
          this.startObject);
      diagram.add(node);
      node.ensureBounds();
    } else {
      port.part.location = diagram.firstInput.documentPoint;
    }

In other words, add the else clause to always update the temporary node’s location.

It’s called a temporary node because it’s only in the diagram during the activation of the running tool.