A node's relative location within viewport

Hi there – this is a pretty basic question about figuring out the location of a node/Shape on the screen within the canvas. I’m confused about how to interpret the location data I am getting when I query a node’s position. I’m getting location values like “-228.9749994277954 -54.75”, but I’m confused as to what those coordinates to relative to?

What I’d like to do is get the node’s actual location on the screen by first determining (via jquery) the position of the GoJS canvas element, which will give me positive X,Y coordinates. Then, within GoJS, I’d like to be able to interpret the aforementioned negative location value coordinates so I can then make them relative the canvas’ position. Once I can do that, I can then infer a node’s ACTUAL position within the browser’s viewport. I’m sure there’s something simple in the docs I’m missing here…

The reason i need to do this is b/c I’m spawning a small modal html toolbar (that , in my requirements, needs to be done outside goJS for styling reasons and I also don’t want that to zoom) that will position itself adjacent to the node.

My diagram’s orientation :

“initialAutoScale”: go.Diagram.Uniform,
“initialContentAlignment”: go.Spot.Center

Here is what a typical node looks like :

$g(go.Node, “Spot”, GoJS_Styles.nodeStyle(),
new go.Binding(“location”, “loc”, go.Point.parse).makeTwoWay(go.Point.stringify),
// the main object is a Panel that surrounds a TextBlock with a rectangular Shape
$g(go.Panel, “Auto”,
$g(go.Shape, “Rectangle”,
{ fill: GoJS_Styles.decisionBgColor,
stroke: “rgb(100,100,100)” },
new go.Binding(“figure”, “figure”)),
{ font: “bold 9pt Helvetica, Arial, sans-serif”,
stroke: GoJS_Styles.darkText,
margin: 8,
maxSize: new go.Size(160, NaN),
wrap: go.TextBlock.WrapFit,
editable: true },
new go.Binding(“text”, “text”).makeTwoWay())


This should explain things: Coordinate Systems.

That is a very good doc, however, it doesn’t help me account for / explain / interpret why all of the location values for my Parts/Shapes are negative?

If the coord system is based on a top-left of (0,0), then I have no idea how to interpret or translate the negative values GoJs is using for location.

For instance, here is one sample diagram’s json stored in my db (note the negative loc values) :

{ “class”: “go.GraphLinksModel”,
“linkFromPortIdProperty”: “fromPort”,
“linkToPortIdProperty”: “toPort”,
“nodeDataArray”: [
{“category”:“Start”, “text”:“Pathway\nStarting\nPoint”, “key”:-1, “id”:2, “loc”:"-314.0413585945412 -788"},
{“category”:“Clinical Question”, “text”:“new node text”, “key”:-2, “id”:6, “loc”:"-645.1560189459059 -683.524374628067", “color”:"#333333", “fill”:"#333333"}
“linkDataArray”: [ {“from”:-1, “to”:-2, “fromPort”:“B”, “toPort”:“T”} ]}

here’s an entry from my node template (not sure if this helps) – am I doing something wrong here with the location binding to get the negative values…?

$g(go.Node, “Spot”, GoJS_Styles.nodeStyle(),
new go.Binding(“location”, “loc”, go.Point.parse).makeTwoWay(go.Point.stringify),
$g(go.Panel, “Auto”,
$g(go.Shape, “Terminator”,
{ minSize: new go.Size(30, 30), fill: GoJS_Fills.greenRadialGradient(), stroke: GoJS_Styles.startColor }),
$g(go.TextBlock, “Pathway Starting Point”,
{ margin: 10,
textAlign: “center”,
font: “bold 9pt Helvetica, Arial, sans-serif”,
stroke: GoJS_Styles.lightText,
editable: true,
maxSize: new go.Size(160, NaN),
wrap: go.TextBlock.WrapFit },
new go.Binding(“text”, “text”).makeTwoWay(),
new go.Binding(“stroke”, “color”).makeTwoWay())
// three named ports, one on each side except the top, all output only:
GoJS_Helpers.makePort(“B”, go.Spot.Bottom, true, false)

I don’t know why you have those values stored in your database.
Do the Nodes appear in the proper relationship with each other? If so, why does it matter what the absolute values are for the location?

Actually, the top-left point of your coordinate system is either -Infinity,-Infinity or the myDiagram.documentBounds.position, depending on whether you are considering the limits for where nodes could be positioned or the limits of where they actually are positioned currently.

Thanks for your response!

With regard to why I have those values stored in my database… Use case for me is that our users can drag & drop / re-position the nodes, thus to save those positions I need to store the coords as part of the nodeData. User’s diagrams are pulled from db and the diagram’s is init’d from a “fromJson” call.

The reason I needed to get the the absolute values is because of some non-GoJS html popover overlays I’m doing relative to the node when it’s clicked (couldn’t do it within GoJS as an Adornment or other Part b/c of a design requirement by the product team) .

Diagram.transformDocToView ( in the Coordinates intro you linked) did the trick for me to get the canvas-relative node position. So…problem solved! I certainly get the -Inifinity,-Inifinity top Left for document (vs. viewport) coords, but I don’t think there was an explicit discussion of that in the docs. I’m thinking that maybe worth a mention around the below paragraph to ward off confusion & forum requests by total n00b’s like me ;) :

"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 twoDiagram 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 theDiagram.viewportBounds. The top-left corner of the viewport is (0,0) in view coordinates but is atDiagram.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."

Thanks for your help!

cheers, G

Pretty Neatly Explained , I was looking for something like this with a clear example

We have added an illustration (which is of course a live GoJS diagram) at GoJS Coordinate Systems-- Northwoods Software.

@walter Is there a way to alway keep a node at the same viewport relative position when the viewport’s position and scale is changed?


Thank you walter! Very helpful.