Keeping parts within the viewport

We are trying to design an app in which we can drag a graphObject from Palette section onto Canvas section.

Inspiration: Planogram sample

Now, We are trying to add some additional things than can be done like,

  1. Using fixedBounds property, setting documentBounds equal to the viewportBounds.

  2. To be not able to resize an element beyond the viewport. Using “PartResized” event, we are able to set the actual bounds of the element to be with in the viewport when trying to resize out of the viewport.

  3. To be not able to reposition an element beyond the viewport.

We are using “SelectionMoved” event, and we are able to access the actualBounds of the element but we are unable to modify the actualBounds to be with in the viewport when we position it beyond the viewport. Need some help with this.

Screenshot of the event subject details.

The problem with the “SelectionMoved” DiagramEvent is that the selected parts have already been moved. Instead, you want to set the Part.dragComputation functional property, since the DraggingTool calls that to determine where the dragged Part may be moved.

The documentation for Part.dragComputation includes as an example the “stayInViewport” function, which might be what you want to use.

You will probably also want to set Diagram.autoScrollRegion = 0 [or equivalently, new go.Margin(0,0,0,0)] in order to disable autoscrolling.

I have been able to use Part.dragComputation successfully. There is an example “stayInGroup” function in the documentation and I modified the conditions as follows. All the coordinates below are view coordinates.

-> Top left point will be coordinates of the top left point of canvas area i.e, (0,0).
-> Bottom right point will be coordinates of the bottom right point of canvas area i.e, (boxWidth, boxHeight).

Please correct if I’m wrong in the above procedure or concept.

Also, regarding the second point in my original post, I have used “PartResized” event. So, the part will be resized first and then if the resized part is beyond bounds, we reset the size to maximum possible size.

Instead of this, is there a different way to be not able to resize the part beyond the viewport?

I recommend that you use the “stayInViewport” function, in the documentation for the Part class. I believe you should be able to use that as your Part.dragComputation function, unaltered.

You’ll need to override the DraggingTool.computeResize method. If you don’t mind waiting a bit, I hope to work on implementing this later today.

Ah, sorry about that – the “stayInViewport” function is new in the documentation for version 1.5: http://gojs.net/latest/api/symbols/Part.html#dragComputation

A major change in the requirement of the app that we are designing.

Limits for the graphObject to move/resize on left, top and right sides are equal to the viewport sides. But the graphObject should be able to move/resize on the bottom edge infinitely.

So, I should not be able to scroll on the left and right sides of the window. And regarding vertical direction, scrolling should be similar to webpage, meaning vertical scrolling should be enabled when we go further down.

Earlier I used fixedBounds: new go.Rect(0, 0, windowWidth, windowHeight) and it was behaving as expected i.e, I cannot scroll at all in any direction.

Now for the change in requirement, when I replace windowHeight with +Infinity, its not behaving in the expected manner. I am able to scroll in all directions when I use +Infinity. I would like to know if its possible to make the canvas section behave like a webpage.

Thank you for the direct link regarding “stayInViewport” function. But for it to behave like a webpage, I am thinking to modify the conditions as ‘top left’ as (0,0) and ‘bottom right’ as (windowWidth, +Infinity) should do.

Any help on overriding DraggingTool.computeResize method is welcome.

Please correct me if I’m from anywhere.

I don’t think it makes sense to specify a “fixed” document bounds to have an infinite width or height. But we could be better about signaling an error, if you are using go-debug.js at least.

We’ll look into what needs to be done for your situation.

What do you think about this way of automatically increasing the document bounds when scrolling down, and automatic decrease of the document bounds when scrolling up from there?

"ViewportBoundsChanged": function(e) { // allow infinite scrolling downwards var oldvp = e.parameter; var newvp = e.diagram.viewportBounds; if (Math.abs(newvp.height - oldvp.height) < 1) { // only when scrolling var doc = e.diagram.documentBounds.copy(); var length = Math.max(0, newvp.height - e.diagram.scrollVerticalLineChange); // see if it's scrolled at or near a "page" from the bottom if (newvp.bottom > oldvp.bottom && Math.abs(doc.bottom - newvp.bottom) < length) { doc.height += length; e.diagram.fixedBounds = doc; } else if (newvp.bottom <= oldvp.bottom && Math.abs(doc.bottom - newvp.bottom) > length) { doc.height -= length; e.diagram.fixedBounds = doc; } } }
(I added this to the initialization of a Diagram via GraphObject.make.)

Regarding resizing within the viewport:

Add this helper function:

function limitInputToViewport(e) { var diagram = e.diagram; var vp = diagram.viewportBounds; var docpt = e.documentPoint.copy(); if (docpt.x < vp.x) docpt.x = vp.x; else if (docpt.x > vp.right) docpt.x = vp.right; if (docpt.y < vp.y) docpt.y = vp.y; else if (docpt.y > vp.bottom) docpt.y = vp.bottom; e.documentPoint = docpt; e.viewPoint = diagram.transformDocToView(docpt); }
This function limits an InputEvent to stay within the viewport.

Then you can override two ResizingTool methods:

[code] myDiagram.toolManager.resizingTool.doMouseMove = function() {
limitInputToViewport(this.diagram.lastInput);
go.ResizingTool.prototype.doMouseMove.call(this);
};

myDiagram.toolManager.resizingTool.doMouseUp = function() {
  limitInputToViewport(this.diagram.lastInput);
  go.ResizingTool.prototype.doMouseUp.call(this);
};[/code]

Now the user cannot drag a resize handle outside of the viewport.