Calculate min scale after graph was draw

Hi. Is there the way to calculate min scale (when all nodes and links in viewport) after initialisation ends and graph was draw? Default scale is 1.
Or maybe i missed something and diagram have some props to don’t zoom out if all nodes and links in viewport?

You can calculate based on the Diagram.documentBounds and the size of the HTMLDivElement, although it’s more complicated because it may depend on the size of the scrollbars, if there would be any.

Normally for automatic scaling on initialization one sets Diagram.initialAutoScale to go.Diagram.Uniform or go.Diagram.UniformToFit.

@walter thanks for answer. Maybe my question was not so clear. I tried calculate based on Diagram.documentBounds but it’s really complicated. Also i already have Diagram.initialAutoScale: go.Diagram.Uniform but when i change scale by scroll i can zoom out graph to tiny size but i need min scale when all nodes and links visible in viewport.

So you are trying to set Diagram.minScale to a value so that the the user cannot zoom out too far?

I suppose you could implement an “InitialLayoutCompleted” DiagramEvent listener:

$(go.Diagram, . . .,
  {
    initialAutoScale: go.Diagram.Uniform,
    "InitialLayoutCompleted": function(e) { e.diagram.minScale = e.diagram.scale; },
    . . .
  })

Does that do what you want?

So you are trying to set Diagram.minScale to a value so that the the user cannot zoom out too far?

Yes, that’s exactly what I’m trying to do.
Unfortunately i can’t use e.diagram.minScale = e.diagram.scale because i have defaultScale: 1 and big graph so after initialisation user will see just part of graph and he must be able to zoom out less then 1.

Diagram.defaultScale just controls what scale the diagram is reset to when the user invokes the CommandHandler.resetScale command.

Or did you mean to say Diagram.initialScale?

Yes i meant Diagram.initialScale.

OK, then, would this do what you want?

      $(go.Diagram, . . .,
        {
          initialAutoScale: go.Diagram.Uniform,
          "InitialLayoutCompleted": function(e) {
            e.diagram.minScale = e.diagram.scale;
            e.diagram.scale = 1;
            e.diagram.centerRect(e.diagram.documentBounds);
          },
          . . .
        })

I’m afraid i can’t use this because user can resize viewport. If I zoom to fit and zoom back in every time, it will be confusing.

This does what you are asking for:

          "InitialLayoutCompleted": function(e) {
            var div = e.diagram.div;
            var db = e.diagram.documentBounds;
            var hscale = div.clientWidth / (db.width+1);
            var vscale = div.clientHeight / (db.height+1);
            e.diagram.minScale = Math.min(hscale, vscale);
          },

BUT, I found that although I think it computes the right number for Diagram.minScale, it doesn’t mean that the user can actually scale down to that number using the normal zooming actions (control-mouse-wheel, pinch zoom). That’s because CommandHandler.decreaseZoom goes in increments, and the computed minimum scale is unlikely to be one of those values.

The only way to get to (about) that scale is via the CommandHandler.zoomToFit command, which is bound to shift-Z by default.

This works for me. Thanks @walter