The node setting svg image causes the port and decoration position to be messed up。

Below is the code screenshot and result


微信截图_20220210154921
Excuse me how to solve?

It’s better to paste and format the code so that we can actually try it.

I suspect the main problem is that you are trying to resize the inner “Spot” Panel rather than the Shape. Try setting resizeObjectName to “SHAPE”.

1 Like

thanks for the reply

What I need to adjust is the shape, not the spot. The main problem is that half of the svg image is set outside the shape, which will cause the ports and decorations to be in disorder. If the svg image is not set or set inside the shape, everything is normal.

Below is the main code snippet

const nodeSelectionAdornmentTemplate =
$(go.Adornment, 'Auto',
  $(go.Shape, { fill: null, stroke: '#3699FF', strokeWidth: 1 }),
  $(go.Placeholder)
)

const nodeResizeAdornmentTemplate =
$(go.Adornment, 'Spot',
  { locationSpot: go.Spot.Right },
  $(go.Placeholder),
  $(go.Shape, { alignment: go.Spot.TopLeft, cursor: 'nw-resize', desiredSize: new go.Size(6, 6), fill: 'white', stroke: '#3699FF' }),
  $(go.Shape, { alignment: go.Spot.TopRight, cursor: 'ne-resize', desiredSize: new go.Size(6, 6), fill: 'white', stroke: '#3699FF' }),
  $(go.Shape, { alignment: go.Spot.BottomLeft, cursor: 'se-resize', desiredSize: new go.Size(6, 6), fill: 'white', stroke: '#3699FF' }),
  $(go.Shape, { alignment: go.Spot.BottomRight, cursor: 'sw-resize', desiredSize: new go.Size(6, 6), fill: 'white', stroke: '#3699FF' })
)

myDiagram.nodeTemplate =
          $(go.Node, 'Spot',
            {
              fromMaxLinks: 1, toMaxLinks: 1,
              contextMenu: myContextMenu,
              locationSpot: go.Spot.Center,
              locationObjectName: 'SHAPE',
              selectable: true,
              resizable: true,
              resizeObjectName: 'PANEL',
              selectionObjectName: 'SHAPE',
              resizeAdornmentTemplate: nodeResizeAdornmentTemplate,
              selectionAdornmentTemplate: nodeSelectionAdornmentTemplate
            },
            new go.Binding('location').makeTwoWay(),
            new go.Binding('angle').makeTwoWay(),
            $(go.Panel, 'Spot',
              { name: 'PANEL' },
              new go.Binding('desiredSize', 'size', go.Size.parse).makeTwoWay(go.Size.stringify),
              $(go.Shape, 'Rectangle',
                {
                  name: 'SHAPE',
                  cursor: 'move',
                  fill: 'white',
                  strokeWidth: 1
                },
                new go.Binding('figure'),
                new go.Binding('fill', 'color')
              ),
              $(go.Picture,
                {
                  background: '#fff',
                  alignment: new go.Spot(0.25),
                  width: 16,
                  height: 16
                },
                new go.Binding('source', 'svg')
              )
            ),
            $(go.TextBlock,
              {
                font: 'bold 9pt Helvetica, Arial, sans-serif',
                margin: 8,
                wrap: go.TextBlock.WrapFit,
                verticalAlignment: go.Spot.Center,
                editable: true,
                overflow: go.TextBlock.OverflowEllipsis,
                maxSize: new go.Size(NaN, NaN)
              },
              new go.Binding('text').makeTwoWay()
            ),
            this.makePort('T', go.Spot.Top, true, true),
            this.makePort('L', go.Spot.Left, true, true),
            this.makePort('R', go.Spot.Right, true, true),
            this.makePort('B', go.Spot.Bottom, true, true),
            {
              mouseEnter: (e, node) => { this.showSmallPorts(node, true) },
              mouseLeave: (e, node) => { this.showSmallPorts(node, false) }
            }
          )

