To smooth out the link in gojs diagram

In our diagram, when we draw manual links, we are getting a rough one as shown in below diag.
image
But when I double click on the link left corner, it smooths out the link.
image

Could you please help to identify which method is doing this? We need our user to be able to draw smooth links automatically. Or if there is a better option available, please guide me.

Is the user drawing a new Link using the standard LinkingTool, or has that tool had some methods overridden?

How is that link template defined? If the Link.routing is orthogonal (either Orthogonal or AvoidsNodes), then unless you have overridden some methods on Link I don’t see how that would happen.

Hi Walter,
Yes, we did update few of the inbuilt methods in past. We are using AvoidsLinkRouter.js as an additional file to format our diagram. Please find below our link template :

  myDiagram.linkTemplate =
    $(go.Link,
      {
    	routing: go.Link.Orthogonal,
        corner: 5,
        curve: go.Link.JumpOver,
        relinkableFrom: true, relinkableTo: true,
        reshapable: true,
        resegmentable: true,
        mouseEnter: function(e, link) { link.path.strokeWidth=14},
		mouseLeave: function(e, link) { link.path.strokeWidth=4}
     },new go.Binding("routing", "routing"),   
      new go.Binding("points").makeTwoWay(),
      $(go.Shape, 
        { isPanelMain: true, stroke: "transparent" },
        new go.Binding("pathPattern", "patt", convertPathPatternToShape),
        new go.Binding("stroke", "color"), 
        new go.Binding("strokeWidth", "thick"),
        new go.Binding("fill", "fill"),
        new go.Binding("isPanelMain", "isPanelMain")
      ),
      $(go.Shape,
        { toArrow: "" }, { isPanelMain: true },
        new go.Binding("toArrow", "toArrow"),
        new go.Binding("angle", "angle"),
        new go.Binding("strokeWidth", "thick"),
        new go.Binding("fill", "fill"),
        new go.Binding("stroke", "color"),
        new go.Binding("isPanelMain", "isPanelMain")
      )
    );
	

We are overriding ‘LinkDrawn’ event method to change few values of linkData which are binding in the template.

What are those link data properties that you modify in the “LinkDrawn” listener, and how?
Presumably you don’t set data.points, and you should not set it – that is what the TwoWay Binding is for.

In summary, below is what we are doing at LinkDrawn

linkData["fromPort"] = //
linkData["color"] = //
linkData["thick"] = //
linkData["from"] = //
linkData["fromPort"] = //
linkData["to"] = //
linkData["toPort"] = //
linkData["thick"] = //
myDiagram.model.removeLinkData(myDiagram.model.linkDataArray[lastId]);
myDiagram.model.addLinkData(linkData);
myRouter.avoidOrthogonalOverlaps(e.diagram.links, e.diagram.nodes);

If you add a link data object to the model, it won’t have any route yet before you call avoidOrthogonalOverlaps, which depends on all of the links already having their routes.

After adding that new link data object, call Diagram.findLinkForData to find the Link and call Link.updateRoute on it. Then call avoidOrthogonalOverlaps.

Do you need to set fromPort twice on the new link data object?

Why remove the new link data object when you could just modify it?

Thanks walter. I tried both ways you advised and in the end I removed all extra stuff from the LinkDrawn method. Now it only contains one line.

myRouter.avoidOrthogonalOverlaps(myDiagram.links, myDiagram.nodes)

I am still getting the crooked link
image
and I can still double click the bottom left corner of link to straight it out.
image

OK, it is good that you have confirmed that you didn’t have to remove and add a link to reproduce the problem.

Nevertheless, my point about the newly drawn link not having a proper route yet is still true, so it is too early to call the router to avoid link segment overlaps. I’ll look into reproducing the problem and finding a solution.

I used a simplified version of your link template but was unable to reproduce any problem. Here’s the complete code:

<!DOCTYPE html>
<html>
<head>
  <title>Minimal AvoidsLinksRouter test</title>
  <!-- Copyright 1998-2022 by Northwoods Software Corporation. -->
