Changing zOrder for Panel on Link on LayeredDiagraphLayout

I am trying to configure my GoJS diagram (using LayeredDiagraphLayout) such that the panels showing a link’s label (in this example it displays a percentage) is always at the foreground, in front of all other items on the diagram. Currently, it is displaying with some link lines in front of the panels (as shown in this image):
diagram example

My goal:

To ensure that panels displaying percentages are always visible in front of everything else.

What I’ve Tried So Far:

Bringing the links into the Foreground layer (as suggested here):

myDiagram.linkTemplate =
  $$(go.Link,
    { routing: go.Link.AvoidsNodes, curve: go.Link.JumpGap, corner: 5, layerName:"Foreground" },
    $$(go.Shape, { strokeWidth: 3, stroke: "#555" }),
    $$(go.Panel, "Auto", // this whole Panel is a link label
      $$(go.Shape, "RoundedRectangle", { fill: "lightgray", stroke: "gray" }),
      $$(go.TextBlock, { margin: 3 },
        new go.Binding("text", "ownership"))
    )
  );

Assigning a zOrder directly to the go.Panel, go.Shape, and go.TextBlock items seen in the code above, however, all gave errors like this: Uncaught Error: Trying to set undefined property "zOrder" on object: Shape(RoundedRectangle). According to the documentation, Part extends Panel, so I expected that I would be able to assign a zOrder to a Panel, but it is giving this error, so apparently my expectations were wrong.

How can I configure this diagram such that the Panel on the Link is always at the foreground and therefore always visible in front of everything else? Thank you!

Part.zOrder is defined on the Part class, not on each GraphObject. And you don’t need it anyway, because the layout will make sure that the links don’t cross over or under any nodes.

I suggest that you set { segmentIndex: -2 } on those labels. If the labels are too tall, as they seem to be in your screenshot, you may need to increase the spacing between the layers, or increase the toEndSegmentLength.

Thank you Walter! My issue is that the other links are crossing over on top of the link labels, as seen with the “70.1%” label that is partially obscured by the link going from “JKL” to “MNO”. Would that be resolved by what you are suggesting?

Yes, I’m hoping so if you either increase the LayeredDigraphLayout.layerSpacing or the Link.toEndSegmentLength. Try it!

Will do, thank you again!

Hi Walter,

I tried your suggestion (setting layerSpacing: 40 and toEndSegmentLength: 0) and it worked in the one example I had shared but the two others shown below were not addressed. Does it seem like I screwed up your instructions?



May I see your link template and layout declarations, please?

Of course, thanks again!

var $$ = go.GraphObject.make;

model = $$(go.GraphLinksModel);

myDiagram =
  $$(go.Diagram, "myDiagramDiv",
    {
      initialContentAlignment: go.Spot.Top,
      initialAutoScale: go.Diagram.UniformToFill,
      layout: $$(go.LayeredDigraphLayout,
        { direction: 90, layerSpacing: 40 }),
      "undoManager.isEnabled": true
    }
  );

myDiagram.nodeTemplate =
  $$(go.Node, "Auto",
    {
      click: function(e, obj) {
        window.open(encodeURIComponent(obj.data.key));
      }
    },
    { zOrder: 100 },
    $$(go.Shape, "RoundedRectangle",
      { fill: "brown" }
    ),
    $$(go.TextBlock, "Default Text",
      { margin: 12, stroke: "white", font: "bold 16px sans-serif" },
      new go.Binding("text", "name")
    )
  );

myDiagram.linkTemplate =
  $$(go.Link,
    { routing: go.Link.AvoidsNodes, curve: go.Link.JumpGap, corner: 5, layerName:"Foreground", toEndSegmentLength: 0 },
    $$(go.Shape, { strokeWidth: 3, stroke: "#555" }),
    $$(go.Panel, "Auto", // this whole Panel is a link label
      $$(go.Shape, "RoundedRectangle", { fill: "lightgray", stroke: "gray" }),
      $$(go.TextBlock, { margin: 3 },
        new go.Binding("text", "ownership"))
    )
  );

You still haven’t set:

on the Panel that is your link label.
https://gojs.net/latest/intro/linkLabels.html#LinkLabelSegmentIndexAndSegmentFraction

Hmmm, from your screenshots, I guess it’s going to be more complicated than placing the label near (but not at) the “to” end of the link. That’s because you don’t want to do that when there are multiple links coming into the same node. In such a case you’d rather have the label be at the “from” end, i.e. at { segmentIndex: 1 }.

Well, see if setting segmentIndex helps in at least some of the cases.

I think your edit nailed this issue, but I’ll provide screenshots anyway. Is there a way to address this? It worked in one case but not in the other.


Does this demonstrate what you want? You’ll need to adapt the code for your own purposes.

  function init() {
    var $ = go.GraphObject.make;

    myDiagram =
      $(go.Diagram, "myDiagramDiv",
        {
          layout: $(go.LayeredDigraphLayout, { direction: 90 }),
          "LayoutCompleted": function(e) {
            e.diagram.links.each(function(l) { l.elt(1).segmentIndex = -Infinity; });
            e.diagram.nodes.each(function(n) {
              var outs = n.findLinksOutOf();
              var ins = n.findLinksInto();
              if (outs.count === 1) outs.first().elt(1).segmentIndex = 1;
              else if (ins.count === 1) ins.first().elt(1).segmentIndex = -2;
            });
          },
          "undoManager.isEnabled": true
        });

    myDiagram.nodeTemplate =
      $(go.Node, "Auto",
        $(go.Shape,
          { fill: "white", portId: "", fromLinkable: true, toLinkable: true, cursor: "pointer" },
          new go.Binding("fill", "color")),
        $(go.TextBlock,
          { margin: 8 },
          new go.Binding("text"))
      );

    myDiagram.linkTemplate =
      $(go.Link,
        { routing: go.Link.Orthogonal, corner: 5 },
        $(go.Shape),
        $(go.TextBlock, "label")
      );

    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" },
      { key: 5, text: "Epsilon", color: "yellow" }
    ],
    [
      { from: 1, to: 2 },
      { from: 1, to: 3 },
      { from: 4, to: 1 },
      { from: 5, to: 1 }
    ]);
  }

I’ll give this a try, thank you!

@Walter This worked beautifully, thank you so much!