onDrag & onDrop events

Hi,
I have a graph with groups and nodes (without groups).
I want when a group (or groups) dragged over another group or node, the opacity of the current dragged group/s will be changed, until the drop (if the drop will not collide with another element).

How do I achieve this behavior, please?

Regards,
Michael

There’s an extension that does something like that, but also explicitly doesn’t move the selection until the drop happens: Non-Realtime Dragging
Is this what you are looking for?

That sample doesn’t prevent a drop from happening if it would overlap some stationary part. That could be done in various manners. One way would be to implement a “SelectionMoved” DiagramEvent listener that looks to see if there are any overlaps in the dropped (selected) Parts. If there isn’t, great. If there are, then cancel the current tool, causing the parts to be moved back to where they had started from.

Thanks for your reply.

Finally I build a code for my need, this is the code:

 class CustomDraggingTool extends go.DraggingTool {
	static isDescendant(node1, node2) {
		while (node1 !== null) {
			if (node1 === node2) {
				return true;
			}
			node1 = node1.containingGroup;
		}
		return false;
	}

 // change the opacity of the elements which collide with the dragged elements
 doDragOver(pt, obj) {
 		super.doDragOver(pt, obj);
 		const { diagram } = this;
 		const draggedGroup = this.draggedParts.first().key;
		diagram.nodes.each((node) => {
			if (node !== draggedGroup && (draggedGroup instanceof go.Group || draggedGroup instanceof go.Node)) {
 				if (CustomDraggingTool.isDescendant(draggedGroup, node)) return;
 				if (draggedGroup instanceof go.Group && draggedGroup.findSubGraphParts().contains(node)) return; // Skip if node is a nested part of draggedGroup
 				if (draggedGroup.actualBounds.intersectsRect(node.actualBounds)) {
					node.opacity = 0.5;
				} else {
 					node.opacity = 1;
				}
			}
		});
	}
}
export default CustomDraggingTool;

Thanks.

By the way, the Part.isMemberOf predicate I think provides some of what your isDescendant implements. Except that if the two argument nodes are the same node, it wouldn’t return equal, so you’ll need to check that for yourself.
Part | GoJS API

I was looking for a built-in function for isDescendant! Thanks.
I have also added a fix for the edge case: The dragged element opacity does not start with 1

So this is the updated code:

class CustomDraggingTool extends go.DraggingTool {
	// change the opacity of the elements which collide with the dragged elements
	doDragOver(pt, obj) {
		super.doDragOver(pt, obj);
		const { diagram } = this;
		const draggedGroup = this.draggedParts.first().key;
		if (draggedGroup.opacity !== 1) {
			draggedGroup.opacity = 1;
		}
		diagram.nodes.each((node) => {
			if (node !== draggedGroup && (draggedGroup instanceof go.Group || draggedGroup instanceof go.Node)) {
				if (draggedGroup.isMemberOf(node)) return; // Skip if draggedGroup is a descendant of node
				if (draggedGroup instanceof go.Group && draggedGroup.findSubGraphParts().contains(node)) return; // Skip if node is a nested part of draggedGroup
				if (draggedGroup.actualBounds.intersectsRect(node.actualBounds)) {
					node.opacity = 0.5;
				} else {
					node.opacity = 1;
				}
			}
		});
	}
}

export default CustomDraggingTool;

Because the Group class inherits from the Node class, you don’t need to check for both. Maybe you just want to check that draggedGroup is not an instance of Link?

Yes, you’re right, not an instance of Link is the more correct code.