Drag Unoccupied

how we can implement this(Drag Unoccupied) with floor planner palette.
i tried doing so but it gives Rect is not defined

var $ = go.GraphObject.make;
return $(go.Node, “Shape”,
{
resizable: true,
rotatable: true,
toolTip: makeNodeToolTip(),
resizeAdornmentTemplate: makeFurnitureResizeAdornmentTemplate(),
rotateAdornmentTemplate: makeFurnitureRotateAdornmentTemplate(),
contextMenu: makeContextMenu(),
locationObjectName: “SHAPE”,
resizeObjectName: “SHAPE”,
rotateObjectName: “SHAPE”,
minSize: new go.Size(5, 5),
dragComputation: avoidNodeOverlap,
locationSpot: go.Spot.Center,
selectionAdorned: false, // use a Binding on the Shape.stroke to show selection
doubleClick: function (e) {
if (e.diagram.floorplanUI) e.diagram.floorplanUI.hideShow(“selectionInfoWindow”)
}
}

function avoidNodeOverlap(node, pt, gridpt) {
var bnds = node.actualBounds;
var loc = node.location;
// see if the area at the proposed location is unoccupied
var x = pt.x - (loc.x - bnds.x);
var y = pt.y - (loc.y - bnds.y);
var r = new Rect(x, y, bnds.width, bnds.height);
if (isUnoccupied(r, node)) return pt; // OK
return loc; // give up – don’t allow the node to be moved to the new location
}

All GoJS types are in the “go” namespace, so references should normally be prefixed with “go.”.

Thanks walter.
However, I did notice that when entering the target diagram, the new node could be created overlapping an existing node.
I need that the new node/object should not overlap existing node/object, it should move to adjacent to existing node when dropped on existing node.

Even if such a location is far away – beyond the viewport? What if there is no such location?

i will have fixed window like above shown (Rectangular box),
where the node/object will be dropped.

You did not answer my question about what to do when there is no empty place. Or how to decide on a location if there are multiple empty places.

if there is no empty place than,
the palette will be disable so that no new node/object can be dragged

Here’s a variation of avoidNodeOverlaps that automatically moves a node to somewhere if it’s just been created.

    // a Part.dragComputation function that prevents a Part from being dragged to overlap another Part
    function avoidNodeOverlap(node, pt, gridpt) {
      if (node.diagram instanceof go.Palette) return gridpt;
      // this assumes each node is fully rectangular
      var bnds = node.actualBounds;
      var loc = node.location;
      if (node.layer.isTemporary && node.avoidable &&
          !isUnoccupied(bnds.copy().inflate(-1, -1), node)) {
        node.avoidable = false;
        // find an empty area for this NODE and move it there
        // for now, just blindly choose an offset of 200,50 from its current location
        // bnds = bnds.copy().offset(200, 50);
        return loc.copy().offset(200, 50);
      }
      // see if the area at the proposed location is unoccupied
      // use PT instead of GRIDPT if you want to ignore any grid snapping behavior
      var x = gridpt.x - (loc.x - bnds.x);
      var y = gridpt.y - (loc.y - bnds.y);
      var r = new go.Rect(x, y, bnds.width, bnds.height);
      // maybe inflate R if you want some space between the node and any other nodes
      if (isUnoccupied(r.inflate(-1, -1), node)) return gridpt;  // OK
      return loc;  // give up -- don't allow the node to be moved to the new location
    }

NOTE: the above code is not smart about finding an empty location – you’ll need to implement that. As you can see, right now it blindly shifts the node by 200,50 without checking for whether that’s OK or not, nor whether it’s the closest empty location, nor whether it meets whatever other requirements you have.

In case you happen to use avoidNodeOverlap in the Palette, it checks for that and just returns the given new location point, so it does not affect the movement of nodes in the Palette.