Limited Group Resizing

I am trying to implement a similar logic to this example Limited Group Resizing

The main difference is that the resizeObject of some of my nodes doesn’t take all the area.

There are some other parts which are not resizable. Such as the label, and some other things. It’s basically a rectangle inside another rectangle.

I am trying to figure out a way to prevent the overflow of the container. Not only the resizableObject.

I end up with complex calculations that initially store the difference between the resizeObject and the outer container.

const aoab = this.adornedObject.part.actualBounds.copy();
const roab = this.adornedObject.part.resizeObject.part.actualBounds.copy();
// Store this somewhere
const topLeftSize = new go.Size(Math.abs(aoab.x - roab.x), Math.abs(aoab.y - roab.y));
// Same for the other 3 points: topRight, bottomLeft, bottomRight

Then in computeResize, I use these values to calculate the outer rectangle dimension.

That works well, until I rotate the nodes. I end up spending few days for nothing so far. Basically nothing work as expected whatever I try.

Note: In my use case, the problem occurs only when resizing the nodes inside a group. For group resize it works as expected since I don’t support rotation and it was pretty much like the code snippet in the example.

Any hint or idea would be very much appreciated.

Thank you.

I believe that the code I wrote is not working when rotating because I am using the actualBounds. That won’t help much when rotating the Node.

Instead, I need to get the local points of the resizeObject inside the container.

The thing is, in most cases, the container is not the direct parent of the resizeObject. Usualy there are different Panels in between. So I am not sure how can I get the local points regardless of the angle value.

If I get these values, I could probably use them later to get the accurate points that I am looking for. Something like:

            const tr = this.adornedObject.getDocumentPoint(
                new go.Point(newRect.right + offsetRight, newRect.top - offsetTop),
            );
            const bl = this.adornedObject.getDocumentPoint(
                new go.Point(newRect.left - offsetLeft, newRect.bottom + offsetBottom),
            );

Sorry for my poor design skills.

[EDIT – our replies crossed by each other]

Yes, you need to use GraphObject.getDocumentPoint. But I’m curious when you are calling it. You might need to call Part.ensureBounds so that the bounds of every visible element in the node is up-to-date if you are depending on the bounds of objects during a tool operation while you are modifying them. If that doesn’t help, don’t call it.

Just to be clear, you have rotated the member nodes of the group, not the group itself, correct? It should then be the case that the actualBounds will be the orthogonal rectangle that encompasses the rotated GraphObject. See for example: GoJS Shapes -- Northwoods Software

Also, more generally: GoJS Coordinate Systems-- Northwoods Software

Yep exactly I rotate the nodes of the group.

I made an example here on codesandbox that shows the problem.

image

Basically I want to make the else clause in the computeResize (resizingTool ) works the same as the stayInGroup method.

I didn’t notice this method until now to be honest with you. I will try to explore its logic more in the coming few days.

The stayInGroup function is just for affecting the behavior of the DraggingTool.
Its implementation depends a lot on the design of the templates.

I could not open that codesandbox example.

My bad. Can you open it now ?

I believe that the design of the custom ResizingTool was that the user would be resizing the whole Node. So I think you want to try using the node’s future bounds rather just the size and position (in document coordinates!) of newRect.

One problem is that in general one cannot know what size the node will be when an element of it changes size. The easiest solution is to change the size and then call Node.ensureBounds so that you can look at the value of Node.actualBounds. However, that is not done by the computeResize method – it is only done by the resize method using the result of the computeResize method.

However you might be able to make some assumptions about the node template(s) that the user will be resizing. In the example of your codesandbox, it appears that the Node height will always be larger than the panel height of resized element by the height of the blue square. So your code could just add that before calling _checkNodeIntersections or whatever.

If the element is not at angle == zero, you’ll need to compute the rotated width and height of the element and use that in your calculations for the future size of the whole Node.