makePort(name, spot, output, input) {
      return $(go.Shape, 'Circle', {
        fill: null,
        stroke: null,
        desiredSize: new go.Size(7, 7),
        alignment: spot,
        portId: name,
        fromSpot: spot, toSpot: spot,
        fromLinkable: output, toLinkable: input,
        cursor: 'crosshair',
        mouseEnter: function(e, port) {
          port.desiredSize = new go.Size(14, 14)
          port.fill = '#D4E9FF'
        },
        mouseLeave: function(e, port) {
          port.desiredSize = new go.Size(7, 7)
          port.fill = '#fff'
        }
      })
    },

showSmallPorts(node, show) {
      const isGroup = node instanceof go.Group
      if (isGroup) return
      node.ports.each(port => {
        if (port.portId !== '') {
          port.fill = show ? '#fff' : null
        }
      })
    },

What I need to adjust is the shape, not the spot [panel].

Exactly. Try setting resizeObjectName to “SHAPE”.

hello,I’ve tried setting ‘resizeObjectName’ to ‘SHAPE’, the decoration will go back to normal, but resize the node, the node size will not change. And the svg image position will change accordingly.
In addition, the port position will also be confused. Do you know the solution?
微信截图_20220211111732

微信截图_20220211112358
You can see that due to the setting of the svg position, the node as a whole has been displaced downward by a part. Is there any way to make the node move up by the same distance?

I used your code, with some modifications because I was missing some definitions (that don’t matter for this issue). I set Node.resizeObjectName to “SHAPE”, and because I don’t have your SVG, I set the Picture.background to “red”.

Resizing shifts the ports appropriately, if that is what you are asking about:
image

Thanks a lot, this is exactly what I need, I can you take a look at your modified code?

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

  <script src="https://unpkg.com/gojs"></script>
  <script id="code">
function init() {
  const $ = go.GraphObject.make;

  myDiagram =
    $(go.Diagram, "myDiagramDiv",
      {
        "undoManager.isEnabled": true
      });

  const nodeSelectionAdornmentTemplate =
    $(go.Adornment, 'Auto',
      $(go.Shape, { fill: null, stroke: '#3699FF', strokeWidth: 1 }),
      $(go.Placeholder)
    )

  const nodeResizeAdornmentTemplate =
    $(go.Adornment, 'Spot',
      { locationSpot: go.Spot.Right },
      $(go.Placeholder),
      $(go.Shape, { alignment: go.Spot.TopLeft, cursor: 'nw-resize', desiredSize: new go.Size(6, 6), fill: 'white', stroke: '#3699FF' }),
      $(go.Shape, { alignment: go.Spot.TopRight, cursor: 'ne-resize', desiredSize: new go.Size(6, 6), fill: 'white', stroke: '#3699FF' }),
      $(go.Shape, { alignment: go.Spot.BottomLeft, cursor: 'se-resize', desiredSize: new go.Size(6, 6), fill: 'white', stroke: '#3699FF' }),
      $(go.Shape, { alignment: go.Spot.BottomRight, cursor: 'sw-resize', desiredSize: new go.Size(6, 6), fill: 'white', stroke: '#3699FF' })
    )

  myDiagram.nodeTemplate =
    $(go.Node, 'Spot',
      {
        fromMaxLinks: 1, toMaxLinks: 1,
        locationSpot: go.Spot.Center,
        locationObjectName: 'SHAPE',
        selectable: true,
        resizable: true,
        resizeObjectName: 'SHAPE',
        selectionObjectName: 'SHAPE',
        resizeAdornmentTemplate: nodeResizeAdornmentTemplate,
        selectionAdornmentTemplate: nodeSelectionAdornmentTemplate
      },
      new go.Binding('location').makeTwoWay(),
      new go.Binding('angle').makeTwoWay(),
      $(go.Panel, 'Spot',
        { name: 'PANEL' },
        new go.Binding('desiredSize', 'size', go.Size.parse).makeTwoWay(go.Size.stringify),
        $(go.Shape, 'Rectangle',
          {
            name: 'SHAPE',
            cursor: 'move',
            fill: 'white',
            strokeWidth: 1
          },
          new go.Binding('figure'),
          new go.Binding('fill', 'color')
        ),
        $(go.Picture,
          {
            background: 'red',
            alignment: new go.Spot(0.25),
            width: 16,
            height: 16,
          },
          new go.Binding('source', 'svg')
        )
      ),
      $(go.TextBlock,
        {
          font: 'bold 9pt Helvetica, Arial, sans-serif',
          margin: 8,
          wrap: go.TextBlock.WrapFit,
          verticalAlignment: go.Spot.Center,
          editable: true,
          overflow: go.TextBlock.OverflowEllipsis,
          maxSize: new go.Size(NaN, NaN)
        },
        new go.Binding('text').makeTwoWay()
      ),
      makePort('T', go.Spot.Top, true, true),
      makePort('L', go.Spot.Left, true, true),
      makePort('R', go.Spot.Right, true, true),
      makePort('B', go.Spot.Bottom, true, true),
      {
        mouseEnter: (e, node) => { showSmallPorts(node, true) },
        mouseLeave: (e, node) => { showSmallPorts(node, false) }
      }
    )

  function makePort(name, spot, output, input) {
    return $(go.Shape, 'Circle', {
      fill: null,
      stroke: null,
      desiredSize: new go.Size(7, 7),
      alignment: spot,
      portId: name,
      fromSpot: spot, toSpot: spot,
      fromLinkable: output, toLinkable: input,
      cursor: 'crosshair',
      mouseEnter: function(e, port) {
        port.desiredSize = new go.Size(14, 14)
        port.fill = '#D4E9FF'
      },
      mouseLeave: function(e, port) {
        port.desiredSize = new go.Size(7, 7)
        port.fill = '#fff'
      }
    })
  }

  function showSmallPorts(node, show) {
    const isGroup = node instanceof go.Group
    if (isGroup) return
    node.ports.each(port => {
      if (port.portId !== '') {
        port.fill = show ? '#fff' : null
      }
    })
  }

  myDiagram.model = new go.GraphLinksModel(
    {
      linkFromPortIdProperty: "fpid",
      linkToPortIdProperty: "tpid",
      nodeDataArray:
        [
          { key: 1, text: "Alpha", color: "lightblue" },
          { key: 2, text: "Beta", color: "orange" },
        ],
      linkDataArray:
        [
          { from: 1, fpid: "B", to: 2, tpid: "B" },
        ]
    });
}
window.addEventListener('DOMContentLoaded', init);
  </script>
</body>
</html>

Thanks for the reply, I used your code to create a new html test run, and it achieved the desired effect, but I don’t think you have changed any code… In addition, since my project uses the 2.1.52 version of gojs downloaded by npm, I switched the gojs link version of the code you replied to version 2.1, and an error was reported
微信截图_20220214163548

When you are starting a new project you should always use the latest stable version of all of the components that you use.

I tried to upgrade the gojs version of the project to 2.2, but the situation is still the same as before, the decoration and port position are messed up, what other code will affect this?
微信截图_20220215090817
微信截图_20220215090851
微信截图_20220215090858

I believe the code I posted above gives you the appearance and the behavior that I think you are asking for. If that is not the case, please explain in more detail what the problem is.

Are you using my node template without modifications other than the sizes of objects? If so, please post your code in a form so that I can try it.

Hi, regarding the node part, I really only need to modify the object size.

Since I use the framework to build the project, and the function of this module is more complex and the amount of code is large, I can only provide the part of the code of the node template that I think caused the error, I will check my code again.

thank you for your reply!

I found the reason, because the node is set with a size. After adding the svg image, Some svg images are displayed outside the node,A part of the graph outside the node occupies the node space,the height is not enough, which causes the node to be partially invisible and the position is scattered.

Also my resizeObjectName cannot be set to SHAPE, it needs to be set to PANEL, because I need to resize PANEL, not SHAPE.

Is there any solution please?

微信截图_20220215143343

微信截图_20220215143021

In your code above, the “PANEL” Panel is of type “Spot” and it holds the Picture which it aligns to be half-outside above the main “Rectangle” Shape. So the total height of the panel must be taller than just the rectangle shape. But it appears that you want the user to be resizing the rectangle shape. Therefore the resizeObjectName should refer to the Shape, not the Panel.

You have already confirmed that the behavior of my code, which is just your code that I altered, appears and behaves correctly.

thanks walter
I solved the problem by some other methods