</head>
<body>
  <div id="myDiagramDiv" style="border: solid 1px black; width:100%; height:400px"></div>
  <p>
    Draw a new link from the bottom of Beta to the bottom of Delta.
    The router doesn't modify the (only) link's route.
  </p>
  <p>
    OR, first draw a new link from the bottom of Alpha to the top of Gamma, and then
     draw a new link from the bottom of Beta to the bottom of Delta.
     Both links will be shifted by the router.
  </p>
  
  <script src="go.js"></script>
  <script src="AvoidsLinksRouter.js"></script>
  <script id="code">
const $ = go.GraphObject.make;

const myDiagram =
  $(go.Diagram, "myDiagramDiv",
    {
      "LayoutCompleted": e => myRouter.avoidOrthogonalOverlaps(e.diagram.links),
      "SelectionMoved": e => myRouter.avoidOrthogonalOverlaps(e.diagram.links),
      "LinkDrawn": e => myRouter.avoidOrthogonalOverlaps(e.diagram.links),
      "undoManager.isEnabled": true
    });

const myRouter = new AvoidsLinksRouter();

myDiagram.nodeTemplate =
  $(go.Node, "Auto",
    { width: 100, height: 50 },
    new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
    $(go.Shape,
      { fill: "white" },
      new go.Binding("fill", "color")),
    $(go.TextBlock,
      new go.Binding("text")),
    $(go.Shape,
      {
        width: 8, height: 8, fill: "white",
        alignment: go.Spot.Top,
        portId: "T", fromSpot: go.Spot.Top, toSpot: go.Spot.Top,
        fromLinkable: true, toLinkable: true, cursor: "pointer"
      }),
    $(go.Shape,
      {
        width: 8, height: 8, fill: "white",
        alignment: go.Spot.Bottom,
        portId: "B", fromSpot: go.Spot.Bottom, toSpot: go.Spot.Bottom,
        fromLinkable: true, toLinkable: true, cursor: "pointer"
      })
  );

myDiagram.linkTemplate =
  $(go.Link,
    {
      routing: go.Link.Orthogonal,
      corner: 5,
      curve: go.Link.JumpOver,
      relinkableFrom: true, relinkableTo: true,
      reshapable: true,
      resegmentable: true,
      //mouseEnter: function(e, link) { link.path.strokeWidth=14},
      //mouseLeave: function(e, link) { link.path.strokeWidth=4}
    },
    new go.Binding("routing", "routing"),   
    new go.Binding("points").makeTwoWay(),
    $(go.Shape,
      //{ isPanelMain: true, stroke: "transparent" },
      //new go.Binding("pathPattern", "patt", convertPathPatternToShape),
      new go.Binding("stroke", "color"), 
      new go.Binding("strokeWidth", "thick"),
      new go.Binding("fill", "fill"),
      new go.Binding("isPanelMain", "isPanelMain")
    ),
    $(go.Shape,
      { toArrow: "" }, //{ isPanelMain: true },
      new go.Binding("toArrow", "toArrow"),
      new go.Binding("angle", "angle"),
      new go.Binding("strokeWidth", "thick"),
      new go.Binding("fill", "fill"),
      new go.Binding("stroke", "color"),
      //new go.Binding("isPanelMain", "isPanelMain")
    )
  );

myDiagram.model = new go.GraphLinksModel(
  {
    linkFromPortIdProperty: "fpid",
    linkToPortIdProperty: "tpid",
    nodeDataArray: [
      { key: 1, text: "Alpha", color: "lightblue", loc: "0 0" },
      { key: 2, text: "Beta", color: "orange", loc: "120 0" },
      { key: 3, text: "Gamma", color: "lightgreen", loc: "200 210" },
      { key: 4, text: "Delta", color: "pink", loc: "180 70" }
    ],
    linkDataArray: [
      //{ from: 1, fpid: "B", to: 3, tpid: "T" }
    ]
  });
  </script>
</body>
</html>

Note that I don’t understand the complexity of your link template, which is part of the reason that I simplified it.

In version 3 of GoJS, there is an improved AvoidsLinksRouter. Dynamic Ports