Skip to main content
  1. Index

Initial, programmatic, and automatic viewport management

When one assigns a Diagram.model to a Diagram, Parts are created and an initial layout is performed. After this, the viewport is moved to its initial location. Beyond the initial layout, you can programmatically move the viewport, as well as have those programmatic changes be called on specific events automatically.

Initial viewport

In large diagrams, it is often important to have the initial view be on a specific node, or in a specific area. The following properties control the initial position of the viewport. They apply after the initial layout of a diagram:

These properties control the initial scale of the viewport:

For more information on what the viewport and document are, read Coordinate Systems.

initialDocumentSpot and initialViewportSpot

A common use case for initialDocumentSpot and initialViewportSpot is when displaying a large tree graph with a high initial zoom. The best starting position for this case is typically the highest level Nodes. The default initial viewport placement usually does this for Tree Layouts with an angle of 0, but other angles cause the initial viewport to be placed far away from the highest level Nodes. For example, for a tree with an angle of 180, this would achieve a similar result:

js

This example visualizes how initialDocumentSpot is calculated, and how initialViewportSpot affects the final Diagram.position.

Changing either dropdown re-aligns the document automatically by calling Diagram.alignDocument with the new values, which is equivalent to creating the Diagram with the corresponding initialDocumentSpot and initialViewportSpot values. Importantly, Diagram.scrollMargin has been increased, which allows the viewport to go much further away from the document than normal.

When either property is set to None, this example leaves the diagram at its default placement. Because calling Diagram.alignDocument with Spots that have NaNs would not produce a meaningful position, we reassign the model to refire the initial layout event.

The snippet below centers the initial viewport on the first Node in Diagram.nodes (it leaves the viewport unchanged if that node is already entirely visible).

js

initialContentAlignment and initialAutoScale

If instead of picking the best initial viewport for a zoomed-in Diagram, one wants to pick the best initial viewport for a zoomed-out or small Diagram, Diagram.initialContentAlignment and Diagram.initialAutoScale are usually a better solution.

A simple case is wanting a small Diagram to appear at the top-center of the viewport. To do this, set initialContentAlignment to Spot.Top. Alternatively, a Diagram that is large or small can be zoomed-to-fit by setting initialAutoScale to AutoScale.Uniform. While you could set both, AutoScale.Uniform would mean that the content is already aligned with some Spot values, causing initialContentAlignment to appear ignored in some cases.

js

The initialLayoutCompleted event

When defining initialViewportSpot, initialDocumentSpot and most other "initial" properties, it is important to wait for all Parts to be created and positioned. This is what the InitialLayoutCompleted Event tracks, and is what GoJS waits for before applying these properties to their non-initial counterparts. Because it is an event, it can be listened for like any other event, allowing customizable initial viewport positions.

In this example, after the initial layout we find the Node closest to the center of the document and zoom into it. To show the resultant viewport relative to the Diagram, there is an Overview in the top-left corner.

Note: because by default one cannot scroll past any edge of the document plus any Diagram.scrollMargin, if the selected node happens to be at or near an edge, the node cannot actually be centered in the viewport unless you set Diagram.scrollMode, Diagram.scrollMargin, or Diagram.padding.

Automatic viewport management

There are also times when you will want to control the viewport (i.e. the Diagram.position and Diagram.scale) after every change to the diagram. For example, if you always want to keep the document centered after the user has moved or deleted or inserted nodes, set Diagram.contentAlignment (rather than Diagram.initialContentAlignment) to Spot.Center.

Or if you always want to keep the document "zoomed-to-fit", set Diagram.autoScale (rather than Diagram.initialAutoScale) to AutoScale.Uniform. As an example, the Overview diagram does this.

Programmatic viewport management

If you do not want continual repositioning or rescaling of the diagram, but you do sometimes want to change the Diagram.position and/or the Diagram.scale, you can set those properties to whatever values you like. However, please note that the ultimate value for Diagram.position is normally limited by the Diagram.documentBounds and the size of the viewport and the scale of the diagram. The Diagram.scale is limited by Diagram.minScale and Diagram.maxScale.

But it is more common to call a method on Diagram to achieve the results that you want. For example, to get the effect of the Diagram.initialDocumentSpot and Diagram.initialViewportSpot properties that are used when the "InitialLayoutCompleted" DiagramEvent occurs, call Diagram.alignDocument with the two desired Spots that you want to have coincide.

As already demonstrated above, if you want to try to center a particular node in the viewport, you can call Diagram.centerRect with the node's GraphObject.actualBounds.

If you want to make sure that a particular node is within the viewport, but not necessarily centered, call Diagram.scrollToRect.

If you just want to scroll the diagram, in the same manners as the user might via a scrollbar or the mouse wheel, call Diagram.scroll with arguments that specify how much to scroll and in which direction.

The just-mentioned Diagram methods do not change the Diagram.scale. If you want to rescale the diagram so that the whole document bounds are shown, call Diagram.zoomToFit. More generally, if you want a particular area of your diagram to be shown at whatever scale will make it fit in the viewport, call Diagram.zoomToRect.