Polygon group limitation

Currently when I have two go groups of polygon (any random shape), it doesn’t let me place them close to each other, since their selection adornments are rectangular, and I am forced to place the two groups thinking in my mind like they are rectangles, how can I ditch the rectangular selection adornment and instead have the selection adornment as a shape of the polygonal group itself, so that I can place groups upfront along their actual boundary ? (You can ignore the point that it does not allow the groups to overlap when dragging since I have a custom class of dragComputation in work there, although even that calculates over the rectangular selection adornment )

Refer the below gif

polygon_issue

Please read GoJS Selection -- Northwoods Software. You could try for a custom Adornment, but it would be easier to just change the Shape.fill or Shape.stroke color when the group is selected, as described in the section GoJS Selection -- Northwoods Software.

The hard part will be in computing non-rectangular intersections, unlike what I did for you in Inside Parts shouldn't move on Group resize - #27 by Abhishek

I did check both pages before writing this question,
I have the same query, how can changing the fill or stroke on group selection change the group selection adornment shape ? I tried implementing but doesnt seem to help.
but can I apply a selection custom adornment ? I tried many ways but doesnt seem to work. Have a look at my code below.

Also thanks for raising concern over my previous question, I understand that can be hard, but can take it up afterwards.

$( go.Group,
      go.Group.Spot,
      {
        layerName: "BlockLayer",
        locationSpot: go.Spot.TopLeft
      },
      {
        // This is to prevent the overlap both while creating and dragging
        dragComputation: avoidNodeOverlap
      },
      {
        selectionAdorned: false,
        selectionObjectName: "SHAPE",
        // custom selection adornment: a blue rectangle
        selectionAdornmentTemplate: $(
          go.Adornment,
          "Auto",
          $(go.Shape, { stroke: "dodgerblue", fill: null }),
          $(go.Placeholder, { margin: -1 })
        )
      },
      { resizable: true, resizeObjectName: "SHAPE" },
      { reshapable: true },
      $(
        go.Shape,
        {
          name: "SHAPE",
          fill: groupFill,
          stroke: groupStroke
        },
        new go.Binding("desiredSize", "size", go.Size.parse).makeTwoWay(
          go.Size.stringify
        ),
        new go.Binding("angle").makeTwoWay(),
        new go.Binding("geometryString", "geo").makeTwoWay()
      ),
      {
        resizable: true,
        resizeObjectName: "SHAPE"
        // because the gridSnapCellSpot is Center, offset the Group's location
        // locationSpot: new go.Spot(0, 0, CellSize.width / 2, CellSize.height / 2),
        // zOrder:1
      },
      // always save/load the point that is the top-left corner of the node, not the location
      new go.Binding("position", "pos", go.Point.parse).makeTwoWay(
        go.Point.stringify
      ),

Well, you have disabled selection adornments for those nodes, but I assume you know that.

So, do you really want an Adornment, or do you want to change the appearance of the group’s Shape?

OK, so after your previous comment I suppose selection adornment and the polygon group containing Rectangle are two totally separate entities ? is that so ? If yes, I do not at all care if my group has an adornment, I only need my gojs layout to treat my polygon shape as if it’s a shape in itself. I do not want a containing rectangle around my polygon to control its boundaries.
So if you see the GIF above, I want my group2 to enter the cavity area in group1, without saying that group2 has overlapped group1 since the actual polygonal shapes do not overlap.( like below )

image

An Adornment is a completely separate Part that is associated with the adorned Part. The presence or size of a “Selection” Adornment has no effect on dragging (the DraggingTool) or on any other operation. That is one of the good things about using Adornments. But changing some Shape.fill or Shape.stroke won’t affect any other operations either. (However changing the Shape.strokeWidth may do so, because changing the size of the Shape may result in other objects being positioned or sized differently.)

So the problem is that you have a Part.dragComputation function, or some other restrictions on the DraggingTool’s behavior, that is preventing the user from moving there. You “just” have to remove those restrictions.

Although removing the dragComputation lets me move there, but even lets me overlap groups, which I do not want. Below is my implementation for dragComputation. Is it possible to not allow it to overlap polygonal group into its actual boundary by calculating non-rectangular boundaries ?

function isUnoccupied(r, node) {
  var diagram = node.diagram;

  // nested function used by Layer.findObjectsIn, below
  // only consider Parts, and ignore the given Node and any Links
  function navig(obj) {
    var part = obj.part;
    if (part === node) return null;
    if (part instanceof go.Link) return null;

    // add these two checks:
    if (part.isMemberOf(node)) return null;
    if (node.isMemberOf(part)) return null;

    return part;
  }

  // only consider non-temporary Layers
  var lit = diagram.layers;
  while (lit.next()) {
    var lay = lit.value;
    if (lay.isTemporary) continue;
    if (lay.findObjectsIn(r, navig, null, true).count > 0) return false;
  }
  return true;
}

// 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;
  // use PT instead of GRIDPT if you want to ignore any grid snapping behavior
  // see if the area at the proposed location is unoccupied
  var r = new go.Rect(
    gridpt.x - (loc.x - bnds.x),
    gridpt.y - (loc.y - bnds.y),
    bnds.width,
    bnds.height
  );
  // maybe inflate R if you want some space between the node and any other nodes
  r.inflate(-0.5, -0.5); // by default, deflate to avoid edge overlaps with "exact" fits
  // when dragging a node from another Diagram, choose an unoccupied area
  if (
    !(node.diagram.currentTool instanceof go.DraggingTool) &&
    (!node._temp || !node.layer.isTemporary)
  ) {
    // in Temporary Layer during external drag-and-drop
    node._temp = true; // flag to avoid repeated searches during external drag-and-drop
    while (!isUnoccupied(r, node)) {
      r.x += 10; // note that this is an unimaginative search algorithm --
      r.y += 10; // you can improve the search here to be more appropriate for your app
    }
    r.inflate(0.5, 0.5); // restore to actual size
    // return the proposed new location point
    return new go.Point(r.x - (loc.x - bnds.x), r.y - (loc.y - bnds.y));
  }
  if (isUnoccupied(r, node)) return gridpt; // OK
  return loc; // give up -- don't allow the node to be moved to the new location
}

Yes, it is possible, but the GoJS API does not offer that functionality – it would have to be written. I have already given you folks a partial solution, one that works for seeing if a rectangle intersects with a polygon. That would need to be extended to work with polygons instead of rectangles.

Can I ask you to point out the one you are mentioning.

I don’t want to mention names or email addresses in a public forum. Has no one else in your group been communicating with us today?

NO i dont expect that either, wanted to know the exact snippet, there has been a lot of talking and to find out the right one is confusing. Anyways, let me just do the searching.

In 2.1.9 we’ll add an undocumented function that will make it easier to implement a predicate that determines whether two polygonal Shapes intersect each other. That will probably be released next week, after which I can give you that code.

I’ll be waiting for that. Thanks!

See this sample: Page Not Found -- Northwoods Software Note that it depends on some undocumented static functions that have just been exposed in version 2.1.9.

The shapeContainsRect function is a predicate for deciding whether a Rect in document coordinates is fully contained by a given Shape’s Shape.geometry, which is assumed to be polygonal. (No curves or arcs.) This function might be useful when trying to keep a node within a particular area.

The shapeIntersectsShape function is a predicate for deciding whether two polygonal Shapes intersect each other. This function might be useful when trying to keep a node outside of a particular area.