How to cause a column to be filled vertically

Hi,

I have uploaded an example of my difficulty here.

In the tab “new”, the two “aaa” nodes are quite close to what I am trying to achieve, but the dark gray rectangle in the center should be as tall as the vertical port columns to its left and right. It is instead sized as though the columns have been disregarded. The MTAPAD node is drawn the way I want, but its template differs in two regards: (1) it lacks the lime green underline rectangle, and (2) it doesn’t involve dynamic ports. I have other nodes that have dynamic ports and no underline rectange that also draw correctly, so I think I’m botching the addition of that lime green underline rectangle somehow. I add it with a nested vertical of two elements.

Here is the node template for the “aaa” nodes:

let $ = go.GraphObject.make;

let node = $(go.Node, "Table",
		 new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
		 {
		     toSpot: go.Spot.Left,
		     fromSpot: go.Spot.Right,
		     locationSpot: go.Spot.Center
		 },
		 $(go.Panel, "Vertical",
		   {
		       column : 1,
		   },
		   $(go.Panel, "Auto",
		     {
		     },
		     $(go.Shape, "Rectangle",
		       {
			   fill: "#333",
			   stroke: null,
			   strokeWidth: 0
		       }),
		     $(go.TextBlock, "",
		       new go.Binding("text", "name").makeTwoWay(),
                   {
			   editable: true,
			   isMultiline: false,
			   textValidation: (textblock, oldname, newname) => { return this.isEmptyOrValidCircuitName(newname, type); },
			   margin: new go.Margin(6, 6, 1.5, 6),
			   stroke: "white",
			   font: "11pt sans-serif"
                   })),
 		   $(go.Shape, "Rectangle",
 		     {
			 stretch: go.GraphObject.Fill,
			 fill: (type == "circuit" ? "lime" : (type == "entry" ? "#FFA500" : "white" )),
			 height : 6
		     })),
		 $(go.Panel, "Vertical",
		   new go.Binding("itemArray", "inports"),
		   {
		       column : 0,
		       alignment: go.Spot.Left,
		       itemTemplate: $(go.Panel,
				       new go.Binding("portId", "pid"),
				       {
					   toLinkable: true,
					   toSpot: go.Spot.Left,
					   alignment: go.Spot.TopLeft,
					   cursor: "pointer"
				       },
				       $(go.Shape, "TriangleRight",
					 {
					     fill: "#4040FF",
					     desiredSize: new go.Size(15, 15),
					 }))
		   }),
		 $(go.Panel, "Vertical",
		   new go.Binding("itemArray", "outports"),
		   {
		       column : 2,
		       alignment: go.Spot.Right,
		       itemTemplate: $(go.Panel,
				       new go.Binding("portId", "pid"),
				       {
					   fromLinkable: true,
					   fromSpot: go.Spot.Right,
					   alignment: go.Spot.TopRight,
					   cursor: "pointer"
				       },
				       $(go.Shape, "TriangleRight",
					 {
					     fill: "#4040FF",
					     desiredSize: new go.Size(15, 15),
					 }))
		   })
		);

(Not sure how to properly format that text for your website.)

Anyway, the culprit seems to be in the column 1 vertical panel. Any suggestions?

Thanks,

-Luddy
.

Your column 1 element should not be a “Vertical” Panel. Just delete it, since it’s not doing anything, and have what was its only element, an “Auto” Panel, as the only element in column 1. But what’s important is to have its GraphObject.stretch property set to go.GraphObject.Vertical.

Hi,

Thanks for the prompt response.

The column 1 element (Vertical) has two elements; the first is an Auto with gray rectangle and text superimposed; the second is a short lime green rectangle. I thought I should use the Vertical to place the former above the latter in the diagram.

I tried adding a GraphObject.stretch to this Vertical, and it has the effect of sliding the whole Auto figure up to the top of the vertical stack, so that the ports are now aligned with the top of the whole, but they extend below the bottom. I’ve updated the linked online example accordingly.

Modified node template:

let $ = go.GraphObject.make;

