Avoid nodes within a group

I am trying to make a nested diagram with groups and ports. I started with ports on the edge that can connect to objects outside the group and within. This mostly works, except that links don’t seem to avoid the nodes in the group.
Changed it to have ports both inside and outside, but that did not solve my problem either.

I would expect the link between the two blue ports to be drawn around the blue nodes inside the group.
Any suggestion? Rob

Yes, link routing to avoid nodes should work within groups. However, a link that goes from a port on a node (in this case a group) to another port on the same node doesn’t know that it should be affected by the nodes inside the group.

In this case it just thinks that it’s crossing the node and that node (which in this case is a group, but it doesn’t care about that) should be avoided. But that node cannot be avoided because the link starts and ends within the node, so it just uses the default orthogonal routing.

You might be able to avoid the problem by putting those blue internal ports into their own two nodes that are members of the group. The appearance need not change if you design those two nodes the right way.

Ah, yes. I hadn’t realized that conceptually that cross-over could not avoid touching the group. So I probably was on the right track adding those blue ports, but hadn’t thought about doing a node for them. That may actually make part of my life easier.

Hmm… the “design the right way” seems part of my challenge ;-) I would need those nodes with blue ports to be placed at exact location in the surrounding group, not just anywhere in the diagram. Should I create another level of grouping to build a simple stack of the two extra nodes with the blue ports plus the group that contains the actual objects?

Your Group.layout needs to position those two special nodes at the top and at the bottom. Have you set Group.layout in your Group template?

If not, you’ll need to define a custom Layout that computes the area of all of the member nodes excluding your two special nodes, and then positions those two appropriately.

If so, you’ll need to customize that layout so that you get the right effect. That depends on the layout you are using.

I have a LayeredDigraphLayout for the diagram and for the groups, because that suited the notion best. Sounds like there is even more to learn… -Rob

Try this:

  // Assume each layout includes at most one "Inputs" node and at most one "Outputs" node,
  // and that they are (respectively) an ultimate source and an ultimate sink for all of the other nodes.
  // In other words, this assumes there are no other nodes in any layer with an "Input" or an "Output" node.
  function InputOutputLayeredDigraphLayout() {
    go.LayeredDigraphLayout.call(this);
  }
  go.Diagram.inherit(InputOutputLayeredDigraphLayout, go.LayeredDigraphLayout);

  InputOutputLayeredDigraphLayout.prototype.commitLayout = function() {
    go.LayeredDigraphLayout.prototype.commitLayout.call(this);
    // after the usual layout, move any "Inputs" and "Outputs" nodes to be
    // at the horizontal center of their respective layers.
    var bounds = this.diagram.computePartsBounds(this.network.findAllParts());
    this.network.vertexes.each(function(v) {
      var n = v.node;
      if (n === null) return;
      // assume there's at most one such node in each category
      if (n.category === "Inputs" || n.category === "Outputs") {
        n.position = new go.Point(bounds.centerX - n.actualBounds.width / 2, n.position.y);
      }
    });
  };

Assign an instance of this to your Group.layout (and optionally to the Diagram.layout).

Thank you. I have not ignored your response, but realize this was a boundary case and I want to get some other parts going first…