Incremental event don't fire


#1

this code, after click button reload Json it will emit errors “Change not within a transaction: !d position: -1 old: Point(54,54) new: Point(66,67)…” and don’t fire any changed event.

var diajson = `
  {
    "nodeDataArray": [
      {
        "loc": "50 50",
        "text": "new node"
      }
    ],"linkDataArray": [],"linkKeyProperty": "id","class": "go.GraphLinksModel"
  }
  `;

  var $go = go.GraphObject.make;  // for conciseness in defining templates
  var diagramA =
    $go(go.Diagram, "DDiv",  // must name or refer to the DIV HTML element
      {
        hasHorizontalScrollbar: false, "animationManager.isEnabled": false,
        hasVerticalScrollbar: false,
        initialAutoScale: go.Diagram.Uniform,
        "toolManager.mouseWheelBehavior": go.ToolManager.WheelZoom,
        "undoManager.isEnabled": true, // enable Ctrl-Z to undo and Ctrl-Y to redo
      });

  // define the Node template
  diagramA.nodeTemplate =
    $go(go.Node, "Vertical", { resizable: true },
      new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
      $go(go.Panel, "Spot", 
				$go(go.Shape, "Rectangle", {
				    width: 80, height: 80, margin: 4, fill: "#99bce8", cursor: "pointer"
        })),
			$go(go.TextBlock, {
					margin: 5, editable: true, textAlign: "center",
					font: '13px Verdana, Arial, sans-serif,"ヒラギノ角ゴ Pro W3","メイリオ","Meiryo","Helvetica Neue","Helvetica"'
				},
				new go.Binding("text", "text").makeTwoWay()
			)
    );

  diagramA.addDiagramListener("Modified", digmModified);

  function digmModified(e) {
			console.log( ">>Modified Diagram<<: "+ e.diagram.diagramKey + " " + e.diagram.isModified);
	}

  diagramA.addModelChangedListener(function(evt) {
    // ignore unimportant Transaction events
    if (!evt.isTransactionFinished) return;
    var json = evt.model.toIncrementalJson(evt);
    if (evt.oldValue == "Initial Layout") return;
    console.log(json);
    console.log(">>>>>>>>>>>>>>>>>>>>>" + evt.oldValue);
    var txn = evt.object;  // a Transaction
    if (txn === null) return;
  });

  diagramA.model = go.Model.fromJson(diajson);

  $("#loadbtn").click(function(){
    diagramA.model = go.Model.fromJson(diajson);
    diagramA.delayInitialization(
      function () {
        diagramA.zoomToFit();
      }
    );
  });

why I use delayInitialization to call diagram.zoomToFit(); is, sometimes some diagram not fit zoom at the first time load json.


#2

Because you have set Diagram.initialAutoScale, you don’t need to call Diagram.zoomToFit. I’m not sure why making that call is causing a problem, but you shouldn’t be calling it anyway.

Here’s what I tried, which is basically your code with a second node (to make it obvious that it had to scale down in order to fit initially within the viewport). Note that I have removed the call to Diagram.delayInitialization.

<script src="go.js"></script>
<script id="code">
  function init() {
    var $go = go.GraphObject.make;  // for conciseness in defining templates
    diagramA =
      $go(go.Diagram, "myDiagramDiv",  // must name or refer to the DIV HTML element
        {
          hasHorizontalScrollbar: false,
          hasVerticalScrollbar: false,
          initialAutoScale: go.Diagram.Uniform,
          "animationManager.isEnabled": false,
          "toolManager.mouseWheelBehavior": go.ToolManager.WheelZoom,
          "undoManager.isEnabled": true, // enable Ctrl-Z to undo and Ctrl-Y to redo
        });

    // define the Node template
    diagramA.nodeTemplate =
      $go(go.Node, "Vertical", { resizable: true },
        new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
        $go(go.Panel, "Spot",
          $go(go.Shape, "Rectangle", {
            width: 80, height: 80, margin: 4, fill: "#99bce8", cursor: "pointer"
          })),
        $go(go.TextBlock, {
          margin: 5, editable: true, textAlign: "center",
          font: '13px Verdana, Arial, sans-serif,"ヒラギノ角ゴ Pro W3","メイリオ","Meiryo","Helvetica Neue","Helvetica"'
        },
          new go.Binding("text", "text").makeTwoWay()
        )
      );

    diagramA.addDiagramListener("Modified", digmModified);

    function digmModified(e) {
      console.log(">>Modified Diagram<<: " + e.diagram.diagramKey + " " + e.diagram.isModified);
    }

    diagramA.addModelChangedListener(function(evt) {
      // ignore unimportant Transaction events
      if (!evt.isTransactionFinished) return;
      var json = evt.model.toIncrementalJson(evt);
      if (evt.oldValue == "Initial Layout") return;
      console.log(json);
      console.log(">>>>>>>>>>>>>>>>>>>>>" + evt.oldValue);
      var txn = evt.object;  // a Transaction
      if (txn === null) return;
    });

    diagramA.model = go.Model.fromJson(diajson);
  }

  var diajson = `
  {
    "nodeDataArray": [
      {
        "loc": "50 50",
        "text": "new node"
      },
      {
        "loc": "50 1050",
        "text": "node 2"
      }
    ],
    "linkDataArray": [],
    "linkKeyProperty": "id",
    "class": "go.GraphLinksModel"
  }
  `;

  function reload() {
    diagramA.model = go.Model.fromJson(diajson);
  }
</script>
</head>
<body onload="init()">
  <div id="myDiagramDiv" style="border: solid 1px black; width:100%; height:600px"></div>
  <button onclick="reload()">reload</button>
</body>

#3

why I use delayInitialization to call diagram.zoomToFit(); is, sometimes some diagram not fit zoom at the first time load json. it happened at first time after first time Json loading everything Ok. reload refresh json it fitzoom no problem. real code is most long and complicated I can’t Paste here. now I just call delayInitialization at first time ones it works , but it just work around. i know delete delayInitialization will no problem to fire all change event.


#4

Are you sure that the diagram’s HTML DIV element has the correct size at the time that the first diagram initialization happens? If an HTML page layout happens later, there is no way to be notified about a size change of an HTML element (other than the whole window), so you would need to call Diagram.requestUpdate. Please read https://gojs.net/latest/intro/resizing.html and see if that situation applies to your app.


#5

After thinking I figure out what the real reason at the first time not to fit zoom. I use some picture on diagram, at the first time picture not loaded to diagram, it takes some time at network loading. so diagram can’t correctly calculate the bound size. at the second time browser cache the image, so image quickly shown on diagram, bound size calculated correctly. I decide , set the size first on picture frame, for example , width: 80, height: 80 then it works!! I don’t need to call delayInitialization or zoomToFit any more. thanks.