Diagram gets resized after dragging a node from the palette

Hi,

I’ve encountered strange behaviour during dragging a node from the palette.

In my project, i overloaded a dragging tool to update some nodes templates during dragging over a node. Because of that, the diagram get’s resized.

The issue occurs only if we drag a node from the palette. If we drag a node from the diagram, everything is just fine.

Is there any option to block this kind of behaviour, so the diagram size doesn’t change?

There is a short video
https://share.vidyard.com/watch/3UsZGg3reA9SEe9rTWCvT3

and the example code

<html>
<head>
    <script src="https://gojs.net/latest/release/go-debug.js"></script>
    <script id="code"/>
    function init() {
        var $ = go.GraphObject.make;  
      
        myDiagram =
          $(go.Diagram, "myDiagramDiv", 
            {
              initialContentAlignment: go.Spot.Center,
              allowDrop: true, 
              allowVerticalScroll: false,
              allowHorizontalScroll: true
            });
        
            
        var templates = new go.Map("string", go.Panel);
        templates.add('cat1',  $(go.Node, "Auto",  
          $(go.Shape, "RoundedRectangle", 
            { fill: "red"})));
      
          templates.add('cat2',  $(go.Node, "Auto",  
          $(go.Shape, "RoundedRectangle", 
            { fill: "green"})));
      
          myDiagram.nodeTemplateMap = templates;
      
        myPalette =
          $(go.Palette, "myPaletteDiv",  
            {
              nodeTemplateMap: myDiagram.nodeTemplateMap, 
              model: new go.GraphLinksModel([{ key: "1", category: 'cat1' }])
            });
      
            var draggingTool = myDiagram.toolManager.draggingTool;
      
            draggingTool.doDragOver = function(pt, obj) {
              var category = myDiagram.model.nodeDataArray[0].category;
                myDiagram.model.setCategoryForNodeData(myDiagram.model.nodeDataArray[0], category === 'cat1' ? 'cat2' : 'cat1');  
            };
      }
    </script>
</head>
<body onload="init()">
    <div style="display: flex; margin-top: 100px">
        <div id="myPaletteDiv" style="width: 200px; margin-left: 10px; background-color: whitesmoke; border: solid 1px black"></div>
        <div id="myDiagramDiv" style="width: 600px; height: 300px; border: solid 1px black"></div>
      </div>
</body>
</html>

I’ll take a look at this a bit later today.

When you change the category/template of a node you will cause a layout to happen, and that might cause the Diagram.documentBounds to be recalculated. However, I’m not sure that that is the problem here.

In playing with your sample (thank you for creating it!) it isn’t clear to me exactly what behavior you wanted and what you didn’t want.

First I’ll mention that since you turned off Diagram.allowVerticalScroll, you might also be interested in setting:

  autoScrollRegion: new go.Margin(0, 20),  // just on the left and right sides

Second, the difference between when you have the customized DraggingTool with your override of DraggingTool.doDragOver is that changing the category/template of a node will normally invalidate the layout, which in turn will cause the Diagram.documentBounds to be updated. You can disable that by setting Layout.isOngoing to false on your Diagram.layout:

  layout: $(go.Layout, { isOngoing: false })

Third, because your doDragOver is continually recreating a node with every single mouse move event (due to that override not considering whether the mouse is over any Part at all or whether it should toggle the category unconditionally), this means that layouts are happening continually during a drag. You can disable that by setting Layout.isRealtime to false.

  layout: $(go.Layout, { isOngoing: false, isRealtime: false })

But even after these changes it still isn’t clear to me whether this is the behavior that you want.

In my project, I change the node template only when the mouse is entering or leaving the 200px area near the node, so it’s not changing constantly as in the example.

I tried using the isOngoing property and reLayouting the diagram with diagram.layoutDiagram(true) only on the drag start (as it is when I really need to layout the diagram). But even with that approach when the template is changing when the mouse is close to the edge, the bounds are getting changed (i checked that layout is not firing when this happens).

Did you set Diagram.autoScrollRegion as I suggested?

Yes, it didn’t help.

Then I do not understand exactly what behavior you are trying to avoid.

I would have suggested looking at Absolute positioning within the viewport, but that does not apply because you do want to support scrolling horizontally. But maybe it does apply?