How to align the node in center based on the background grid

I want to set node position in the center of every rectangle while drag from palette it should automatically fit according to rectangle size.

this.node = goInstance(go.Node, “Auto”,

        { rotatable: true, width:100,height:100, selectable: true,

        }, 

grid: this._goInstance(go.Panel, “Grid”,

             { gridCellSize: new go.Size(100, 100) },

and I have set the
this.diagram.toolManager.draggingTool.isGridSnapEnabled = true;

Set https://gojs.net/latest/api/symbols/DraggingTool.html#gridSnapCellSpot to Spot.Center.

$(go.Diagram, . . .,
  { "draggingTool.gridSnapCellSpot": go.Spot.Center })

You probably also want to set Node.locationSpot and Node.locationObjectName.
https://gojs.net/latest/intro/nodes.html#PositionAndLocation

actually whenever I am dragging a node from the palette the node should be fit according to grid size in the center if I will set “draggingTool.gridSnapCellSpot”: go.Spot.Center
the node placed

is there any property so that node position will fix inside the grid cell size.

I believe that what I suggested above works well. Here’s a complete sample:

<!DOCTYPE html>
<html>
<head>
  <title>Minimal GoJS Editor</title>
  <!-- Copyright 1998-2021 by Northwoods Software Corporation. -->
  <script src="https://unpkg.com/gojs"></script>
  <script id="code">
    function init() {
      var $ = go.GraphObject.make;

      // initialize main Diagram
      myDiagram =
        $(go.Diagram, "myDiagramDiv",
          {
            grid: $(go.Panel, "Grid",
              { gridCellSize: new go.Size(100, 100) },
              $(go.Shape, "LineH"),
              $(go.Shape, "LineV")
            ),
            "draggingTool.isGridSnapEnabled": true,
            "draggingTool.gridSnapCellSpot": go.Spot.Center,
            "undoManager.isEnabled": true
          });

      myDiagram.nodeTemplate =
        $(go.Node, "Spot",
          { locationSpot: go.Spot.Center, locationObjectName: "SHAPE" },
          new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
          $(go.Shape, "Circle",
            { name: "SHAPE", width: 30, height: 30, fill: "white", stroke: "gray", strokeWidth: 2 },
            new go.Binding("stroke", "color")),
          $(go.TextBlock,
            { alignment: go.Spot.Left, alignmentFocus: go.Spot.Right },
            new go.Binding("text"))
        );

      // initialize Palette
      myPalette =
        $(go.Palette, "myPaletteDiv",
          {
            nodeTemplateMap: myDiagram.nodeTemplateMap,
            model: new go.GraphLinksModel([
              { text: "R", color: "red" },
              { text: "G", color: "green" },
              { text: "B", color: "blue" },
              { text: "O", color: "orange" }
            ])
          });

      // initialize Overview
      myOverview =
        $(go.Overview, "myOverviewDiv",
          {
            observed: myDiagram,
            contentAlignment: go.Spot.Center
          });

      load();
    }

    // save a model to and load a model from Json text, displayed below the Diagram
    function save() {
      var str = myDiagram.model.toJson();
      document.getElementById("mySavedModel").value = str;
    }
    function load() {
      var str = document.getElementById("mySavedModel").value;
      myDiagram.model = go.Model.fromJson(str);
    }
    </script>
</head>
<body onload="init()">
  <div style="width: 100%; display: flex; justify-content: space-between">
    <div style="display: flex; flex-direction: column; margin: 0 2px 0 0">
      <div id="myPaletteDiv" style="flex-grow: 1; width: 100px; background-color: floralwhite; border: solid 1px black"></div>
      <div id="myOverviewDiv" style="margin: 2px 0 0 0; width: 100px; height: 100px; background-color: whitesmoke; border: solid 1px black"></div>
    </div>
    <div id="myDiagramDiv" style="flex-grow: 1; height: 400px; border: solid 1px black"></div>
  </div>
  <div id="buttons">
    <button id="loadModel" onclick="load()">Load</button>
    <button id="saveModel" onclick="save()">Save</button>
  </div>
  <textarea id="mySavedModel" style="width:100%;height:200px">
  </textarea>
</body>
</html>

yes thanks for the response you are correct but problem is here I am using html Palette and when I am dropping the node first time it is not working but after dropped when I will move the node it is working fine.

You will need to customize your HTML drag-and-drop code to get that behavior which is built into our Diagram-to-Diagram dragging implementation, which does not use HTML drag-and-drop.

This could be useful:
https://gojs.net/latest/api/symbols/Point.html#snapToGrid

Hi walter ,
I couldn’t find any solution is there any way you can suggest or else you can provide some example with html palette.
below is my code .


in html two are svg icon

public registerDefaultTemplate(nodeDTOList) {

    const goInstance = go.GraphObject.make;

    // start: add to the go instance

    this.node = goInstance(go.Node, "Auto",

        {

            rotatable: true, rotateObjectName: "FIGURE",

            locationSpot: go.Spot.Center, selectable: true, width: 55, height: 55

        },

}

private initGo() {

    this._goInstance = go.GraphObject.make;

let CellSize = new go.Size(55, 55);
let goProperties = {

       // padding: 20,  // extra space when scrolled all the way

        grid: this._goInstance(go.Panel, "Grid",

            { gridCellSize: this.CellSize },

            // this._goInstance(go.Shape, "LineH", { stroke: "lightgray" }),

            // this._goInstance(go.Shape, "LineV", { stroke: "lightgray" }) // a simple 10x10 grid

            this._goInstance(go.Shape, "LineH", { stroke: "lightgray", strokeWidth: 0.5 }),

            this._goInstance(go.Shape, "LineV", { stroke: "lightgray", strokeWidth: 0.5 })

        ),

        "draggingTool.isGridSnapEnabled": true,

        "draggingTool.gridSnapCellSpot": go.Spot.Center,

        "resizingTool.isGridSnapEnabled": true,

        "handlesDragDropForTopLevelParts": true,

        "undoManager.isEnabled": true,

        "draggingTool.dragsLink": true,

        "linkingTool.isUnconnectedLinkValid": true,

        "linkingTool.portGravity": 20

    }

}

Your code doesn’t seem to address your problem of implementing the HTML drag-and-drop.

Hi,
private onDrop(event) {

    if (event.hasOwnProperty('signal')) {

        const stateData = this.editor.assignSignal(event.droppedLocation)

    } else {

        let droppedCategory = event.dataTransfer.getData('id');

        this.editor.createNode(droppedCategory, event.droppedLocation);

    }

}

using event I am getting event.drppedLocation
and added to the model
public createNode(shape, droppedLocation) {

    let SLDShape = new SLDNode(shape);

    //console.log(SLDShape);

    SLDShape.location = go.Point.stringify(droppedLocation);

    SLDShape.signalAssigned = false;

    let sld = SLDShape;
    this.diagram.model.addNodeData(sld)

}

I doubt while dropping the node I am not getting exact location that’s what node is not coming in the center is there any while drop the node it will fit in the grid cell center.

is there any first time while I will drag the node I will git the nearest cell size location and assign to the node same location.

Have you converted the drop point into document coordinates in the same manner that the HTML Drag Drop sample does? Have you debugged it to make sure the values are correct? Do you then snap that point to the center of each grid cell?

have a look my below code ondrop I am calling this function and passing drop location this.properties.onDrop(event);
div1.addEventListener(“drop”, (event) => {

        event.preventDefault();

        console.log(event.dataTransfer);

        let draggedId = event.dataTransfer.getData('id');

        let signals = event.dataTransfer.getData('signal-data');

        let dragged = JSON.parse(event.dataTransfer.getData('dragged-data'));

        console.log(signals);

        var can = event.target;

        var pixelratio = this.diagram.computePixelRatio();

        // if the target is not the canvas, we may have trouble, so just quit:

        if (!(can instanceof HTMLCanvasElement)) return;

        var bbox = can.getBoundingClientRect();

        var bbw = bbox.width;

        if (bbw === 0) bbw = 0.001;

        var bbh = bbox.height;

        if (bbh === 0) bbh = 0.001;

        var mx = event.clientX - bbox.left * ((can.width / pixelratio) / bbw) - dragged['offsetX'];

        var my = event.clientY - bbox.top * ((can.height / pixelratio) / bbh) - dragged['offsetY'];

        var point = this.diagram.transformViewToDoc(new go.Point(mx, my));

        this.diagram.startTransaction('new node');

        this.dropLocation = point;

        event['droppedLocation'] = point;

        if (signals != "undefined") {

            event['signal'] = JSON.parse(signals);

        }

        if (this.properties.onDrop) {

            this.properties.onDrop(event);    

        }

        console.log(this.diagram.model.nodeDataArray);

        this.automaticConnection();

        this.diagram.commitTransaction('new node');

        // remove dragged element from its old location

    }, false);

And when you debug that code, is the dropLocation sensible?
You’ll want to call Point.snapToGrid.
If your Node.locationSpot is go.Spot.Center, you’ll want to add half the grid cell width and half the grid cell height.

the drop location is sensible I am getting look like this {G: -88.58305415968732, H: -141.5, s: false}

the grid cell height and width i have given 55 and 55 and Yes I have given locationspot center.
where I need to call Point.snapTogrid function
is it inside ondrop function the above I have showed you . and where I have to add
add half the grid cell with and half the grid cell height.

public registerDefaultTemplate(nodeDTOList) {
const goInstance = go.GraphObject.make;
this.node = goInstance(go.Node, “Auto”,
{
rotatable: true, rotateObjectName: “FIGURE”,
locationSpot: go.Spot.Center, selectable: true, width: 55, height: 55,
},

OK, if you have the correct point in document coordinates for the center of a grid cell, then you can either set Node.location directly on the Node that was created for you for the particular data object that you added to the model, or you can set the data property and allow binding to determine the node location.

my mistake actually the point I am getting it is not center of grid cell size
CellSize = new go.Size(55, 55);
let suppose while drag the node I am getting this location point
{G: -88.58305415968732, H: -141.5, s: false}

so after that how can align node in the center of every grid cell size automatically when I drag n number of node and If will fix the location then every node will drop same location
please explain some line of code will appreciate

    const p = myDiagram.transformViewToDoc(...);
    myDiagram.commit(diag => {
      const org = diag.grid.gridOrigin;
      const sz = diag.grid.gridCellSize;
      p.snapToGrid(org.x + sz.width/2, org.y + sz.height/2, sz.width, sz.height);
      diag.model.addNodeData({ loc: go.Point.stringify(p) })
    });

This assumes the node is something like:

    myDiagram.nodeTemplate =
      $(go.Node, . . .,
        { locationSpot: go.Spot.Center },
        new go.Binding("location", "loc", go.Point.parse),
        . . .