Centering textblocks in panels

I’m trying to show some additional information on nodes, the count and type of children in subtree to be precise. It works more or less okay:

The problem is the textblocks are not properly centered on shapes, and since they have fixed positions they wont work with double-digit numbers. I’m using Panel.position to set it up (of all panel types, this gave me the closest aproximation of what I want). Is there any way to center it properly? The code for current version is this:

$$(go.Panel, go.Panel.Position,
  $$(go.Shape, "circle",
    { position: new go.Point(0, 0),
      fill: "#e7422d",
      width: 20, height: 20,
      strokeWidth: 2,
      stroke: "white"}
    ),
  $$(go.TextBlock, "3", { stroke: "white", position: new go.Point(7, 4) }),
  $$(go.Shape, "circle",
    { position: new go.Point(0, 23),
      fill: "#1d89cf",
      width: 20, height: 20,
      strokeWidth: 2,
      stroke: "white"}
    ),
  $$(go.TextBlock, "9", { stroke: "white", position: new go.Point(7, 27) })
)
);

One normally uses an “Auto” Panel to put a border around some content.

Yes, I don’t think that was clear enough in the last post. I already tried auto, it gave me a very similar result:

while it allows for two digit numbers to fit nicely it still doesn’t give me proper centering.

Are you using a nested Auto Panel for each colored circle and white text? Your quoted template did not use any Panels there at all.

Yes, I was using a nested structure in the version from the second post. Here it is:

$$(go.Panel, go.Panel.Vertical,

  $$(go.Panel, go.Panel.Auto,
    $$(go.Shape, "circle",
      { alignment: go.Spot.Center,
        fill: "#e7422d",
        width: 20, height: 20,
        strokeWidth: 2,
        stroke: "white"}
      ),
    $$(go.TextBlock, "3", { stroke: "white", font: "10px sans-serif", alignment: go.Spot.Center, })
  ),
  $$(go.Panel, go.Panel.Auto,
    $$(go.Shape, "circle",
      { alignment: go.Spot.Center,
        fill: "#1d89cf",
        width: 20, height: 20,
        strokeWidth: 2,
        stroke: "white"}
      ),
    $$(go.TextBlock, "99", { stroke: "white", font: "10px sans-serif", alignment: go.Spot.Center,  })
  )
)

Ah, you shouldn’t be setting the width/height of the Shape then – either set the size of the whole panel, if that is what you want, or don’t set anything, if you want each panel to be their natural size.

If you want each panel to be a fixed size and the text to automatically get smaller as the string gets longer (or if you make the font bigger), you could use a “Viewbox” Panel there so that it automatically scales the TextBlock to fit in the fixed size panel.

Also, you can set the Shape.spot1 and Shape.spot2 properties so that there is less margin around the text inside the non-rectangular shape. If you are sure to only have one or two digit numbers there, and if the Panel is big enough or the font is small enough, then this might avoid using Viewbox Panels.

Unfortunately this does not change anything for the better. When I remove widths an heights the textboxes are still not centered, and their size changes depending on the number of digits present.

As for the automatic size changes you mentioned, there is no need for that in this case. I need both circles to be of the same size, with the same font size. There won’t be more than 2 digits.

Well, then, just set each Panel size to the same value.

That still has exactly the same problems as everything we’ve covered so far. Can I jus use some offset in auto panels?

    myDiagram.nodeTemplate =
      $(go.Node, "Horizontal",
        $(go.Shape, "Hexagon", { fill: "crimson", width: 24, height: 24, strokeWidth: 0 }),
        $(go.TextBlock, new go.Binding("text", "key")),
        $(go.Panel, "Vertical",
          $(go.Panel, "Auto", { width: 20, height: 20 },
            $(go.Shape, "Circle", { stroke: "white", strokeWidth: 2, fill: "red" }),
            $(go.TextBlock, { stroke: "white", textAlign: "center", font: "7pt sans-serif" }, new go.Binding("text", "a"))
          ),
          $(go.Panel, "Auto", { width: 20, height: 20 },
            $(go.Shape, "Circle", { stroke: "white", strokeWidth: 2, fill: "cornflowerblue" }),
            $(go.TextBlock, { stroke: "white", textAlign: "center", font: "7pt sans-serif" }, new go.Binding("text", "b"))
          )
        )
      );

Yes, that is exactly what I’m getting. The labels are stil too high and too far to the left
I know I’m being infuriating with pixel precision here and I’m terribly sorry for that but I know for a fact that this won’t pass testing and I’ll have to resolve it one way or another.

If there is no way to make it work then I guess it’ll have to do, but is there really no way to do some manual adjustments?

Really sorry for nitpicking, I’m on the receiving end here too.

Just add a margin on the top of the TextBlock.

    margin: new go.Margin(1, 0, 0, 0)

or whatever works for you.

1 Like