I have created a GoJS diagram that allows dragging nodes from a side palette and dropping them onto routing links connecting other nodes. When a node is dropped over a routing link, it is inserted between the existing nodes that were previously connected by the link.
In the current implementation of my GoJS diagram, the dragged node is inserted between the existing nodes only when the mouse pointer is over the link and I drop the node. However, I would like to modify this behavior so that the dragged node is dropped and inserted between the existing nodes when the dragged node itself is directly over the link, rather than relying on the mouse pointer’s position.
In the below provided image, it is observed that when the dragged node is directly positioned over the link, dropping the node does not result in its insertion between the previously connected nodes. This behavior needs to be modified so that when the node is dropped while its position is directly over the link, it will be added in between the previously connected nodes as intended.
In addition to having the mouseDrop on the link, use the Diagram.mouseDrop as well, or perhaps ExternalObjectsDropped if you only want to do this on palette drops.
For the given selection, see if it intersects any links. If it does, use that link as the dropOntoLink link.
Except side palette nodes I am using some custom HTML nodes also, how can I do the same operation on custom HTML nodes ? Also I want to highlight the routing link over which the dragged node is hovered.
When using the following code to drop an HTML element onto the diagram, the dragged element is inserted between the previously linked nodes if the mouse pointer is over a link during the drop.
myDiagram.div.addEventListener("drop", event => {
console.log("drop event")
console.log(event)
event.preventDefault();
// Dragging onto a Diagram
if (div === myDiagram.div) {
const can = event.target;
const pixelratio = myDiagram.computePixelRatio();
const key = event.dataTransfer.getData("text/plain");
const imageSrc = getImageSrcByKey(key);
const nodeName = getNameByKey(key)
const newNodeData = {
key: getUniqueKey(),
img: imageSrc,
name: nodeName,
// loc: go.Point.stringify(point) // Set the location of the new node
};
// If the target is not the canvas, we may have trouble, so just quit:
if (!(can instanceof HTMLCanvasElement)) return;
const bbox = can.getBoundingClientRect();
let bbw = bbox.width;
console.log("Box width" + bbw)
if (bbw === 0) bbw = 0.001;
let bbh = bbox.height;
console.log("Box height" + bbh)
if (bbh === 0) bbh = 0.001;
const mx = event.clientX - bbox.left * ((can.width / pixelratio) / bbw);
const my = event.clientY - bbox.top * ((can.height / pixelratio) / bbh);
const point = myDiagram.transformViewToDoc(new go.Point(mx, my));
// Find the link at the drop point
// const link = myDiagram.findPartAt(point);
const link = myDiagram.findPartAt(myDiagram.lastInput.documentPoint);
console.log("html link")
console.log(link)
if (link instanceof go.Link) {
// Create a new node with the dropped image
myDiagram.startTransaction("addNode");
myDiagram.model.addNodeData(newNodeData);
// Add a link from the dropped link's fromNode to the new node
myDiagram.model.addLinkData({
from: link.fromNode.key,
to: newNodeData.key
});
// Add a link from the new node to the dropped link's toNode
myDiagram.model.addLinkData({
from: newNodeData.key,
to: link.toNode.key
});
myDiagram.commitTransaction("addNode");
// Remove the dropped link
myDiagram.remove(link);
}
else {
myDiagram.model.addNodeData(newNodeData);
}
}
});
How can I retrieve the link data when the dragged node is dropped directly over the link, instead of getting it when the mouse pointer is over the link?
You have a lot of choices deciding which link to splice into. Many of the choices are quite reasonable, but you must decide which policy is appropriate for your app.
You could call Diagram.findPartsIn, Diagram | GoJS API using the dropped node’s actualBounds.
Or you could call Diagram.findPartsNear, Diagram | GoJS API using the mouse point, InputEvent.documentPoint, or else using the center of the node’s bounds.
If the user can drop more than one node at a time, you have even more choices to make.
Either way, you will have a collection that will have zero or more Links in them.
You might want to call Link.findClosestSegment and then Point.distanceLineSegmentSquared to decide which link is closest to either the center of the node or to the mouse point. If there is no such link, you will need to decide if you need to do anything extra.