JointJS : How to restrict links per port to one?
Asked Answered
M

3

6

API doc for the JointJS library is here: http://www.jointjs.com/api I'm using DEVS plugin for Elements with ports.

I need to restrict number of connections from a port to a single one.

Once a link is made from a port, user shouldn't be able to start a connection from the same port unless the existing connection is removed.

Is it possible without code changes in the library itself?

I was not able to get a hook/entry point to implement this requirement even after looking into API doc and the code itself. Any help or pointers are appreciated.

PS:

  • unfortunately I'm not good at Backbone at the moment.
  • it was matter of setting magnet="passive" to the port in question, I guess. Just don't know how to do it. (graph is dynamic, not predefined links between elements)
Marcosmarcotte answered 30/5, 2014 at 9:12 Comment(0)
M
2

It was as simple as getting element from graph and setting certain attribute on it.

var source = graph.getCell(sourceId);
source.attr('.outPorts circle/magnet', 'passive')
Marcosmarcotte answered 30/5, 2014 at 10:2 Comment(0)
D
12

I've been struggling with this all day. Setting the magnets to passive was not a good enough solution for me. What I've finally ended up with after digging through the source is using the validateMagnet function of the paper object. I get the port from the magnet, and then get all the outbound links from the source model. If any of the links are using the same point I reject the validation. Here's the code:

validateMagnet: function(cellView, magnet) {
    // Prevent links from ports that already have a link
    var port = magnet.getAttribute('port');
    var links = graph.getConnectedLinks(cellView.model, { outbound: true });
    var portLinks = _.filter(links, function(o) {
        return o.get('source').port == port;
    });
    if(portLinks.length > 0) return false;
    // Note that this is the default behaviour. Just showing it here for reference.
    // Disable linking interaction for magnets marked as passive (see below `.inPorts circle`).
    return magnet.getAttribute('magnet') !== 'passive';
},
Dryfoos answered 13/1, 2016 at 22:22 Comment(1)
Hi @DanielWood , this code helps a lot. May i know to restrict inbound also to one. Thanks in advance!Brooks
M
2

It was as simple as getting element from graph and setting certain attribute on it.

var source = graph.getCell(sourceId);
source.attr('.outPorts circle/magnet', 'passive')
Marcosmarcotte answered 30/5, 2014 at 10:2 Comment(0)
A
0

To limit inbound and outbound ports to one connection each, check the existing connected links when validating the potential connection:

new dia.Paper({
    validateConnection: (cellViewS, magnetS, cellViewT, magnetT) => {
        return !Boolean([
            // Find existing outbound links from the source element.
            ...graph.getConnectedLinks(cellViewS.model, { outbound: true, inbound: false, })
                .filter(link => link.get('source').port === magnetS.getAttribute('port')),
            // Find existing inbound links to the target element.
            ...graph.getConnectedLinks(cellViewT.model, { outbound: false, inbound: true, }),
        ].length)
    },
})
Autolithography answered 10/2, 2023 at 20:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.