diagram.isModified property set when diagram is replaced

I have a canvas that I will replace the diagram when a user loads it.
In fact I replace the both diagram and assign a new model to the diagram.

I do this as follows:

if (myDiagram !== undefined)
{
	myDiagram.div = null;  // just in case the diagram has been set
}

myDiagram =
  $(go.Diagram, "myDiagramDiv"
	, {
	  "undoManager.isEnabled": true
	  , allowDrop: true

etc.

I set the new data model afterwards using:

myDiagram.model = diagramModel;  

It seems that the line that sets: myDiagram = $(go.Diagram, “myDiagramDiv”
sets the isModified property to true when there was previously a diagram.
And also the property is not reset on assignment of the data model

How can I prevent this property being set to true, because the diagram is not modified?

Here’s what I tried. I do not understand what the problem is.

<!DOCTYPE html>
<html>
<head>
  <title>Minimal GoJS Sample</title>
  <!-- Copyright 1998-2022 by Northwoods Software Corporation. -->
</head>
<body>
  <div id="myDiagramDiv" style="border: solid 1px black; width:100%; height:400px"></div>
  <button id="myTestButton">Test</button>

  <script src="go.js"></script>
  <script id="code">
function init() {
  const $ = go.GraphObject.make;

  myDiagram =
    $(go.Diagram, "myDiagramDiv",
      {
        "undoManager.isEnabled": true,
        "Modified": e => console.log("Modified:" , e.diagram.isModified),
      });
  console.log("init1:", myDiagram.isModified)

  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, editable: true },
        new go.Binding("text").makeTwoWay())
    );
  console.log("init2:", myDiagram.isModified)

  myDiagram.model = new go.GraphLinksModel(
  [
    { key: 1, text: "Alpha", color: "lightblue" },
    { key: 2, text: "Beta", color: "orange" },
  ],
  [
    { from: 1, to: 2 },
  ]);
  console.log("init3:", myDiagram.isModified)
}

document.getElementById("myTestButton").addEventListener("click", e => {
  myDiagram.div = null;
  init();
  setTimeout(() => console.log("afterwards:", myDiagram.isModified), 1000);
});

const $ = go.GraphObject.make;

var myDiagram =
  $(go.Diagram, "myDiagramDiv",
    {
      "undoManager.isEnabled": true,
      model: new go.GraphLinksModel(
        [
          { key: 1, text: "Alpha" },
          { key: 2, text: "Beta" }
        ], [
          { from: 1, to: 2 }
        ])
    });
  </script>
</body>
</html>

I’m assuming that what happens to the original diagram, before calling init(), doesn’t matter for this discussion. It’s just the state of the second diagram that you are asking about.

I get the results:

init1: false
init2: true
init3: true
Modified: false
afterwards: false

OK. So the first thing that I’m not getting here is:

After “init3”. is printed: what is causing the Modified event to trigger? There is no code that does anything to the diagram after init.

In fact, your code shows what is exactly my problem, I thought after reassigning the model, the Modifed state should be false, so I would expect: init3: to print false.

Well, if nothing else, my init code is at least setting Diagram.nodeTemplate, so the Diagram has clearly been modified.

Yes, to meet your general expectations, which are perfectly reasonable, Diagram.isModified is set to false after the initial transaction, after the “InitialLayoutCompleted” DiagramEvent. But it’s done outside of the transaction, which is why one is not supposed to make any changes to a Diagram or Model from a “Modified” DiagramEvent.

There are a lot of places in the code which set Diagram.isModified to true, of course, but I think that is the only place where it is set to false, other than in the Diagram constructor.

The documentation for Diagram.isModified
here: Diagram | GoJS API
says:

" Replacing the model automatically sets this property to false after the initial layout has completed."

In your example, you replace the model, but straight after that: console.log(“init:3”… ) the print out gives “true” but according to the documentation, should it not be “false”?

Or is it printing “true” because the layout is not yet complete? And does that mean if I wish to find out if the diagram is modified, I need to check in the Modified event handler?

That is correct: setting the Diagram.model property causes an initial layout to happen soon after. Not synchronously. That permits other changes to happen without requiring repeated layouts.