let node = $(go.Node, "Table",
	 new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
	 {
	     toSpot: go.Spot.Left,
	     fromSpot: go.Spot.Right,
	     locationSpot: go.Spot.Center
	 },
	 $(go.Panel, "Vertical",
	   {
	       stretch: go.GraphObject.Vertical,
	       column : 1,
	   },
	   // element #1 of Vertical
	   $(go.Panel, "Auto",
	     $(go.Shape, "Rectangle",
	       {
		   fill: "#333",
		   stroke: null,
		   strokeWidth: 0
	       }),
	     $(go.TextBlock, "",
	       new go.Binding("text", "name").makeTwoWay(),
                   {
		   editable: true,
		   isMultiline: false,
		   textValidation: (textblock, oldname, newname) => { return this.isEmptyOrValidCircuitName(newname, type); },
		   margin: new go.Margin(6, 6, 1.5, 6),
		   stroke: "white",
		   font: "11pt sans-serif"
                   })),
	   // element #2 of Vertical
	   $(go.Shape, "Rectangle",
	     {
		 stretch: go.GraphObject.Fill,
		 fill: (type == "circuit" ? "lime" : (type == "entry" ? "#FFA500" : "white" )),
		 height : 6
	     })),
	 $(go.Panel, "Vertical",
	   new go.Binding("itemArray", "inports"),
	   {
	       column : 0,
	       alignment: go.Spot.Left,
	       itemTemplate: $(go.Panel,
			       new go.Binding("portId", "pid"),
			       {
				   toLinkable: true,
				   toSpot: go.Spot.Left,
				   alignment: go.Spot.TopLeft,
				   cursor: "pointer"
			       },
			       $(go.Shape, "TriangleRight",
				 {
				     fill: "#4040FF",
				     desiredSize: new go.Size(15, 15),
				 }))
	   }),
	 $(go.Panel, "Vertical",
	   new go.Binding("itemArray", "outports"),
	   {
	       column : 2,
	       alignment: go.Spot.Right,
	       itemTemplate: $(go.Panel,
			       new go.Binding("portId", "pid"),
			       {
				   fromLinkable: true,
				   fromSpot: go.Spot.Right,
				   alignment: go.Spot.TopRight,
				   cursor: "pointer"
			       },
			       $(go.Shape, "TriangleRight",
				 {
				     fill: "#4040FF",
				     desiredSize: new go.Size(15, 15),
				 }))
	   })
	);

Thanks for indenting better.

Although a “Vertical” Panel can be stretched vertically, it will not be able to stretch its contents vertically, which I think is what you are asking for. I suggest you replace “Vertical” with “Table” and put the “Auto” Panel in row 0 and the “lime” Rectangle Shape in row 1.

Are you sure that’s what you want – having the “lime” Shape below the “Auto” Panel? Why not put the TextBlock and “lime” Shape in a “Vertical” Panel that is in the “Auto” Panel? And forget about either your “Vertical” Panel or my suggested “Table” Panel.

Well, no, I’m not sure; I’m just hunting and pecking for something that has the look I have in mind.

But you’ve given me some new ideas to try, I will experiment a bit.

Thanks,

-Luddy

This node template:

    myDiagram.nodeTemplate =
      $(go.Node, "Table",
        $(go.Panel, "Table",  // this stretches to fill the available area in both directions
          { column: 1, stretch: go.GraphObject.Fill },
          $(go.Shape,  // the gray background stretches to fill the whole cell, behind the TextBlock
            { row: 0, stretch: go.GraphObject.Fill, fill: "gray", strokeWidth: 0 }),
          $(go.TextBlock,  // this has its natural size and is centered in its cell
            { row: 0, margin: 2 },
            new go.Binding("text")),
          // The Shape in row 1 does not get any extra space vertically
          $(go.RowColumnDefinition, { row: 1, sizing: go.RowColumnDefinition.None }),
          $(go.Shape,
            { row: 1, height: 10, stretch: go.GraphObject.Horizontal, fill: "lime", strokeWidth: 0 },
            new go.Binding("fill", "color"))
        ),
        $(go.Panel, "Vertical",
          { column: 0 },
          new go.Binding("itemArray", "left")
        ),
        $(go.Panel, "Vertical",
          { column: 2 },
          new go.Binding("itemArray", "right")
        )
      );

and this data:

    myDiagram.model = new go.GraphLinksModel(
    [
      { key: 1, text: "Alpha", color: "lightblue", left: ["a"], right: ["x", "y", "z"] },
      { key: 2, text: "Beta", color: "orange", left: ["a", "b", "c", "d", "e"], right: ["x", "y", "z"] },
      { key: 3, text: "Gamma", color: "lightgreen", left: ["a"], right: ["v", "w", "x", "y", "z"] },
      { key: 4, text: "Delta", color: "pink" }
    ],
    [
      { from: 1, to: 2 },
      { from: 1, to: 3 },
      { from: 3, to: 4 },
      { from: 4, to: 1 }
    ]);

produce:
image

Note that I didn’t bother specifying any Panel.itemTemplate, so there’s only one port on each node, not one for each item.

For clarity I did set row: 0 and column: 0, although those are the default values for those properties and thus do not need to be set.

Walter,

That’s fantastic, thanks so much. Exactly the effect I was looking for.

-Luddy