cytoscape.jsqtip2

How to set QTip to always show tooltips in Cytoscape.js


I'm looking for a way of getting QTip to concurrently display tooltips for each node in a Cytoscape.js graph, such that they are always displayed and anchored to the nodes in the graph without the user having to click or mouseover the node.

I got close with the code below:

$(document).ready(function(){
            cy.nodes().qtip({
                content: function(){ return 'Station: ' + this.id() +
                                       '</br> Next Train: ' + this.data('nextTrain') +
                                       '</br> Connections: ' + this.degree();
                        },
                hide: false,
                show: {
                    when: false,
                    ready: true
                 }
            })
        })

The above code displays tooltips on $(document).ready, but they are all located at one node in the Cytoscape graph and they disappear when I zoom in or pan at all.

The goal is to have tooltips anchored to each node in my graph such that when I zoom in and pan around they remain fixed to that node. I'm not sure if there is an easier way to do this just using Cytoscape (i.e., multi-feature labelling).

I'm using Qtip2, jQuery-2.0.3 and the most recent release of cytoscape.js

Any help is much appreciated.


Solution

  • EDIT: If you want to create these elements automatically, use a function and a loop to iterate over cy.nodes():

    var makeTippy = function (nodeTemp, node) {
        return tippy(node.popperRef(), {
            html: (function () {
                let div = document.createElement('div');
                // do things in div
                return div;
            })(),
            trigger: 'manual',
            arrow: true,
            placement: 'right',
            hideOnClick: false,
            multiple: true,
            sticky: true
        }).tooltips[0];
    };
    var nodes = cy.nodes();
    for (var i = 0; i < nodes.length; i++) {
        var tippy = makeTippy(nodes[i]);
        tippy.show();
    }
    

    If you want a sticky qTip, I would instead recommend the cytoscape extension for popper.js and specificly the tippy version (sticky divs):

    document.addEventListener('DOMContentLoaded', function() {
      var cy = window.cy = cytoscape({
        container: document.getElementById('cy'),
        style: [{
            selector: 'node',
            style: {
              'content': 'data(id)'
            }
          },
          {
            selector: 'edge',
            style: {
              'curve-style': 'bezier',
              'target-arrow-shape': 'triangle'
            }
          }
        ],
        elements: {
          nodes: [{
              data: {
                id: 'a'
              }
            },
            {
              data: {
                id: 'b'
              }
            }
          ],
          edges: [{
            data: {
              source: 'a',
              target: 'b'
            }
          }]
        },
        layout: {
          name: 'grid'
        }
      });
      var a = cy.getElementById('a');
      var b = cy.getElementById('b');
      var makeTippy = function(node, text) {
        return tippy(node.popperRef(), {
          html: (function() {
            var div = document.createElement('div');
            div.innerHTML = text;
            return div;
          })(),
          trigger: 'manual',
          arrow: true,
          placement: 'bottom',
          hideOnClick: false,
          multiple: true,
          sticky: true
        }).tooltips[0];
      };
      var tippyA = makeTippy(a, 'foo');
      tippyA.show();
      var tippyB = makeTippy(b, 'bar');
      tippyB.show();
    });
    body {
      font-family: helvetica neue, helvetica, liberation sans, arial, sans-serif;
      font-size: 14px
    }
    
    #cy {
      position: absolute;
      left: 0;
      top: 0;
      bottom: 0;
      right: 0;
      z-index: 1;
    }
    
    h1 {
      opacity: 0.5;
      font-size: 1em;
      font-weight: bold;
    }
    
    
    /* makes sticky faster; disable if you want animated tippies */
    
    .tippy-popper {
      transition: none !important;
    }
    <!DOCTYPE>
    <html>
    
    <head>
      <title>Tippy > qTip</title>
      <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1">
      <script src="https://unpkg.com/cytoscape/dist/cytoscape.min.js"></script>
      <script src="https://unpkg.com/popper.js"></script>
      <script src="cytoscape-popper.js"></script>
      <script src="https://unpkg.com/tippy.js@2.0.9/dist/tippy.all.js"></script>
      <link rel="stylesheet" href="https://unpkg.com/tippy.js@2.0.9/dist/tippy.css" />
      <script src="https://cdn.jsdelivr.net/npm/cytoscape-popper@1.0.2/cytoscape-popper.js"></script>
    </head>
    
    <body>
      <h1>cytoscape-popper tippy demo</h1>
      <div id="cy"></div>
    </body>
    
    </html>

    I think popper is just easier to handle when having the divs 'stick around'