How to interactively create links in JointJS
Asked Answered
C

3

7

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 
    }
});
Crowbar answered 5/7, 2014 at 14:53 Comment(0)
E
10

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:

var r = new joint.shapes.basic.Rect({
    position: { x: 50, y: 50 },
    size: { width: 100, height: 40 },
    attrs: { text: { text: 'basic.Rect', magnet: true } }
});

This will make the element behave like a port.

Eventempered answered 7/7, 2014 at 8:17 Comment(3)
Fantastic! Maybe should be documented a little better. Now I have to find a way to prevent the creation of dangling links between a node and nothing.Crowbar
@Crowbar did you ever figure out how to prevent dangling links? (or how to pick them back up and drag onto an element - once it's disconnected, it just changes the shape :()Mckown
I've added magnet: true to every port but I still am unable to start drawing a link and resize cursor is on all the ports and elementsCarnet
D
3

To prevent the dangling links:

joint.dia.Paper({ linkPinning: false })
Dinnerware answered 26/5, 2017 at 20:10 Comment(1)
thank you. The documentation and examples are really way under the quality of the code and librarySacking
B
0

Here is a nice solution.

You can combine

linkView.startArrowheadMove('target');

and

evt.data.view.pointermove(evt, p.x, p.y);
Baguette answered 10/11, 2016 at 17:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.