Coordinate Systems
A Diagram uses two major coordinate systems when drawing Parts in a Canvas element: document and view coordinates. (Panels have their own coordinate systems.)
View and document coordinates
The Part.location and GraphObject.actualBounds and GraphObject.position of Parts are in document coordinates. Thus the Points that may be saved in the model's node data are normally in document coordinates:
diagram.model.nodeDataArray = [ { key: "Alpha", loc: "0 0" }, { key: "Beta", loc: "100 50" } ];
But a Part with a Part.location of (0, 0) in document coordinates is not always drawn at the top-left corner of the Canvas element that the user sees. When the user scrolls the diagram the part will need to be drawn elsewhere on the canvas. And if the user zooms in to make the parts appear larger, the parts will be drawn at different points in the canvas. Points in the canvas are in view coordinates: distances from the top-left corner in device-independent pixels.
The differences between document coordinates and view coordinates are primarily controlled by two Diagram properties: Diagram.position and Diagram.scale. Scrolling and panning change the Diagram.position. Zooming in or out changes the Diagram.scale. You can also convert between coordinate systems by calling Diagram.transformDocToView and Diagram.transformViewToDoc.
The viewport is the area of the document that is visible in the canvas. That area is available as the Diagram.viewportBounds. The top-left corner of the viewport is (0,0) in view coordinates but is at Diagram.position in document coordinates. The bottom-right corner of the viewport is at the canvas's (width,height) in view coordinates. The bottom-right corner of the viewport in document coordinates depends on the Diagram.scale.
Coordinate systems example
This example shows three Parts at three different locations in document coordinates. Pass the mouse over each of the parts to see where those locations are in view coordinates. Initially you will see that the only difference between document and view coordinates are a constant offset. That offset is due to the Diagram.padding that puts a little space between the edge of the canvas and the edge of where the diagram's objects are. It is also due to Part.locationSpot having the location be at the center of the "+" Shape, not at the top-left corner of the whole Part.
// read-only to avoid accidentally moving any Part in document coordinates diagram.isReadOnly = true; diagram.nodeTemplate = $(go.Part, // no links or grouping, so use the simpler Part class instead of Node { locationSpot: go.Spot.Center, locationObjectName: "SHAPE", layerName: "Background", mouseOver: function (e, obj) { showPoint(obj.part.location); } }, new go.Binding("location", "loc", go.Point.parse), $(go.Shape, "PlusLine", { name: "SHAPE", width: 8, height: 8 }), $(go.TextBlock, { position: new go.Point(6, 6), font: "8pt" }, new go.Binding("text", "loc")) ); diagram.model.nodeDataArray = [ { loc: "0 0" }, { loc: "100 0" }, { loc: "100 50" } ]; function showPoint(loc) { var docloc = diagram.transformDocToView(loc); var elt = document.getElementById("Message1"); elt.textContent = "document: " + loc.x.toFixed(2) + " " + loc.y.toFixed(2) + " view: " + docloc.x.toFixed(2) + " " + docloc.y.toFixed(2); } myDiagram = diagram; // make accessible to the HTML buttons(object location in document and in view coordinates)
Then try zooming in and looking at the locations of those parts in view coordinates. Zooming in increases the Diagram.scale by a small factor. That changes the locations in view coordinates, even though the locations in document coordinates did not change.
Document bounds
All of the Parts of a diagram have positions and sizes (i.e. their GraphObject.actualBounds) in document coordinates. The union of all of those parts' actualBounds constitutes the Diagram.documentBounds. If all of the parts are close together, the document bounds might be small. If some or all of the parts are far apart from each other, the document bounds might be large, even if there are only two parts or if there is just one really large part. The Diagram.documentBounds value is independent of the Diagram.viewportBounds. The former only depends on the bounds of the parts; the latter only depends on the size of the canvas and the diagram's position and scale.
Diagram.computeBounds, which is responsible for the bounds computation, also adds the Diagram.padding Margin so that no Parts appear directly up against the edge of the diagram. You may want to keep some parts, particularly background decorations, from being included in the document bounds computation. Just set Part.isInDocumentBounds to false for such parts.
The diagram does not compute a new value for Diagram.documentBounds immediately upon any change to any part or the addition or removal of a part. Thus the Diagram.documentBounds property value may not be up-to-date until after a transaction completes.
The relative sizes of the Diagram.documentBounds and Diagram.viewportBounds control whether or not scrollbars are needed. You can set Diagram.hasHorizontalScrollbar and/or Diagram.hasVerticalScrollbar to false to make sure no scrollbar appears even when needed.
If you do not want the Diagram.documentBounds to always reflect the sizes and locations of all of the nodes and links, you can set the Diagram.fixedBounds property. However if there are any nodes that are located beyond the fixedBounds, the user may be unable to scroll the diagram to see them.
When scrolling, the Diagram.position will be limited to the range specified by the Diagram.documentBounds. The short or "line" scrolling distance is controlled by Diagram.scrollHorizontalLineChange and Diagram.scrollVerticalLineChange. The long or "page" scrolling distance is controlled by the size of the viewport.
When zooming in or out, the Diagram.scale will be limited to the range given by Diagram.minScale and Diagram.maxScale.