Issues with go.Link.AvoidsNodes


#1

GoJS 1.8 in Angular 6

Hi,

First of all, thank for this amazing library !!

I’m trying to link some nodes with go.Link.AvoidsNodes but the links are getting over the node:

Can you help me please ?

// elements
const square = {
    width: 90,
    height: 90,
    inports: [],
    outports: [{ label: "OUT", x: 82, y: 38 }],
}
const rect = {
    width: 200,
    height: 240,
    inports: [{ label: "IN", x: 0, y: 107 }],
    outports: [
      { label: "PSV", x: 180, y: 32 },
      { label: "GAS", x: 0, y: 41 },
      { label: "OIL", x: 0, y: 190 },
      { label: "WAT", x: 0, y: 225 }
    ],
}
// config for all elements
makeElement(width, height, inports, outports): any {
    const node = go.GraphObject.make(
        go.Node,
        "Auto",
        { locationSpot: go.Spot.Center, rotatable: true },
        go.GraphObject.make(
          go.Panel,
          "Position",
          { width, height },
          go.GraphObject.make(go.Shape, "Rectangle", {
            fill: "blue",
            width,
            height,
            stroke: null,
            strokeWidth: 0,
            spot1: go.Spot.TopLeft,
            spot2: go.Spot.BottomRight
          }),
          go.GraphObject.make(
            go.Panel,
            "Position",
            inports.map((y) => {
                return this.makePort(y.label, new go.Point(y.x, y.y), "IN");
            })
          ),
          go.GraphObject.make(
            go.Panel,
            "Position",
            outports.map((y) => {
                return this.makePort(y.label, new go.Point(y.x, y.y), "IN");
            })
          )
        )
      );
      return node
}
// config for ports
  makePort(name, position, way): any {
    const port = go.GraphObject.make(go.Shape, "Rectangle", {
      fill: "gray",
      stroke: null,
      desiredSize: new go.Size(8, 8),
      portId: name,
      toMaxLinks: 1,
      cursor: "pointer"
    });
    const panel = go.GraphObject.make(go.Panel, "Horizontal", {
      margin: new go.Margin(2, 0)
    });
    port.toLinkable = way === "IN";
    port.fromLinkable = way === "OUT";
    panel.position = position;
    panel.add(port);
    return panel;
  }
// config for links
  linkTemplate(deletable): any {
    return go.GraphObject.make(
      go.Link,
      {
        routing: go.Link.AvoidsNodes,
        corner: 5,
        curve: go.Link.JumpOver,
        reshapable: true,
        resegmentable: true,
        relinkableFrom: true,
        relinkableTo: true,
        deletable
      },
      new go.Binding("fromSpot", "fromSpot", go.Spot.parse),
      new go.Binding("toSpot", "toSpot", go.Spot.parse),
      new go.Binding("points").makeTwoWay(),
      go.GraphObject.make(
        go.Shape,
        { stroke: "#2F4F4F", strokeWidth: 3 },
        new go.Binding("stroke", "stroke")
      ),
      go.GraphObject.make(
        go.Panel,
        "Auto",
        go.GraphObject.make(go.Shape, "Rectangle", {
          fill: "yellow",
          stroke: "gray"
        }),
        go.GraphObject.make(
          go.TextBlock,
          { margin: 5 },
          new go.Binding("text", "label")
        )
      )
    );
  }

Thanks !


#2

You don’t have a third Node present to be able to tell if the Link is being routed to avoid crossing over other nodes. AvoidsNodes routing does not include avoiding the two connected nodes. Imagine that the ports were inside their respective nodes even more than they are now. It would be impossible for the route to connect with the port without crossing over some piece of the node.

But you can fix the problem by setting GraphObject.fromSpot and toSpot on the port object created by makePort. For example, for those ports on the left side of the node, set both spots to go.Spot.Left.


#3

Thank you so much Walter !

  makePort(name, position, way): any {
    const port = go.GraphObject.make(go.Shape, "Rectangle", {
      fill: "gray",
      stroke: null,
      desiredSize: new go.Size(8, 8),
      portId: name,
      toMaxLinks: 1,
      cursor: "pointer"
    });
    const panel = go.GraphObject.make(go.Panel, "Horizontal", {
      margin: new go.Margin(2, 0)
    });
    port.toLinkable = way === "IN";
    port.fromLinkable = way === "OUT";
    panel.position = position;
    port.fromSpot = go.Spot.Left;
    port.toSpot = go.Spot.Left;
    panel.add(port);
    return panel;
  }

#4

You will want to set the spots for the ports on the right side of a node to be go.Spot.Right.