Link selection is getting registered in UndoManager on using Adornment

Hi,

I added Adornment to my link and set its layerName to Background as wanted to have Label on the link which is not passed through by the link when selected.

But the issue is, after adding selectionAdornmentTemplate property to my linkTemplate, on selecting the link, UndoManager registers it with the name “Layout”.

I want to avoid registering link selection on Undo/Redo.

My linkTemplate:

$(
  go.Link,
  {
    relinkableFrom: true,
    relinkableTo: true,
    reshapable: true,
    resegmentable: true,
    selectionAdornmentTemplate: $(
      go.Adornment,
      { layerName: 'Background' },
      $(go.Shape, { isPanelMain: true, stroke: sassVariables['colors-startEndNodeFill'], strokeWidth: 3.5 })
    ),
  },
  {
    routing: go.Link.AvoidsNodes,
    adjusting: go.Link.End,
    curve: go.Link.JumpOver,
    corner: 5,
    toShortLength: 4,
  },
  // link segments
  new go.Binding('points').makeTwoWay(),
  // link path shape
  $(go.Shape, linkPathStyle()),
  // link arrowhead
  $(go.Shape, linkArrowheadStyle()),
  linkLabelTemplate: $(
    go.Panel,
    'Auto', // this whole Panel is a link label
    $(
      go.Shape,
      'Rectangle',
      new go.Binding('fill', linkLabelBackgroundBinding),
      new go.Binding('stroke', linkLabelBackgroundBinding)
    ),
    $(go.TextBlock, new go.Binding('text', 'label'))
  ) // Link label
)

Thanks for any help!

I think the problem is that you assigned the Adornment to be in the “Background” Layer. Regular Layers, including “Background” and “” and “Foreground”, normally have all changes recorded in the UndoManager. Whereas the default layer for Adornments is “Adornment”, which has Layer.isTemporary set to true, so no changes to Parts in that layer get recorded by the UndoManager.

And one of normal side-effects of adding (or removing) a Link (or a Node) to a Diagram is to invalidate the Layout, which is why a layout is happening.

I assume that you wanted the Adornment to be behind the Link, so that it doesn’t occlude the link’s path. That’s OK – just create a new temporary layer that is behind whatever layer(s) the links are in.

<!DOCTYPE html>
<html>
<head>
  <title>Minimal GoJS Sample</title>
  <!-- Copyright 1998-2021 by Northwoods Software Corporation. -->
  <script src="https://unpkg.com/gojs"></script>
  <script id="code">
  function init() {
    var $ = go.GraphObject.make;

    myDiagram =
      $(go.Diagram, "myDiagramDiv");

    myDiagram.addLayerBefore(
      $(go.Layer, { name: "LinkAdornment", isTemporary: true }),
      myDiagram.findLayer("Background"));

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

    myDiagram.linkTemplate =
      $(go.Link,
        $(go.Shape),
        $(go.Shape, { toArrow: "Standard" }),
        {
          selectionAdornmentTemplate:
            $(go.Adornment,
              { layerName: "LinkAdornment" },
              $(go.Shape,
                {
                  isPanelMain: true,
                  stroke: "dodgerblue",
                  strokeWidth: 7
                })
            )
        }
      )

    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: 3, to: 4 }
    ]);
  }
  </script>
</head>
<body onload="init()">
  <div id="myDiagramDiv" style="border: solid 1px black; width:100%; height:600px"></div>
</body>
</html>

Then assign the selection Adornment’s layerName to be whatever name you chose for that new Layer.

image

1 Like

Hi Walter,
I added a new layer as you suggested and it works like a charm.
Thanks a lot!