I want to interactively add links to my JointJS based graph.
My idea is to create a small temporary node on pointerdown
with a link from the original node to this temporary node, drag it on top of another node and on pointerup
create the real link removing the temporary link and node.
Unfortunately I don't know how to convince the pointer to move the temporary element and not the node on which the pointerdown
event happened. Any idea?
Thanks!
var tmp_obj;
paper.on('cell:pointerdown', function(cellView, evt, x, y) {
if(evt.button == 1) {
// Freeze the selected node so it does not move
paper.findViewByModel(cellView.model).options.interactive = false;
// Create a small temporary node on top of the selected node
tmp_obj = new joint.shapes.basic.Rect({
position: { x: x, y: y },
size: { width: 5, height: 5 }
}
// Create the link between the original node and the small temporary node
// And now?
}
}
paper.on('cell:pointerup', function(cellView, evt, x, y) {
if(evt.button == 1) {
// Unfreeze the origin node
paper.findViewByModel(cellView.model).options.interactive = true;
// Delete the temporary object (and temporary link)
tmp_obj.remove()
// Find the first element below that is not a link nor the dragged element itself.
var elementBelow = graph.get('cells').find(function(cell) {
if (cell instanceof joint.dia.Link) return false; // Not interested in links.
if (cell.id === cellView.model.id) return false; // The same element as the dropped one.
if (cell.getBBox().containsPoint(g.point(x, y))) {
return true;
}
return false;
});
// create the link from cellView to elementBelow
}
});
Maybe you can use the magnet feature of JointJS? If you set
magnet: true
on an SVG subelement of a JointJS element, that element becomes active and will allow the user to create a link starting from that element. For example:This will make the element behave like a port.
Here is a nice solution.
You can combine
and
To prevent the dangling links: