Automatic Scale formula

Sometimes a diagram contains lots of nodes and links and some of them are not seen unless the user scroll vertically or horizontally in order to view them.
I’m looking for a formula to change to diagram scale automatically, so that all elements will be seen in the diagram DIV.
Any ideas ?

Set either Diagram.initialAutoScale or Diagram.autoScale to go.Diagram.Uniform. The former only applies just after loading a new Diagram.model (as do all of the Diagram.initial… properties); the latter applies after each transaction.


By the way, if i want to do it only once and then return to manual scale, i beleive that i have to set Diagram.autoScale to go.Diagram.Uniform and after some timeout() reset to value to None.
Right ?

That does not sound “automatic” to me, but rather “programmatic”. I think you want to call CommandHandler.zoomToFit: myDiagram.commandHandler.zoomToFit().

If i call myDiagram.commandHandler.zoomToFit() will it fit the view port only once and afterwards the user will be able to scale manually ?

That depends on whether you have set Diagram.autoScale or not.

In fact,
I have a diagram with groups.
As soon as i expand one group, i hide all groups and show the content of the expanded group.
At this stage, i would like to fit the group member nodes and links into screen BUT allow the user to scale the diagram (with CTRL+/-).
I tried to call zoomToFit() when the group is expanded, it worked fined but when i collapsed the group in order to show all other groups, the zoomToFit() remained and the groups are shown much smaller.
As soon as i close the group, i would like to restore the group size to the original size with autoScale capabilities like they were before the group was expanded.

Oh, I see – this is a much more complicated situation. It seems that after you have changed the expanded state of all of the groups, you only then want to zoomToFit().

Now I see what you mean about setting Diagram.autoScale and then turning it off after in a setTimeout function. Sure, that sounds like a good idea.

i’m not sure when to call the zoomToFilt() function ?
Right after the expanded transaction is committed ? before ?

If you are calling setTimeout, then it shouldn’t matter if you are calling it immediately before or immediately after any synchronous code to change state, That state-changing code is being performed within a transaction, isn’t it?

if i call the zoomToFit within the transaction it does not work.
Also, i i call it after committing.
It works only when i settimout(200) AFTER committing

OK, I’m glad you found a way to make it work.

FYI, I’m finding that this seems to work:

<!DOCTYPE html>
<title>Minimal GoJS Sample</title>
<!-- Copyright 1998-2019 by Northwoods Software Corporation. -->
<meta charset="UTF-8">
<script src="go.js"></script>
<script id="code">
  function init() {
    var $ = go.GraphObject.make;

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

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

    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 }

  function test() {
    var alpha = myDiagram.findNodeForKey(1);
    if (alpha) {
      myDiagram.commit(function(d) {
        d.nodes.each(function(n) { n.location = new go.Point(Math.random() * 1000, Math.random() * 1000); });
        alpha.isTreeExpanded = !alpha.isTreeExpanded;
        setTimeout(function() { d.commandHandler.zoomToFit(); }, 1);
      }, "toggled Alpha isTreeExpanded");
<body onload="init()">
  <div id="myDiagramDiv" style="border: solid 1px black; width:100%; height:600px"></div>
  <button onclick="test()">Test</button>

But if i want to zoomToFit on demand, upon user request, and then return to AutoScale = NONE.
If i call zoomToFit, does it set autoScale to UNIFORM or it works once ?

Calling Diagram.zoomToFit or CommandHandler.zoomToFit does not modify Diagram.autoScale.


We’ll improve this in v2.1, so that the order and timing of the calls to the zoomToFit and/or scrollToPart commands does not matter as much.