Zoom Out and Zoom In a TableLayout diagram relative to mouse click position

I have a table layout diagram with some nodes placed inside the cells.

There are two options “Zoom Out” and “Zoom In” , that can be selected from UI.

When “Zoom Out” is selected and mouse is clicked on a particular position, I want to zoom out that portion of the diagram.

Similarly, When “Zoom In” is selected and mouse is clicked on a particular position, I want to zoom in the diagram.

I have tried zoom using myDiagram.commandHandler.increaseZoom() and myDiagram.commandHandler.decreaseZoom().

It is noticed that the zoom happens relative to center.

So if the diagram is big, while zoom out, scroll bar comes and the position where I clicked goes out of my view. I want the zoom to happen relative to my mouse click position.

Please help to achieve this.

What happens when the user uses the mouse to click on the “Zoom Out” or “Zoom In” buttons? Is your app supposed to remember where the user last clicked within the diagram? What if the user clicks somewhere and then manually scrolls to some other place that is of greater interest, and then zooms?

I assume you already know about Diagram.scrolltoRect. You could also call Diagram.zoomToRect if you want to implement your own zoom commands.

If the user selects a Node and you want to make sure that Node is in the viewport, you could always call CommandHandler.scrollToPart.

Thanks Walter. Please help me with some more details.

My requirement is as follows

There are two magnifier glasses corresponding to “Zoom Out” and “Zoom In” in our web application toolbar.
Also there is a Go.JS table layout diagram with some nodes placed inside the cells.

User selects “Zoom Out” and then mouse is clicked on a particular position. For example in the 50th cell in 50th row. On each mouse click, the expected behaviour is to zoom out the diagram in such a way that the user should see the contents of 50 th cell in 50th row in his vision. It should not go out of the visible canvas area which forces the user to scroll and see the contents.

This web application should work properly in mobile devices also. Means, when the same zoom out operation is done from a mobile device, it will be a tap operation instead of mouse click.

Similarly, When “Zoom In” is selected and mouse is clicked on a particular position, it should go back to previous state.

Based on this, I would like to know which option is more suitable for this requirement? Diagram.scrolltoRect or Diagram.zoomToRect?

I assume the better option is to zoom using myDiagram.commandHandler.increaseZoom() and myDiagram.commandHandler.decreaseZoom(), and then modify the position to show a given Rect of the diagram in user’s vision by calling Diagram.scrolltoRect.

In this case, I doubt my coordinate system may change on each zoom operation. If so, do I need to calculate the coordinates on each mouse click to proceed with using Diagram.scrolltoRect.

Could you please help me to proceed.

Ah, OK, that sort of scenario makes sense. You have several options.

Since you talk about being in a “zoom-by-click” mode, one possibility is to implement a custom Tool where each click zooms in or out at that document point. When the user chooses such a mode, you set Diagram.currentTool to be an instance of your custom tool. Each click could set the Diagram.scale appropriately and call Diagram.scrollToRect. You’ll note that changing the diagram scale is normally limited to Diagram.minScale and Diagram.maxScale.

The advantage of using a separate tool is that when in that “mode” you can completely control all possible operations that might happen due to whatever input events might come in.

There are alternative possibilities too.

Thanks Walter for your suggestion.

I have newly started working with Go.JS and I feel your suggestion to implement a custom Tool to manage zoom is difficult to implement.

Do you have any samples available which will guide me to do this.

Please help.

Thanks in advance.

Here you go, zooming in only:

  function ZoomClickingTool() {
    go.Tool.call(this);
  }
  go.Diagram.inherit(ZoomClickingTool, go.Tool);

  ZoomClickingTool.prototype.doMouseUp = function() {
    this.diagram.commandHandler.increaseZoom();
    this.diagram.scrollToRect(new go.Rect(this.diagram.lastInput.documentPoint, new go.Size(1, 1)));
  };

Your mode-switching button can then do:

    myDiagram.currentTool = new ZoomClickingTool();

Switch back to normal mode via:

    myDiagram.currentTool = myDiagram.defaultTool;

Note that the only way to “escape” from this mode (without your code resetting the Diagram.currentTool) is for the user to hit the ESCape key.

There are lots of example custom tools throughout the sample apps.

Thanks Walter. I will try this solution.

I tried this solution,

I am getting the following behavior

1.The zoom-in/out happend based on the TopLeft corner(since I set daigram.contentAlignmnet= TopLeft)
2.The clicked point is getting shifted towards bottom-right corner and moves out of visible region
3.If click on the extreme end of the diagram, then clicked portion get shifted to visible region

I have tried by passing a Rect (whose center point will be the clicked point) to the scrollToRect() API.

var newPoint = new go.Point(diagram.lastInput.documentPoint.x - 10, diagram.lastInput.documentPoint.y - 10);
diagram.scrollToRect(new go.Rect(newPoint, new go.Size(20, 20)));

In this scenario, the clicked point gets shifted to visible region when it is a little(around 10px) away from extreme end of the diagram.
However a smooth transition to visible region is not happening.

I would like to know what additional steps need to be done, so that zoomed area is always in the vision.
Also whenever zoomed area goes out of vision, a smooth transition should happen to shift that portion to the vision.

Setting Diagram.contentAlignment results in behavior that takes precedence over setting Diagram.position, including calls to Diagram.scrollToRect.

I removed the contentAlignment of the diagram

Now I get a little bit different behavior.

I am uploading 3 images to describe the current behavior.
First image shows the initial position before staring zoom out
Second image shows the position of zoomed area after some zoom out operations
Third image shows the zoomed area get hiding after some more zoom out operations

This the code I am used to get the zoom

function ZoomClickingTool() {
	go.Tool.call(this);
    }
    go.Diagram.inherit(ZoomClickingTool, go.Tool);

    ZoomClickingTool.prototype.doMouseUp = function() {
	myDiagram.commandHandler.increaseZoom();
    	var newPoint = new go.Point(myDiagram.lastInput.documentPoint.x - 100, myDiagram.lastInput.documentPoint.y - 100);
    	myDiagram.scrollToRect(new go.Rect(newPoint, new go.Size(200, 200)));
}

What are the things to do additionally to avoid the hiding of zoomed area?