Zooming selected nodes

Can we do zoom in zoom out for selected nodes only ?

Zooming means changing the Diagram.scale, which applies to all objects in the diagram.

But you could certainly override ToolManager | GoJS API to change the GraphObject.scale of selected Nodes only.

doMouseWheel doesn’t get called if i do zoom from touch screen . is there any other event?

You could override ToolManager.standardPinchZoomStart and standardPinchZoomMove. But you’ll need to reimplement the math to figure out how much to rescale the selected nodes.

DO we have any sample available to implement the math to figure out how much to rescale the selected nodes.

OK, here’s a sketch of the code you’ll need. Pardon any errors on my part – I haven’t had time to try this. You’ll need to debug this and fix it.

function CustomToolManager() {
    go.ToolManager.call(this);
}
go.Diagram.inherit(CustomToolManager, go.ToolManager);

CustomToolManager.prototype.standardPinchZoomStart = function() {
  var diagram = this.diagram;
  if (diagram === null) return;
  var e = diagram.lastInput;

  var first = e.getMultiTouchViewPoint(0);
  var second = e.getMultiTouchViewPoint(1);
  if (!first.isReal() || !second.isReal()) {
    return;
  }

  // event.isMultiTouch
  // call doCancel to stop the rest of typical toolManager.domousedown/domousemove behavior
  this.doCancel();

  if (diagram.getInputOption('hasGestureZoom')) {
    diagram._origScale = diagram.scale;
    var x = second.x - first.x;
    var y = second.y - first.y;
    var dist = Math.sqrt((x * x) + (y * y));
    diagram._startDist = dist;
    e.bubbles = false;
  }
};

CustomToolManager.prototype.standardPinchZoomMove = function() {
  var diagram = this.diagram;
  if (diagram === null) return;
  var e = diagram.lastInput;

  var first = e.getMultiTouchViewPoint(0);
  var second = e.getMultiTouchViewPoint(1);
  if (!first.isReal() || !second.isReal()) {
    return;
  }

  // event.isMultiTouch
  // call doCancel to stop the rest of typical toolManager.domousedown/domousemove behavior
  this.doCancel();

  if (diagram.getInputOption('hasGestureZoom')) {
    var x = second.x - first.x;
    var y = second.y - first.y;
    var dist = Math.sqrt((x * x) + (y * y));
    var scale = dist / diagram._startDist;
    var newscale = diagram._origScale * scale;
    diagram.startTransaction();
    diagram.selection.each(function(part) {
        if (part instanceof go.Node) {
            part.scale = newscale;
        }
    });
    diagram.commitTransaction("rescaled selected nodes");
    e.bubbles = false;
  }
};

// install with:
myDiagram.toolManager = myDiagram.defaultTool = new CustomToolManager();

getmultitouchviewpoint function doesn’t exist in InputEvent of Diagram.

It’s undocumented, but it’s there on InputEvent.

I suppose you could go directly to the TouchEvents or PointerEvents and get the point and convert to viewport coordinates, but calling InputEvent.getMultiTouchViewPoint is easier.

It is throwing error at getmultitouchviewpoint. i am not able to see the function at the runtime as well.

Are you using version 1.7?

i am using 1.7.1

I just looked in the 1.7.1 go.js library file, and when I searched for “getMultiTouchViewPoint”, I found the method on InputEvent.

may be go.d.ts is not updated since i am coding in typescript so i am unable to find the function

Well, it is undocumented, so it is not surprising that it is not in go.d.ts.

moreover if i try to use it through external javascript – " this.myDiagram.toolManager = this.myDiagram.defaultTool = new CustomToolManager();" line gives me error — Cannot share ToolManagers between Diagrams: ToolManager Tool

if i directly code in typescript and write the implementation of methods mentioned above . i get the error

Ah, pardon me – I used the API in the wrong manner too.

Try this:

    // Override normal pinch zoom to zoom the selected node instead of the Diagram.

    var originalScale = 1;
    var startDistance = 0; // how far apart the touches are at the start
    var isPinching = false;
    // Initiates pinch-zooming on multi-touch devices.
    myDiagram.toolManager.standardPinchZoomStart = function() {
      var diagram = this.diagram;
      if (diagram === null) return;
      var e = diagram.lastInput;

      var first = e.getMultiTouchViewPoint(0, new go.Point());
      var second = e.getMultiTouchViewPoint(1, new go.Point());

      // event.isMultiTouch
      // call doCancel to stop the rest of typical toolManager.domousedown/domousemove behavior
      this.doCancel();

      var node = diagram.selection.first();
      if (node === null) return;

      originalScale = node.scale;
      var x = second.x - first.x;
      var y = second.y - first.y;
      var dist = Math.sqrt((x * x) + (y * y));
      startDistance = dist;
      e.bubbles = false;
      isPinching = true;
      myDiagram.startTransaction('zoom node');
    };

    // Continues pinch-zooming (started by {@link #standardPinchZoomStart} on multi-touch devices.
    myDiagram.toolManager.standardPinchZoomMove = function() {
      var diagram = this.diagram;
      if (diagram === null) return;
      var e = diagram.lastInput;

      // event.isMultiTouch
      // call doCancel to stop the rest of typical toolManager.domousedown/domousemove behavior
      this.doCancel();

      var first = e.getMultiTouchViewPoint(0, new go.Point());
      var second = e.getMultiTouchViewPoint(1, new go.Point());

      var x = second.x - first.x;
      var y = second.y - first.y;
      var dist = Math.sqrt((x * x) + (y * y));
      var scale = dist / startDistance;
      var oldskip = myDiagram.skipsUndoManager;
      var node = diagram.selection.first();
      if (node !== null) node.scale = originalScale * scale;
      e.bubbles = false;
    };

    myDiagram.toolManager.doMouseUp = function() {
      if (isPinching) {
        myDiagram.commitTransaction('zoom node');
        isPinching = false;
      }
      go.ToolManager.prototype.doMouseUp.call(this);
    }

This code only rescales one selected node, but you can rescale all selected nodes instead.

thank you walter. this piece of code works :)

but i believe if these events are documented, it will be easy to understand what they do instead of copy paste piece of code.

in DoMouseWheel , how can we find out if we are zooming out ?