TreeLayout Vertical Align

Hello, I can’t make this simple ReactDiagram CENTER align vertically the orange and white nodes.

I tested pretty much every combination of values based on the API docs and nothing changes this layout:

arrangement: go.TreeLayout.ArrangementVertical,
alignment: go.TreeLayout.AlignmentBus,

I’m using a CustomTreeLayout with a main layout and a side layout. The blue node is the side layout and that’s fine as is. It’s the mainLayout that needs centered vertical alignment so all nodes center are aligned to the same vertical AXIS…

image

export class CustomTemplateTreeLayout extends go.Layout {
	private _mainLayout: go.TreeLayout;
	private _sideLayout: go.Layout;
	private _side: go.Spot;
	private _spacing: go.Size;
	private $ = go.GraphObject.make;

	constructor() {
		super();

		const mainLayout = this.$(go.TreeLayout, {
			arrangement: go.TreeLayout.ArrangementVertical,
			alignment: go.TreeLayout.AlignmentBus,
			layerSpacing: 10,
		});

		this._mainLayout = mainLayout;

		const sideLayout = this.$(go.TreeLayout, {
			layerSpacing: 10,
			angle: 90,
		});

		this._sideLayout = sideLayout;
		this._side = go.Spot.LeftSide;
		this._spacing = new go.Size(250, 200);
	}
...

try setting

locationSpot: go.Spot.Center

in your Node templates. By default, its TopLeft.

That didn’t work either… this is code for both Nodes, orange and white.

const dropDocletType = $(
		go.Node,
		'Spot', // Use 'Spot' as the main panel to position ports accurately
		{ movable: false, locationSpot: go.Spot.Center },
		$(go.Shape, 'RoundedRectangle', {
			strokeWidth: 1,
			stroke: '#ffc74c',
			fill: '#ffc74c',
			width: 150,
			height: 30,
		}),
		$(
			go.Panel,
			'Vertical',
			$(
				go.TextBlock,
				{
					textAlign: 'center',
					font: 'bold 10pt Barlow, sans-serif',
				},
				new go.Binding('text', 'text')
			)
		),
		// Conditional Port for "prepend"
		$(
			go.Shape,
			'Circle',
			{
				portId: 'prepend', // Assign a portId for linking
				alignment: go.Spot.Bottom, // Align to the bottom of the node
				desiredSize: new go.Size(8, 8),
				fill: '#1776D2',
				fromLinkable: false,
				toLinkable: false,
				visible: false,
			},
			new go.Binding('visible', 'text', (text: any) => text.includes('Prepend'))
		),
		// Conditional Port for "append"
		$(
			go.Shape,
			'Circle',
			{
				portId: 'append', // Assign a portId for linking
				alignment: go.Spot.Top, // Align to the top of the node
				desiredSize: new go.Size(8, 8),
				fill: '#1776D2',
				fromLinkable: false,
				toLinkable: false,
				visible: false,
			},
			new go.Binding('visible', 'text', (text: any) => text.includes('Append'))
		)
	);

const docletTypeNodes = $(
		go.Node,
		'Spot', // Changed to 'Spot' to allow precise port positioning
		{ movable: false, locationSpot: go.Spot.Center },
		new go.Binding(
			'copyable',
			'',
			(data: any) => data.state !== GoJsNodeState.Copied
		),
		// Main content of the node wrapped in an Auto Panel
		$(
			go.Panel,
			'Auto',
			$(
				go.Shape,
				'RoundedRectangle',
				new go.Binding('fill', 'state', (state: any) =>
					state === GoJsNodeState.Copied
						? '#ccc'
						: state === GoJsNodeState.Palette || state === GoJsNodeState.Diagram
						? 'white'
						: null
				),
				new go.Binding('stroke', 'state', (state: any) =>
					state === GoJsNodeState.Copied
						? '#ccc'
						: state === GoJsNodeState.Palette || state === GoJsNodeState.Diagram
						? '#1776D2'
						: null
				),
				{
					width: 200,
					minSize: new go.Size(200, 35),
					maxSize: new go.Size(200, 35),
					strokeWidth: 1,
					alignment: go.Spot.Center,
				}
			),
			$(
				go.Panel,
				'Horizontal',
				{ stretch: go.GraphObject.Horizontal, alignment: go.Spot.Left },
				'Horizontal',
				paletteIcon,
				$(
					go.TextBlock,
					{
						margin: new go.Margin(2, 10, 0, 5),
						width: 135,
						wrap: go.TextBlock.WrapDesiredSize,
						textAlign: 'center',
						font: 'bold 10pt Barlow, sans-serif',
					},
					new go.Binding('text', 'title')
				),
				$(
					'Button',
					new go.Binding(
						'visible',
						'state',
						(state: any) => state === GoJsNodeState.Diagram
					),
					{
						column: 1,
						'ButtonBorder.figure': 'Circle',
					},
					$(go.Shape, 'XLine', {
						width: 8,
						height: 8,
						fill: 'white',
						click: (ev: any, obj: any) => {},
					})
				)
			)
		),
		// Conditional Ports
		$(
			go.Shape,
			'Circle',
			{
				portId: 'left',
				alignment: new go.Spot(0, 0.5),
				desiredSize: new go.Size(8, 8),
				fill: '#1776D2',
				fromLinkable: false,
				toLinkable: true,
				visible: false,
			},
			new go.Binding(
				'visible',
				'state',
				(state: any) => state === GoJsNodeState.Diagram
			)
		),
		$(
			go.Shape,
			'Circle',
			{
				portId: 'top',
				alignment: go.Spot.TopCenter,
				desiredSize: new go.Size(8, 8),
				fill: '#1776D2',
				fromLinkable: false,
				toLinkable: false,
				visible: false,
			},
			new go.Binding(
				'visible',
				'state',
				(state: any) => state === GoJsNodeState.Diagram
			)
		),
		$(
			go.Shape,
			'Circle',
			{
				portId: 'bottom',
				alignment: go.Spot.BottomCenter,
				desiredSize: new go.Size(8, 8),
				fill: '#1776D2',
				fromLinkable: false,
				toLinkable: false,
				visible: false,
			},
			new go.Binding(
				'visible',
				'state',
				(state: any) => state === GoJsNodeState.Diagram
			)
		)
	);

I just tried implementing the class FlatTreeLayout extends go.TreeLayout that is aligning the Nodes vertically but the results are pretty bad.

image

What’s wrong with the code I gave you in Which Diagram Layout to use? - GoJS - Northwoods Software (nwoods.com) ? It vertically aligns different width nodes of any category.

We had to change it to a CustomTreeLayout with a MainLayout and SideLayout like I posted in the beginning of this thread because for the side layout, we have to programmatically move the nodes up/down based on 1-to-many Links from the side to the main layout. The side layout is not arranged vertically top/down.

So the main layout should just be a regular TreeLayout, and that would get everything aligned the way that you want.

And the side layout would arrange those nodes on the left side with a vertical location corresponding to what they are linked with in the main tree/layout.

That sounds reasonable. But that side layout should not be a TreeLayout. That should be custom code to locate each node appropriately.

The side layout is fine as is. It’s the main TreeLayout that won’t align

This is the CustomLayout. As I mentioned earlier, I have tried all possible values for Alignment to no avail.

I added locationSpot: go.Spot.Center as well.

As I said above, that’s not going to work. You want the TreeLayout arrange all of the nodes and links on the right side, but you need custom code to arrange the nodes on the left side.

In the code that I gave you before (in the other forum topic) that was designed so that there was just a Diagram.layout that was a TreeLayout and the nodes on the left were not laid out automatically. They were assumed to be created via drag-and-drop from the Palette and arranged manually in the main Diagram. I’m just suggesting that you create a new custom layout that uses TreeLayout on the right side and your own code for the nodes on the left side.