Fill existing nodes horizontally with color blocks of variable width and fixed order


The above figure is the result I want and the result I made now, the main problem is probably in getting the right of the previous shape, the following is my existing code

$(go.Shape, 'Rectangle', {
                name: 'AShape',
                stroke: null,
                fill: Color.ANode,
                alignment: go.Spot.Left,
                height: Size._commonTemplateHeight,
            }).bind('width', 'AProportion', function (s) {
                return s * Size._commonTemplateWidth;
            }),
            $(
                go.Shape,
                'Rectangle',
                {
                    name: 'BShape',
                    stroke: null,
                    fill: Color.BNode,
                    alignment: go.Spot.Left,
                    height: Size._commonTemplateHeight,
                },
                new go.Binding('width', 'BProportion', function (s) {
                    return s * Size._commonTemplateWidth;
                }),
                new go.Binding('alignment', 'naturalBounds', function (s: go.Rect) {
                    console.log(s.width);
                    console.log(s.right);
                    return new go.Spot(s.right / Size._commonTemplateWidth, 0, 0, 0);
                }).ofObject('AShape')
            ),
            $(
                go.Shape,
                'Rectangle',
                {
                    name: 'CShape',
                    stroke: null,
                    fill: Color.CNode,
                    alignment: go.Spot.Left,
                    height: Size._commonTemplateHeight,
                },
                new go.Binding('width', 'CProportion', function (s) {
                    return s * Size._commonTemplateWidth;
                }),
                new go.Binding('alignment', 'naturalBounds', function (s: go.Rect) {
                    console.log(s.width);
                    console.log(s.right);
                    return new go.Spot(s.right / Size._commonTemplateWidth, 0, 0, 0);
                }).ofObject('BShape')
            ),

The problem I found is that both right and width are 100, but according to the actual result, it should not be this, if the result of right can be correctly obtained, then I can achieve my purpose with this method, please help to see why right can only get 100, or is there a better way?

What is the Panel that contains these Shapes?
What is the data to which the node is data-bound?
What is the value of Size._commonTemplateWidth?

  1. $(go.Panel, 'Auto', commonTemplates)
  2. ‘AProportion’ is something like ‘0.6’, and all proportions add up to less than 1,
  3. Size._commonTemplateWidth = 220

A more detailed code addition

const commonTemplates = [
            { name: 'nodeBody', height: Size._commonTemplateHeight, width: Size._commonTemplateWidth },
            $(go.Shape, 'Rectangle', {
                name: 'nodeBodyShape',
                //stroke: null,
                fill: Color.DNode,
                height: Size._commonTemplateHeight,
                width: Size._commonTemplateWidth,
            }),
           $(go.Shape, 'Rectangle', {
                name: 'AShape',
                stroke: null,
                fill: Color.ANode,
                alignment: go.Spot.Left,
                height: Size._commonTemplateHeight,
            }).bind('width', 'AProportion', function (s) {
                return s * Size._commonTemplateWidth;
            }),
            $(
                go.Shape,
                'Rectangle',
                {
                    name: 'BShape',
                    stroke: null,
                    fill: Color.BNode,
                    alignment: go.Spot.Left,
                    height: Size._commonTemplateHeight,
                },
                new go.Binding('width', 'BProportion', function (s) {
                    return s * Size._commonTemplateWidth;
                }),
                new go.Binding('alignment', 'naturalBounds', function (s: go.Rect) {
                    console.log(s.width);
                    console.log(s.right);
                    return new go.Spot(s.right / Size._commonTemplateWidth, 0, 0, 0);
                }).ofObject('AShape')
            ),
            $(
                go.Shape,
                'Rectangle',
                {
                    name: 'CShape',
                    stroke: null,
                    fill: Color.CNode,
                    alignment: go.Spot.Left,
                    height: Size._commonTemplateHeight,
                },
                new go.Binding('width', 'CProportion', function (s) {
                    return s * Size._commonTemplateWidth;
                }),
                new go.Binding('alignment', 'naturalBounds', function (s: go.Rect) {
                    console.log(s.width);
                    console.log(s.right);
                    return new go.Spot(s.right / Size._commonTemplateWidth, 0, 0, 0);
                }).ofObject('BShape')
            ),

Why doesn’t the “Auto” Panel hold the first Shape as a border/background and a “Horizontal” Panel that holds the three Shapes?

Panel, Auto
  Shape
  Panel, Horizontal
    Shape
    Shape
    Shape

GraphObject.naturalBounds is not a settable property, so you cannot use it as the source of a Binding. Delete those Bindings. The alignment settings can also be deleted once the Shapes are in a “Horizontal” Panel.

Maybe you don’t need those names either.

Thank you very much for your reply, it is very useful, following your method can basically achieve the effect I expected, the only problem is that there is an automatic spacing between the shapes (as shown below), do you know how to eliminate the spacing?
image

It’s hard to answer when you don’t post the relevant code.

A “Horizontal” Panel doesn’t normally put any space between the elements. But each element might have a margin that would cause there to be some space.

Oh, maybe you still have Shape.stroke set to null, which means it draws nothing where it would normally draw the stroke outline. Maybe instead of setting stroke: null you should set strokeWidth: 0.

You are right, it is the problem that strokeWidth is not set to 0. Thank you very much.