dragComputation property

Point Function(Part, Point, Point)? get dragComputation

Gets or sets the function used to determine the location that this Part can be dragged to. The first argument is a reference to the Part being dragged, the second argument is a Point describing the proposed location, and the third argument is a snapped location, if one was determined during dragging. It should return a Point that is the proposed new location.

By default this function is null and the DraggingTool uses the snapped location, if one was determined and if DraggingTool#isGridSnapEnabled is true, or the proposed location (the second argument) if not snapping to a grid.

In either case the DraggingTool will limit the proposed new location by #minLocation and #maxLocation.

The function, if supplied, must not have any side-effects.

An example that limits moving a Node to the current viewport:

  function stayInViewport(part, pt, gridpt) {
    var diagram = part.diagram;
    if (diagram === null) return pt;
    // compute the area inside the viewport
    var v = diagram.viewportBounds.copy();
    v.subtractMargin(diagram.padding);
    // get the bounds of the part being dragged
    var bnd = part.actualBounds;
    var loc = part.location;
    // now limit the location appropriately
    var l = v.x + (loc.x - bnd.x);
    var r = v.right - (bnd.right - loc.x);
    var t = v.y + (loc.y - bnd.y);
    var b = v.bottom - (bnd.bottom - loc.y);
    if (l <= gridpt.x && gridpt.x <= r && t <= gridpt.y && gridpt.y <= b) return gridpt;
    var p = gridpt.copy();
    if (diagram.toolManager.draggingTool.isGridSnapEnabled) {
      // find a location that is inside V but also keeps the part's bounds within V
      var cw = diagram.grid.gridCellSize.width;
      if (cw > 0) {
        while (p.x > r) p.x -= cw;
        while (p.x < l) p.x += cw;
      }
      var ch = diagram.grid.gridCellSize.height;
      if (ch > 0) {
        while (p.y > b) p.y -= ch;
        while (p.y < t) p.y += ch;
      }
      return p;
    } else {
      p.x = Math.max(l, Math.min(p.x, r));
      p.y = Math.max(t, Math.min(p.y, b));
      return p;
    }
  }

Note that for this functionality you will also probably want to set Diagram#autoScrollRegion to be a zero margin.

  myDiagram.nodeTemplate =
    new go.Node(. . .,
      { dragComputation: stayInViewport },
      . . .
    )

Implementation

_i3.Point Function(
  _i3.Part,
  _i3.Point,
  _i3.Point,
)? get dragComputation => (
      _i3.Part p0,
      _i3.Point p1,
      _i3.Point p2,
    ) =>
        _i4.callMethod(
          _i4.getProperty(
            this,
            'dragComputation',
          ),
          r'call',
          [
            this,
            p0,
            p1,
            p2,
          ],
        );
set dragComputation (Point value(Part, Point, Point)?)

Implementation

set dragComputation(
    _i3.Point Function(
      _i3.Part,
      _i3.Point,
      _i3.Point,
    )? value) {
  _i4.setProperty(
    this,
    'dragComputation',
    value == null ? _i5.undefined : _i4.allowInterop(value),
  );
}