Node Position or Location based off of Node part and not Node itself

Hi, Long time listener, First time caller…lol

My question is, is it possible to position a node via location or position based on the Image part or any sub-part of a Node, or only the node itself? My issue is I have a node with an image in the center, this image has a standard size, but has other attributes such as ports, and annotations. The annotations can be on top, bottom, left, or right based on a users choice. Problem is once a annotation is loaded at the top of a node, the image isn’t lining up with other nodes that have a annotation at the bottom of the node.

Stubbed out code that resembles my current code.

$(go.Panel, “Table”
$(go.Panel, “Auto”,
{ row: 1, column: 1, name: “BODY” },

	{name: 'nodeIcon', row: 1, column: 1, width:36, height:36, stretch: go.GraphObject.Fill},
	new go.Binding("source"),
	new go.Binding("position", "position", go.Point.parse).makeTwoWay(go.Point.stringify)

//adding left ports
getPort($, "leftnode")
//adding right ports
getPort($, "rightnode")
//adding top ports
getPort($, "topnode")
//adding bottom ports
getPort($, "bottomnode")

//annotation panel

$(go.Panel, 'Auto' {},
	new go.Binding('row', '', getRow),
	new go.Binding('column', '', getColumn),
	$(go.Shape, 'Rectangle', {fill: bgColor, stroke: 'gray'}),
	$(go.TextBlock, textStyle()),


Well, ultimately the alignment of nodes will depend on the layout.

But basically what you are talking about is why there is a difference between the Part.position property and the Part.location property. “Position” is always at the top-left corner; “location” can be at any spot of any named element of the Part.

So change your Node template to include:

$(go.Node, . . .,
    { locationSpot: go.Spot.Center, locationObjectName: "nodeIcon" },
    new go.Binding("location", "position", go.Point.parse).makeTwoWay(go.Point.stringify),
    . . .,
        { name: 'nodeIcon', . . .  },
        new go.Binding('source'))  // note--removed Binding on Picture.position

I’ll give that a try thanks. And the Binding(‘source’) is actually the source of the image being streamed in.

Yes, I included it to make it clear that the “position” Binding was no longer there.

Ahhh, yeah sorry I put that in the wrong location on this stub, it normally is under the go.panel binding. thanks.

That worked Brilliantly!!! Thanks for the quick reply walter!

Is there a way to use the locationObjectName and then bind to position instead of location?

What do you mean? If you use a Part.locationSpot that is go.Spot.TopLeft (which is the default value), then the top-left corner of the Part.locationObject will be at the Part.location.

Okay so the part that I have left out is we are upgrading a product that saves a x, y coordinate to an xml file, and when the user opens that file in our new system that is written with gojs, we are needing to load that workflow exactly as it would have been in the original version.

So with that being said, when we use position for our binding of groups, textboxes, and nodes, they all load in their correct areas perfectly. When location is used to bind, text boxes, groups, nodes, have some slight variances that cause objects to land on top of each other. So when binding to position, the locationObjectName doesn’t appear to be honored. It only seems to work when location is bound. But again location binding is causing issues vs position binding.

I’m not understanding your situation. If you use the Part.location, then some of those other properties that have “location” in their names may apply. If you use the Part.position property, the properties with “location” in their names do not apply.