Multiple node selection in vis.js
Asked Answered
H

4

6

I'm playing with vis.js because I like its Network Visualization module. I'd like to know, as I can't find it in documentation, if it's possibile to select multiple nodes.

Cheers,

Riccardo

Henryk answered 18/9, 2014 at 6:53 Comment(0)
S
4

Search for "selectable" property in documentation at http://visjs.org/docs/network/

If true, nodes in the network can be selected by clicking them. Long press can be used to select multiple nodes.

Swill answered 4/12, 2014 at 7:42 Comment(0)
P
12

Update! the link for the documentation is http://visjs.org/docs/network/interaction.html

set the multiselect property to true.

add this section to your network option object.

interaction: { multiselect: true}
Pelagi answered 24/11, 2016 at 15:0 Comment(2)
Is there any way to use simple click instead of long click for multiple selection ?Webfooted
Hi, you can use a hack. bind to the events selectNode and deselectNode.with those you could know what are the selected nodes you want. than you can just use the method selectNodes.Pelagi
S
4

Search for "selectable" property in documentation at http://visjs.org/docs/network/

If true, nodes in the network can be selected by clicking them. Long press can be used to select multiple nodes.

Swill answered 4/12, 2014 at 7:42 Comment(0)
S
2

If you are looking for a rectangle to select your nodes, just look at this thread on visjs-network github : https://github.com/almende/vis/issues/3594

Full demo code :

const nodes = new vis.DataSet([
    { id: 1, label: 'Node 1' },
    { id: 2, label: 'Node 2' },
    { id: 3, label: 'Node 3' },
    { id: 4, label: 'Node 4' },
    { id: 5, label: 'Node 5' }
]);

const edges = new vis.DataSet([
    { from: 1, to: 3 },
    { from: 1, to: 2 },
    { from: 2, to: 4 },
    { from: 2, to: 5 }
]);

const options = {
    layout: { randomSeed: 2 },
    interaction:{
    hover: true,
        multiselect: true
    }
};

// Everything is in there
const makeMeMultiSelect = (container, network, nodes) => {
    const NO_CLICK = 0;
    const RIGHT_CLICK = 3;

    // Disable default right-click dropdown menu
    container[0].oncontextmenu = () => false;

    // State

    let drag = false, DOMRect = {};

    // Selector

    const canvasify = (DOMx, DOMy) => {
        const { x, y } = network.DOMtoCanvas({ x: DOMx, y: DOMy });
        return [x, y];
    };

    const correctRange = (start, end) =>
        start < end ? [start, end] : [end, start];

    const selectFromDOMRect = () => {
        const [sX, sY] = canvasify(DOMRect.startX, DOMRect.startY);
        const [eX, eY] = canvasify(DOMRect.endX, DOMRect.endY);
        const [startX, endX] = correctRange(sX, eX);
        const [startY, endY] = correctRange(sY, eY);

        network.selectNodes(nodes.get().reduce(
            (selected, { id }) => {
                const { x, y } = network.getPositions(id)[id];
                return (startX <= x && x <= endX && startY <= y && y <= endY) ?
                    selected.concat(id) : selected;
            }, []
        ));
    }

    // Listeners

    container.on("mousedown", function({ which, pageX, pageY }) {
        // When mousedown, save the initial rectangle state
        if(which === RIGHT_CLICK) {
            Object.assign(DOMRect, {
                startX: pageX - this.offsetLeft,
                startY: pageY - this.offsetTop,
                endX: pageX - this.offsetLeft,
                endY: pageY - this.offsetTop
            });
            drag = true;
        }
    });

    container.on("mousemove", function({ which, pageX, pageY }) {
        // Make selection rectangle disappear when accidently mouseupped outside 'container'
        if(which === NO_CLICK && drag) {
            drag = false;
            network.redraw();
        }
        // When mousemove, update the rectangle state
        else if(drag) {
            Object.assign(DOMRect, {
                endX: pageX - this.offsetLeft,
                endY: pageY - this.offsetTop
            });
            network.redraw();
        }
    });

    container.on("mouseup", function({ which }) {
        // When mouseup, select the nodes in the rectangle
        if(which === RIGHT_CLICK) {
            drag = false;
            network.redraw();
            selectFromDOMRect();
        }
    });

    // Drawer

    network.on('afterDrawing', ctx => {
        if(drag) {
            const [startX, startY] = canvasify(DOMRect.startX, DOMRect.startY);
            const [endX, endY] = canvasify(DOMRect.endX, DOMRect.endY);

            ctx.setLineDash([5]);
            ctx.strokeStyle = 'rgba(78, 146, 237, 0.75)';
            ctx.strokeRect(startX, startY, endX - startX, endY - startY);
            ctx.setLineDash([]);
            ctx.fillStyle = 'rgba(151, 194, 252, 0.45)';
            ctx.fillRect(startX, startY, endX - startX, endY - startY);
        }
    });
}; // end makeMeMultiSelect

$(document).ready(() => {
    const container = $("#network");
    const network = new vis.Network(container[0], { nodes, edges }, options);
    makeMeMultiSelect(container, network, nodes);
});
Scapular answered 30/4, 2019 at 9:46 Comment(0)
H
1

I've just discovered that in vis.js you can select multiple nodes long pressing them.

Henryk answered 23/9, 2014 at 7:0 Comment(2)
Since some time you can use ctrl+click and shift+click too for multi select. EDIT: sorry, this only holds for the Timeline, is not yet supported by Network.Coahuila
long click and ctrl+click works in Network too, but only if you enable multiselect..Declarant

© 2022 - 2024 — McMap. All rights reserved.