There is no built-in way to have a Binding where the dimensions of one GraphObject are determined by the actualBounds (or measuredBounds) of another (or the same) GraphObject.
The reason is to avoid bad feedback loops, particularly ones where the measurements do not stabilize! It also guarantees that measuring and arranging panels is fast, or at least bounded.
Note that there would be no problem with having two Bindings to a source data property where there’s a conversion function that causes one GraphObject’s width to be half the width of a different GraphObject. It’s the Binding.ofObject that could cause panel layout problems.
Here’s a node template that I think does what you want:
myDiagram.nodeTemplate =
$(go.Node, "Spot",
$(go.Panel, "Auto",
{ name: "BODY", portId: "" },
$(go.Shape,
new go.Binding("fill", "color")),
$(go.TextBlock,
{ margin: 8, editable: true },
new go.Binding("text").makeTwoWay())
),
$(go.TextBlock, "abcdefghijklmnopqrstuvwxyz",
{
alignment: go.Spot.TopRight,
background: "orange",
wrap: go.TextBlock.None,
overflow: go.TextBlock.OverflowEllipsis
},
new go.Binding("width", "actualBounds", function(b) { return b.width/2; }).ofObject("BODY"))
);
Note the Binding on GraphObject.actualBounds. That property is not settable, so the Binding does not “work”.
But you can make it work by explicitly asking for the Binding to be evaluated, by calling Panel.updateTargetBindings. This is somewhat inefficient, but I think it accomplishes what you want:
$(go.Diagram, . . . ,
{
"LayoutCompleted": function(e) {
e.diagram.nodes.each(n => n.updateTargetBindings("actualBounds"));
},
})