How can I create a new node when I drag a link as soon as I release my mouse?

Hi, thank you for your hard work, I have some problems when using ‘gojs’.
I found that when I drag a link from a node which already in canvas, I must drag it onto another node, otherwise the link will disappear when I release my mouse. How can I create a new node when I drag a link as soon as I release my mouse, and make the new node just at the place where the ‘mouse up’, and also make the link link-to the new node automatically?
Thank you !

I think you might be interested in this sample: Page Not Found -- Northwoods Software

As with almost all of our samples, the complete source code is in the page itself – perform a View Page Source command in your browser.

The basic idea is to override the LinkingTool.doNoLink method. That sample, when no link is made, shows a context menu that allows the user to choose to create a node right there along with a link to it. You could adapt the code so that the doNoLink override just creates the node and link immediately, without showing showing information and some buttons.
LinkingTool | GoJS API

The sample seems to be gone or it is at a new URL. Do you have a working sample?

I’m not sure what happened to that basic sample, but there’s another slightly more complex one here that has the same idea: Linking Failure Context Menu

1 Like

The basic idea is to override LinkingTool.doNoLink, which is called when the user lets go of the mouse when there is no valid link to be drawn, to actually create a node at that location and create the link anyway from the original port to the new node.

The only thing I’ve added here is the override of doNoLink.

<!DOCTYPE html>
<html>
<head>
  <title>Create Node at No Link Location</title>
  <!-- Copyright 1998-2025 by Northwoods Software Corporation. -->
</head>
<body>
  <div id="myDiagramDiv" style="border: solid 1px black; width:100%; height:400px"></div>
  <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", {
      // override without defining a new class requires a function, not =>
      "linkingTool.doNoLink": function (fromnode, fromport, tonode, toport) {
        if (fromnode && !tonode) {
          this.transactionResult = "drew a new node and link";
          const diagram = this.diagram;

          // new node data properties depend on your app's schema
          var nodedata = { text: "new", color: "lavender" };
          diagram.model.addNodeData(nodedata);
          var newnode = diagram.findNodeForData(nodedata);
          if (newnode !== null) newnode.location = diagram.lastInput.documentPoint;

          // new link data properties depend on your app's schema
          var linkdata = { from: fromnode.key, to: newnode.key };
          diagram.model.addLinkData(linkdata);
        }
      },
      "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("Auto")
    .add(
      new go.Shape({ fill: "white", portId: "", fromLinkable: true, toLinkable: true, cursor: "pointer" })
        .bind("fill", "color"),
      new go.TextBlock({ margin: 8 })
        .bind("text")
    );

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

Thank you!