I want Bi-Directional Linkages

As we see in the image, two nodes have two linkages. Instead, I want a single bi-directional link.

image

Have you specified any fromSpot or toSpot values?

Are you using a layout that is a TreeLayout or LayeredDigraphLayout? Those are directional layouts for which most people want particular directions for the links. You can set TreeLayout.setsPortSpot and TreeLayout.setsChildPortSpot, or LayeredDigraphLayout.setsPortSpots, to false.

Here’s a sample using LayeredDigraphLayout. You can draw new links or delete existing ones in order to play with the graph.

<!DOCTYPE html>
<html>

<head>
  <title>LayeredDigraphLayout.setsPortSpots</title>
  <!-- Copyright 1998-2025 by Northwoods Software Corporation. -->
</head>

<body>
  <div id="myDiagramDiv" style="border: solid 1px black; width:100%; height:450px"></div>
  <button id="myTestButton">Toggle Setting Port Spots</button>
  <textarea id="mySavedModel" style="width:100%;height:250px"></textarea>

  <script src="https://cdn.jsdelivr.net/npm/gojs/release/go-debug.js"></script>
  <script id="code">
const myDiagram =
  new go.Diagram("myDiagramDiv", {
      layout: new go.LayeredDigraphLayout(),
      "undoManager.isEnabled": true,
      "ModelChanged": e => {     // just for demonstration purposes,
        if (e.isTransactionFinished) {  // show the model data in the page's TextArea
          document.getElementById("mySavedModel").textContent = e.model.toJson();
        }
      }
    });

myDiagram.nodeTemplate =
  new go.Node("Vertical", {
      selectionObjectName: "CIRCLE",
      layerName: "Foreground",
      selectionAdorned: false,
      shadowOffset: new go.Point(0, 0),
      shadowBlur: 20,
      shadowColor: "black",
      locationSpot: go.Spot.Center,
    })
    .add(
      new go.Shape("Circle", {
          name: "CIRCLE",
          width: 50, height: 50, portId: "",
          fromLinkable: true,
          toLinkable: true,
          fromLinkableDuplicates: true,
          toLinkableDuplicates: true,
          cursor: "pointer"
        })
        .bind("fill", "color"),
      new go.TextBlock({
          maxSize: new go.Size(200, NaN),
          overflow: go.TextBlock.OverflowEllipsis,
          toolTip: go.GraphObject.build("ToolTip")
            .add(
              new go.TextBlock({ margin: 2 })
                .bind('text')
            )
        })
        .bind("text")
    );

myDiagram.linkTemplate =
  new go.Link({
      layerName: "Background",
      curve: go.Link.Bezier,
      selectionAdornmentTemplate:
        new go.Adornment('Link')
          .add(
            new go.Shape({ isPanelMain: true, strokeWidth: 3, stroke: "black" }),
            new go.Shape({ isPanelMain: true, strokeWidth: 3, stroke: "white", name: "PIPE", strokeDashArray: [10, 10] })
          ),
      fromEndSegmentLength: 40,
      toEndSegmentLength: 40,
      selectionChanged: onLinkSelect
    })
    .add(
      new go.Shape({ strokeWidth: 2 }),
      new go.Shape({ toArrow: "OpenTriangle", strokeWidth: 2 })
    );

function onLinkSelect(obj) {
  if (!obj.isSelected) return;
  setTimeout(() => {
    const animation = new go.Animation();
    animation.easing = go.Animation.EaseLinear;
    const pipe = obj.adornments.first().findObject("PIPE");
    animation.add(pipe, "strokeDashOffset", 20, 0)
    // Run indefinitely
    animation.runCount = Infinity;
    animation.start();
  }, 100);
}

myDiagram.model = new go.GraphLinksModel(
  [
    { key: 1, text: "1", color: "orange" },
    { key: 2, text: "2", color: "orange" },
    { key: 3, text: "3", color: "orange" },
    { key: 4, text: "4", color: "orange" },
    { key: 5, text: "5", color: "orange" },
    { key: 6, text: "6", color: "orange" },
    { key: 7, text: "7", color: "orange" },

    { key: 8, text: "8", color: "lightgreen" },
    { key: 9, text: "9", color: "lightgreen" },
    { key: 10, text: "10", color: "lightgreen" },
    { key: 11, text: "11", color: "lightgreen" },
    { key: 12, text: "12", color: "lightgreen" },
  ],
  [
    { from: 3, to: 2 },
    { from: 1, to: 3 },
    { from: 1, to: 4 },
    { from: 2, to: 5 },
    { from: 5, to: 6 },
    { from: 6, to: 2 },
    { from: 6, to: 7 },

    { from: 8, to: 9 },
    { from: 9, to: 10 },
    { from: 10, to: 11 },
    { from: 9, to: 11 },
    { from: 8, to: 12 },
  ]);

document.getElementById("myTestButton").addEventListener("click", e => {
  myDiagram.commit(d => {
    d.links.each(l => l.fromSpot = l.toSpot = go.Spot.Default);
    d.layout.setsPortSpots = !d.layout.setsPortSpots;
  });
});
  </script>
</body>
</html>