Need to lock a go.Link.AvoidsNodes Link in position and not reroute when objects are dropped on or near it

Hi all, I am struggling with this. I need to allow the user to lock a node or link in place in the drawing.

I am using Orthogonal routing with go.Link.AvoidsNodes.

Expanding on the intro Links topic I am doing this:

 diagram.nodeTemplate =
    $(go.Node, "Auto",
      new go.Binding("location", "loc", go.Point.parse),
	  
		new go.Binding("movable", "lockPosition", function (p, s) { //my binding to the lockPosition property we are trying to implement for nodes
            s.resizable = !p;
            s.rotatable = !p;
            return !p;
        }),
      $(go.Shape, "RoundedRectangle", { fill: "lightgray" }),
      $(go.TextBlock, { margin: 5 },
        new go.Binding("text", "key"))
    );

  diagram.linkTemplate =
    $(go.Link,
      { routing: go.Link.AvoidsNodes }, // link route should avoid nodes
		new go.Binding("movable", "lockPosition", function (p, s) { //my binding to the lockPosition property we are trying to implement for links
            s.reshapable = !p;
            s.resegmentable = !p;
            s.relinkableFrom = !p;
            s.relinkableTo = !p;
            return !p;
        }),	 
      $(go.Shape),
      $(go.Shape, { toArrow: "Standard" })
    );

  var nodeDataArray = [
    { key: "Alpha", loc: "0 0" , lockPosition: true},
    { key: "Beta", loc: "250 40" , lockPosition: true},
    { key: "Gamma", loc: "100 0" },
    { key: "Delta", loc: "75 50" },
    { key: "Epsilon", loc: "150 30" }
  ];
  var linkDataArray = [
    { from: "Alpha", to: "Beta", lockPosition:true }
  ];
  diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);

This kind of works until one of the unlocked nodes is dropped on or near our lockPosition link. Then the link is invalidated and redrawn.

I can’t seem to figure out how to block this behavior.

Any help would be appreciated.

Thanks!

Usually, that is the behavior that people want. But if you don’t like it, you could set Link.routing to go.Routing.Orthogonal, once you have a route that you want to keep.

Or maybe customize the DraggingTool to set that temporarily before dragging and set it back to go.Routing.AvoidsNodes afterwards. Hmmm, are you using v3+? Maybe you could get that effect by temporarily disabling the AvoidsNodesRouter and then re-enabling it after the drag. I haven’t tried that.

I agree that the default behavior works most of the time. Some of our users get upset that their carefully reshaped links are redrawn just because they dropped a new node near enough to invalidate the links.

I am back on v2. I’ve tried the go.Routing.Orthogonal approach thinking I could switch back and forth in the binding, but the link is invalidated upon switching. So, no go.

Try something like this:

class CustomDraggingTool extends go.DraggingTool {
  doActivate() {
    super.doActivate();
    this.diagram.links.each(l => {
      if (this.draggedParts.has(l.fromNode) || this.draggedParts.has(l.toNode)) return;
      l.suspendsRouting = true;
    });
  }
}
  function init() {
    myDiagram =
      new go.Diagram("myDiagramDiv",
        {
          draggingTool: new CustomDraggingTool(),
          "SelectionMoved": e => e.diagram.links.each(l => l.suspendsRouting = false),
          "SelectionCopied": e => e.diagram.links.each(l => l.suspendsRouting = false),
          . . .

Does that work with v2?

I am guessing so, but I haven’t tried it. Of course that property is not officially defined in the API, but it is in the go.d.ts file, so it will probably keep working for the foreseeable future.

That was the tidbit I needed.

I moved it into the binding function and it works a treat.

Thanks!