Temporary link starting point

I need to increase the selectable area for a small port,
From
image

To
image

I have added a wrapper shape (light blue) over the blue dot and made it the new port. But the problem now is the temporary edge is starting from the center of Rectangle (as default behaviour)
I want the to shift the starting point of temporary link to the blue dot.

Could you please share with us your port definition?


     $(
        go.Panel,
        go.Panel.Auto,
        {
          alignment: getAlignment(item.align, item.alignOffset),
          alignmentFocus: getAlignment(item.align),
          portId: "L",
          fromLinkable: true,
          toLinkable: true,
          cursor: "pointer",
          desiredSize: [Align.LEFT, Align.RIGHT].includes(item.align)
            ? new go.Size(14, 28)
            : new go.Size(28, 14),
        },
        // transparent Panel for easy port selection
        $(go.Shape, {
          fill: "transparent",
          stroke: null,
        }),
        // Blue dot
        $(
          go.Shape,
          "Circle",
          {
            name: PORT_DOT,
            desiredSize: new go.Size(7, 7),
            stroke: null,
            alignment: getAlignment(item.align),
            opacity: 1
          }
        )
      )

This is the code for blue-dot and its wrapper (port)

Does your model support multiple ports per node?

Well, under the assumption that you have set GraphLinksModel.linkFromPortIdProperty and linkToPortIdProperty, here’s a sample which supports the user drawing a new link from something that contains the port that you actually want to be connected by the new link.

Basically, it defines a dummy port whose identifier is prefixed with “_”. When the LinkingTool finishes successfully, the “LinkDrawn” DiagramEvent is raised. In such a listener it reconnects the link to come from the intended port rather than from the dummy port.

<!DOCTYPE html>
<html>
<head>
  <title>Minimal GoJS Sample</title>
  <!-- Copyright 1998-2024 by Northwoods Software Corporation. -->
</head>
<body>
  <div id="myDiagramDiv" style="border: solid 1px black; width:100%; height:600px"></div>
  <textarea id="mySavedModel" style="width:100%;height:250px"></textarea>

  <script src="https://unpkg.com/gojs"></script>
  <script id="code">
const myDiagram =
  new go.Diagram("myDiagramDiv",
    {
      // if the user drew a new link from one of the dummy ports,
      // reconnect the link with the intended port
      "LinkDrawn": e => {
        const link = e.subject;
        const pid = link.fromPortId;
        if (pid.startsWith("_")) {
          link.fromPortId = pid.substring(1);
        }
      },
      "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();
        }
      }
    });

const $ = go.GraphObject.make;
myDiagram.nodeTemplate =
  new go.Node("Spot")
    .add(
      new go.Shape({ fill: "white" })
        .bind("fill", "color"),
      new go.TextBlock({ margin: 8 })
        .bind("text"),
      $(go.Panel, go.Panel.Auto,
        {
          alignment: go.Spot.Right,
          alignmentFocusName: "DOT",
          portId: "_R",  // a dummy port name is the real port name prefixed with "_"
          fromLinkable: true,
          cursor: "pointer",
          desiredSize: new go.Size(14, 28),
        },
        // transparent Panel for easy port selection
        $(go.Shape, {
          fill: "transparent",
          stroke: null,
        }),
        // Blue dot
        $(go.Shape, "Circle",
          {
            name: "DOT",
            portId: "R",
            fromLinkable: true,
            toLinkable: true,
            cursor: "pointer",
            desiredSize: new go.Size(7, 7),
            stroke: null,
            alignment: go.Spot.Right,
            opacity: 1
          }
        )
      )
    );

myDiagram.model = new go.GraphLinksModel(
  {
    linkFromPortIdProperty: "fp",
    linkToPortIdProperty: "tp",
    nodeDataArray:
      [
        { key: 1, text: "Alpha", color: "lightblue" },
        { key: 2, text: "Beta", color: "orange" },
        { key: 3, text: "Gamma", color: "lightgreen" },
        { key: 4, text: "Delta", color: "pink" }
      ]
  });
  </script>
