Create a resizeable NodeTemplate (Image & Title)

I’ve got some difficulty creating a resizeable node that contains an Image and a Title. The Diagram is configured to use a Grid Layout like in the Planogram Sample.

What I got so far:


But as you can see, the image is behind the title, and I was unable to add spacing between them. Here is the node template:

new Node(Panel.Auto, {
      resizable: true,
      resizeObjectName: 'PANEL',
      locationSpot: new Spot(0, 0, 50 / 2, 50 / 2),
    }).add(
      new Panel(Panel.Auto, {
        name: 'PANEL',
        background: 'white',
        minSize: new Size(100, 100),
        desiredSize: new Size(100, 100),
      })
        .add(
          new Picture({
            imageStretch: GraphObject.Uniform,
            name: 'IMAGE',
          }).bind('source', '', (data: Element) => {
            return data.image;
          }),
        )
        .add(
          new Panel(Panel.Auto, {
            alignment: Spot.BottomCenter,
            alignmentFocus: Spot.TopCenter,
            alignmentFocusName: 'IMAGE',
            stretch: GraphObject.Horizontal,
            margin: new Margin(10, 0, 0, 0),
            background: '#3F7899',
            minSize: new Size(100, 10),
          }).add(
            new TextBlock({
              stretch: GraphObject.Horizontal,
              background: '#3F7899',
              margin: 10,
              textAlign: 'center',
              stroke: 'white',
            }).bind('text', 'name'),
          ),
        ),
    )

The Grid has a 50×50 Size.

Do you have any Idea how I could add some spacing between the Image and the text while still being able to resize the node?

Thanks in advance

One problem is that you are using two Panels of type “Auto” that do not have two (or more) elements in them. The purpose of “Auto” panels is to wrap the main element around the other element(s) – like a border shape around something.

I don’t understand exactly what resizing behavior you want. But here’s my best guess. Note how much simpler the node template is.

<!DOCTYPE html>
<html>
<head>
  <title>Minimal GoJS Sample</title>
  <!-- Copyright 1998-2023 by Northwoods Software Corporation. -->
</head>
<body>
  <div id="myDiagramDiv" style="border: solid 1px black; width:100%; height:600px"></div>
  <textarea id="mySavedModel" style="width:100%;height:250px"></textarea>

  <script src="go.js"></script>
  <script id="code">
const $ = go.GraphObject.make;

const myDiagram =
  $(go.Diagram, "myDiagramDiv",
    {
      "grid.visible": true,
      "draggingTool.isGridSnapEnabled": true,
      "draggingTool.gridSnapCellSize": new go.Size(50, 50),
      "undoManager.isEnabled": true,
      "ModelChanged": e => {     // just for demonstration purposes,
        if (e.isTransactionFinished) {  // show the model data in the page's TextArea
          document.getElementById("mySavedModel").textContent = e.model.toJson();
        }
      }
    });

myDiagram.nodeTemplate =
  new go.Node(go.Panel.Table, {
      resizable: true,
      resizeCellSize: new go.Size(50, 50),
      background: 'white',
      minSize: new go.Size(100, 100),
      desiredSize: new go.Size(100, 100)
    })
    .bind("desiredSize", "size", go.Size.parse, go.Size.stringify)
    .bind("location", "loc", go.Point.parse, go.Point.stringify)
    .addRowColumnDefinition(new go.RowColumnDefinition({ row: 1, sizing: go.RowColumnDefinition.None }))
    .add(
      new go.Picture({
        row: 0,
        stretch: go.GraphObject.Fill,  // expand to fill the table cell
        imageStretch: go.GraphObject.Uniform,
        //background: "lime"  // for debugging the size of the Picture
      }).bind('source', 'image'),
      new go.TextBlock({
        row: 1,
        stretch: go.GraphObject.Horizontal,
        background: '#3F7899',
        textAlign: 'center',
        stroke: 'white',
        margin: new go.Margin(5, 0, 0, 0) // the space above the textblock
      }).bind('text', 'color')
    );

myDiagram.model = new go.GraphLinksModel(
[
  { key: 1, text: "Alpha", color: "lightblue", image: "../samples/images/hs1.jpg", loc: "0 0" },
  { key: 2, text: "Beta", color: "orange", image: "../samples/images/hs2.jpg", loc: "200 0" },
  { key: 3, text: "Gamma", color: "lightgreen", image: "../samples/images/hs3.jpg", loc: "0 150" },
  { key: 4, text: "Delta", color: "pink", image: "../samples/images/hs4.jpg", loc: "150 200" }
]);
  </script>
</body>
</html>

After resizing three of the four nodes:

1 Like

Thank you, you’re right, it’s way simpler. :)