Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

vis.js network -- fixed position for tooltip/popup

How does one get a "fixed" position (like for example the center of the node/edge) for tooltip/popup in vis.js network using javascript?

Right now, the tooltips move as the mouse cursor is moving and therefore is not possible to copy the text which is in the tooltip! The tooltip should be "fix" and not move in order to allow the user to "catch it" using the mouse and copy (and paste it lated) that text which is inside it.

Here is the standard Javascript code where by default the tooltip/popup is "running away" from the mouse.

<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/vis/4.2.0/vis.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/vis/4.2.0/vis.min.css" rel="stylesheet" type="text/css" />

...
  <style type="text/css">
    #mynetwork {
      position:relative;
      width: 600px;
      height: 400px;
      border: 1px solid lightgray;
    }
<script type="text/javascript">
// create an array with nodes
var nodes = new vis.DataSet([
{id: 1, label: 'Node 1', title:'popup'},
{id: 2, label: 'Node 2', title:'popup'},
{id: 3, label: 'Node 3', title:'popup'},
{id: 4, label: 'Node 4', title:'popup'},
{id: 5, label: 'Node 5', title:'popup'}
]);

// create an array with edges
var edges = new vis.DataSet([
{from: 1, to: 3, title:'popup'},
{from: 1, to: 2, title:'popup'},
{from: 2, to: 4, title:'popup'},
{from: 2, to: 5, title:'popup'},
{from: 3, to: 3, title:'popup'}
]);

// create a network
var container = document.getElementById('mynetwork');
var data = {
nodes: nodes,
edges: edges
};
var options = {};
var network = new vis.Network(container, data, options);
</script>
like image 742
durila Avatar asked Nov 07 '22 12:11

durila


1 Answers

I agree with Termin, use the click event and paint a div over the canvas.

Finding the click position was the hard part for me. Vis.js does a great job of giving the x,y within the canvas, but you need the canvas position in the DOM to make it all work. jQuery is great at position on the page, so I used that to find the position of the canvas and locate the div.

network.on('click', function (properties) {
        var nodeID = properties.nodes[0];
        if (nodeID) {

            var sNodeLabel = this.body.nodes[nodeID].options.label
            var sToolTip = this.body.nodes[nodeID].options.title;

            //use JQUERY to see where the canvas is on the page.
            var canvasPosition = $('.vis-network').position();

            //the properties give x & y relative to the edge of the canvas, not to the whole document.
            var clickX = properties.pointer.DOM.x + canvasPosition.top;
            var clickY = properties.pointer.DOM.y + canvasPosition.left;

        //make sure we have a valid div, either clear it or generate one.
            if ($('#cellBatchAttrPopUp').length) {
                $('div#cellBatchAttrPopUp').empty();
            }
            else {
                $('<div id="cellBatchAttrPopUp"></div>').click(function () {
            //clicking the popup hides it again.
                    $(this).empty().hide();
                }).css('position','absolute').appendTo("body");
            }

            // put the div over the node, display the tooltip and show it.
            $('div#cellBatchAttrPopUp').append(sNodeLabel)
                       .append('<br/>')
                                       .append(sToolTip)
                           .css('top', clickY).css('left', clickX)
                           .show();

        }
    });

CSS to make the popup look nice, really position: absolute; is the only thing essential here.

div#cellBatchAttrPopUp {
    display: none;
    position: absolute;
    z-index: 2000;
    padding: 4px 8px;
    color: #333;
    white-space: nowrap;
    -moz-border-radius: 5px;
    -webkit-border-radius: 5px;
    border-radius: 5px;
    -moz-box-shadow: 0px 0px 4px #222;
    -webkit-box-shadow: 0px 0px 4px #222;
    box-shadow: 0px 0px 4px #222;
    background-image: -moz-linear-gradient(top, #eeeeee, #cccccc);
    background-image: -webkit-gradient(linear,left top,left bottom,color-stop(0, #eeeeee),color-stop(1, #cccccc));
    background-image: -webkit-linear-gradient(top, #eeeeee, #cccccc);
    background-image: -moz-linear-gradient(top, #eeeeee, #cccccc);
    background-image: -ms-linear-gradient(top, #eeeeee, #cccccc);
    background-image: -o-linear-gradient(top, #eeeeee, #cccccc);
}
like image 77
mike Avatar answered Nov 14 '22 21:11

mike