</body>
</html>

The issue is not with the drawn link, these are working fine as the node itself is a port and this dot is just for representational purposes, I just want to move the center point of the temporary-link which I have set using linkingTool.**temporaryLink**.
The below image shows the temporary link(blue) and I want it to start from blue dot (like red link) only while drawing the link and not after the link is drawn.

OK, so I’ll assume that you are not using different ports on each node, and that your question only involves the temporaryLink used by the LinkingTool (or RelinkingTool, maybe).

So I have modified your code in my node template so that the port-like panel has a name that is the portId of the actual port object prefixed with “". I have overridden LinkingTool.findLinkablePort so that when the user starts drawing a new link from that transparent Shape it finds that Panel whose name is prefixed with "”, which causes that method to return the actual port object whose portId is the rest of that name. That way the LinkingTool operates thinking it’s drawing a new link from that little circular object.

But because you aren’t actually using multiple ports on nodes (because the GraphLinksModel doesn’t support links with particular port identifiers), the actual Link created between the Nodes will only connect with the default port on each Node (Node.port), which is either the port whose portId is the empty string or else (if no such element) the whole Node.

<!DOCTYPE html>
<html>
<head>
  <title>Minimal GoJS Sample</title>
  <!-- Copyright 1998-2024 by Northwoods Software Corporation. -->
</head>
<body>
  <div id="myDiagramDiv" style="border: solid 1px black; width:100%; height:600px"></div>
  <textarea id="mySavedModel" style="width:100%;height:250px"></textarea>

  <script src="https://unpkg.com/gojs"></script>
  <script id="code">
const myDiagram =
  new go.Diagram("myDiagramDiv",
    {
      "linkingTool.findLinkablePort": function() {
        const diagram = this.diagram;
        let obj = this.startObject;
        if (obj === null) {
          obj = diagram.findObjectAt(diagram.firstInput.documentPoint,
              obj => {
                while (obj && obj.name[0] !== "_") obj = obj.panel;
                if (obj && obj.name[0] === "_") return obj;
                return null;
              });
          if (obj === null) return null;
          this.startObject = obj.part.findPort(obj.name.substring(1));
        }
        return go.LinkingTool.prototype.findLinkablePort.call(this);
      },
      "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();
        }
      }
    });

const $ = go.GraphObject.make;
myDiagram.nodeTemplate =
  new go.Node("Spot")
    .add(
      new go.Shape({ fill: "white" })
        .bind("fill", "color"),
      new go.TextBlock({ margin: 8 })
        .bind("text"),
      $(go.Panel, go.Panel.Auto,
        {
          alignment: go.Spot.Right,
          alignmentFocusName: "DOT",
          name: "_R",  // a dummy port name is the real port name prefixed with "_"
          cursor: "pointer",
          desiredSize: new go.Size(14, 28),
        },
        // transparent Panel for easy port selection
        $(go.Shape, {
          fill: "transparent",
          stroke: null,
        }),
        // Blue dot
        $(go.Shape, "Circle",
          {
            name: "DOT",
            portId: "R",
            fromLinkable: true,
            toLinkable: true,
            cursor: "pointer",
            desiredSize: new go.Size(7, 7),
            stroke: null,
            alignment: go.Spot.Right,
            opacity: 1
          }
        )
      )
    );

myDiagram.model = new go.GraphLinksModel(
  {
    // linkFromPortIdProperty: "fp",
    // linkToPortIdProperty: "tp",
    nodeDataArray:
      [
        { key: 1, text: "Alpha", color: "lightblue" },
        { key: 2, text: "Beta", color: "orange" },
        { key: 3, text: "Gamma", color: "lightgreen" },
        { key: 4, text: "Delta", color: "pink" }
      ]
  });
  </script>
</body>
</html>