How to make node avoid another node while dragging

is there a clever way to make node avoid another node that could be on the way when you drag it ?
I tried to make it work defining a dragComputation for node, I took example from grid patterns but I didnt find a good way to avoid other nodes with it.

Is there anything I should know about how to implement that?

Did you mean something like: Drag Unoccupied

Yes, exaclty like this. Thanks Walter.

@walter is there a chance that it is possible to make “NonRealtimeDragging” like style when user drag a node over node, and regular realtime dragging style when user moves node in a free space.

Yes it is possible. There are several designs that I can imagine. What results did you get when you tried?

I just tired to switch dragging tool while hitting occupaied space and switch it back.
Didnt work out, and it maked impression that this is a wrong idea.

You’ll have to merge the code together.

In NonRealtimeDragging _imagePart which holds the shadow node is set on computeEffectiveCollection which I think happens only on dragging start, and I think of something which will allow me to set/unset _imagePart during dragging a node.
WDYT walter? Am I heading towards correct direction?

What happens when you literally merge the code together in your app? Use both the dragComputation function and the NonRealtimeDraggingTool. Does that get you the effects that you want?

If I simply use dragComputation: avoidOccupied for my templates, and use draggingTool: goMake(NonRealtimeDraggingTool, { duration: 600 }) for diagram, that just makes dragging with shadow node all time, regardless if dragging hits occupied or not. But I would like to have shadow node effect only when user drags a node over another node

OK, forget using the NonRealtimeDraggingTool.
Instead, modify:

        if (isUnoccupied(r, node)) return gridpt;  // OK
        return loc;  // give up -- don't allow the node to be moved to the new location

to be something like:

        if (isUnoccupied(r, node)) {
           node.opacity = 1;
           node._safe = loc.copy();
        } else {
           node.opacity = 0.5;
        return gridpt;  // always allow drag over other nodes

But then at the end of the drag change the location of any node with a _safe Point to be that value.

By saying at the end of the drag you mean override “draggingTool.computeMove” ?

No, I meant in a “SelectionMoved” DiagramEvent listener or override of DraggingTool | GoJS API, depending on how you want to organize your code.

Cool, thanks Walter.

loc variable is changing all the way during the dragging. and if I drop the node over a node, loc.copy() which is being saved to _save is just the last location of the node. which is basicaly breaks the avoidOccupied idea.
How can I get the original node location before dragg start in this context?

Oops, maybe I got the two cases mixed up. In other words you want to save the last known good or safe location, not the location when the node being moved overlaps some other node. I have updated the code above. But I still haven’t tried it…

All good, Thanks walter for support, I managed to achive what I needed.

I have one more question @walter.
Is there a way to define that current dragged node is a new node for diagram (when I dragged a node from palette into diagram for ex)
I need to add escape condition in isUnoccupied, for some case when I add a new node to a diagram from palette
Thanks :)

During dragging? Note how the avoidNodeOverlap function already checks that by looking to see if the Node is in a Layer that is Layer.isTemporary.

A post was split to a new topic: Setting location of a group