Align Center X across Shapes - when text is aligned using Spots

In following fig - there are two scenarios where textAlign property value is shown.


With first figure, the Spot uses only the position on node where text should be displayed using alignment. Also using alignmentFocus ( as reply for https://forum.nwoods.com/t/negative-margin-for-text-block/9213/10 display the text inside the shape as required.

With figure 1 when align Center X functionality from DrawCommandHander is executed shapes gets aligned centrally and striaght line is shown between the shapes.

But with fig 2, where one of the shape ( Bigger circle ) has -100 offset is used, text gets shifted out side the circle.
With this when center X alignment code executed, they are not aligned with shape in the center ( Expected is straight line between these two shapes)

Below is code for the Template and Center align X function

Template :

    var activityNodeTemplate =
    $(go.Node, "Spot",
       {
           locationObjectName: "SHAPE", locationSpot: go.Spot.Center, zOrder: 0, 
           resizable: true, resizeObjectName: "SHAPE", selectionObjectName: "SHAPE",
           selectionAdorned: true,           
        },
       new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
       new go.Binding("zOrder", "zOrder"),
         $(go.Panel, "Spot",
          $j(go.Shape,
            {
                name: "SHAPE",
                portId: "",
                fromLinkable: true, toLinkable: true,  fromLinkableDuplicates : true, toLinkableDuplicates : true,
                fromSpot: go.Spot.AllSides, toSpot: go.Spot.AllSides,
                stretch: go.GraphObject.Fill,
            },
            new go.Binding("desiredSize", "size", go.Size.parse).makeTwoWay(go.Size.stringify),
            new go.Binding("figure", "figure"))
           ),
        $(go.TextBlock,  // the center text
          {
              cursor: "move", 
              editable: true, isMultiline: false
          },
          new go.Binding("text").makeTwoWay(),
          new go.Binding("alignment", "textAlign", go.Spot.parse).makeTwoWay(go.Spot.stringify),
          new go.Binding("alignmentFocus", "textAlign", nodeAlignmentFocusConverter)),
          new go.Binding("font", "font").makeTwoWay()
          ))  // end Auto Panel


function nodeAlignmentFocusConverter (s) {
    var s = s.split(" ");
    if (s.length >= 2)
        return new go.Spot(s[0], s[1], 0, 0);
    else
        return new go.Spot(0, 0, 0, 0); //go.Spot.TopLeft;
}

Alignment Function

DrawCommandHandler.prototype.alignCenterX = function () {
    var diagram = this.diagram;
    var firstSelection = diagram.selection.first();
    if (!firstSelection) return;
    diagram.startTransaction("aligning Center X");

    var centerX = 0;
    if ((firstSelection.category == "gateway") || (firstSelection.category == "event") || (firstSelection.category == "dataObject") || (firstSelection.category == "customshape") || (firstSelection.category == "shape") || (firstSelection.category == "dataStore") || (firstSelection.category == "documentType")) {
        var shapeObject = firstSelection.findObject("SHAPE");
        if (shapeObject != undefined)
            centerX = shapeObject.actualBounds.x + shapeObject.actualBounds.width / 2;
        else
            centerX = firstSelection.actualBounds.x + firstSelection.actualBounds.width / 2;
    }
    else {
        centerX = firstSelection.actualBounds.x + firstSelection.actualBounds.width / 2;
    }

    diagram.selection.each(function (current) {
        if (current instanceof go.Link) return; // skips over go.Link
        //current.move(new go.Point(centerX - current.actualBounds.width / 2, current.actualBounds.y));
        if ((current.category == "gateway") || (current.category == "event") || (current.category == "dataObject") || (current.category == "customshape") || (current.category == "shape") || (current.category == "dataStore") || (current.category == "documentType")) {
            var shapeObject = current.findObject("SHAPE");
            if (shapeObject != undefined) {
                var valueToAdd = 0;
                var offset = current.part.data.textAlign.split(" ");
                if (offset.length >= 2)
                    valueToAdd = parseInt(offset[2]);
                current.move(new go.Point(centerX - shapeObject.actualBounds.width / 2 + valueToAdd, current.actualBounds.y));
            }
            else
                current.move(new go.Point(centerX - current.actualBounds.width / 2, current.actualBounds.y));
        }
        else {
            current.move(new go.Point(centerX - current.actualBounds.width / 2, current.actualBounds.y));
        }
    });
    diagram.commitTransaction("aligning Center X");
};

I tried by adding the offset value , but doesn’t work with that.
Also checked by adding the difference of actual bounds of node and shape bounds. This one also doesn’t work.

In the second case the node is actually wider because the text is extending out towards the left side of the node’s Shape. So naturally the center points of the Shapes do not line up, because only the centers of the whole nodes do. That is what the command is named, not “align X locations”.

If all of your node templates set the Part.locationSpot and Part.locationObjectName, maybe you should define your command to just set the nodes locations to all have the same X value.

Yes. As the second node is wider due to text, original Align CenterX functionality aligns the node centrally.

To align same centrally according to shapes, the function is modified to calculate the centers of Shapes.
Here what I need is - to move the object such that both nodes shapes center should be linked / aligned in straight line -

For eq. First shape is top left position is (100, 100 ) and it is wide 100 then center X of same is 150.
Second shape initial left position is 80 and it is wide 80 then 150 - 80/2 gives us 110. So moving shape to 110 aligns both nodes centrally. [ In this case it is assumed that of text of shape is aligned centrally]

With above case, if text of second node starts at position 60 (left aligned), then moving the node to 110 position is not correct and one need to move it position 90 instead of 110. That will make width of text 20 + half of shape width 80. (so actual shape starts from position 110 - as in first case, but node starts from position 90 )

In above second case - with actual code I assume 60 is obtained from current.actualbounds.
I am not able to get what code needs to be written there exactly.

Did you try what I suggested above?

If all of your nodes have locationSpot: go.Spot.Center and locationObjectName: "SHAPE" (or whatever the name is of the shape that you want to center-align to), then you don’t need to find the sizes or bounds of anything nor do any calculations – just set the Node.location to have the same X values. The library will do those offset calculations for you.

Sorry walter, didn’t get you initally.
Now its working great. I will be changing all my templates to support that text alignment and location spot for shapes.

With this I don’t need to find any centerX for shapes. First nodes location.X needs to be set to all nodes location.X

Thanks for your help.