Show and hide node info on mouseover in cytoscape
Asked Answered
C

2

8

I am working on a cytoscape.js graph in browser. I want to show some information of nodes (e.g. node label) as the mouse hovers over the nodes in a cytoscape graph. The following code is working for console.log() but I want to show the information in the browser:

cy.on('mouseover', 'node', function(evt){
    var node = evt.target;
    console.log( 'mouse on node' + node.data('label') );
});

Please help !

Capon answered 6/2, 2019 at 6:37 Comment(0)
N
11

Cytoscape.js has popper.js with tippy. I can give you a working exapmle for popper.js:

popper with tippy:

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: {
          id: "ab",
          source: "a",
          target: "b"
        }
      }]
    },
    layout: {
      name: "grid"
    }
  }));

  function makePopper(ele) {
    let ref = ele.popperRef(); // used only for positioning

    ele.tippy = tippy(ref, { // tippy options:
      content: () => {
        let content = document.createElement('div');

        content.innerHTML = ele.id();

        return content;
      },
      trigger: 'manual' // probably want manual mode
    });
  }

  cy.ready(function() {
    cy.elements().forEach(function(ele) {
      makePopper(ele);
    });
  });

  cy.elements().unbind('mouseover');
  cy.elements().bind('mouseover', (event) => event.target.tippy.show());

  cy.elements().unbind('mouseout');
  cy.elements().bind('mouseout', (event) => event.target.tippy.hide());

});
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;
}
<head>
  <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/[email protected]/dist/umd/popper.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/cytoscape-popper.min.js"></script>
  <script src="https://unpkg.com/[email protected]/umd/index.all.min.js"></script>
  <link rel="stylesheet" href="https://unpkg.com/[email protected]/index.css" />
</head>

<body>
  <div id="cy"></div>
</body>
Neoplasm answered 6/2, 2019 at 14:34 Comment(7)
Thanks a lot @Stefan T.Capon
It is worth mentioning that as of today, Qtip is no longer maintained, btw.Throughout
Hey there, would you mind sending me a demo for popper.js/tippy.js for this?Phippen
I changed the demo to popper.js/tippy.js :)Neoplasm
@StephanT. Much appreciated! Works very well, thanks for the time :)Phippen
Is there a way to allow the tooltip to follow the node on drag events?Slant
For a sticky tooltip use the sticky tippy.js implementation as demonstrated hereNeoplasm
C
4

Hi guys the Stephan's answer won't work using module based code like in React.js so I'm giving you an alternative without tippy

popper.css // popper style

.popper-div { // fill free to modify as you prefer
  position: relative;
  background-color: #333;
  color: #fff;
  border-radius: 4px;
  font-size: 14px;
  line-height: 1.4;
  outline: 0;
  padding: 5px 9px;
}

App.js

import cytoscape from "cytoscape";
import popper from "cytoscape-popper"; // you have to install it

import "./popper.css";

cytoscape.use(popper);

const cy = cytoscape({....});

cy.elements().unbind("mouseover");
cy.elements().bind("mouseover", (event) => {
  event.target.popperRefObj = event.target.popper({
    content: () => {
      let content = document.createElement("div");

      content.classList.add("popper-div");

      content.innerHTML = event.target.id();

      document.body.appendChild(content);
      return content;
    },
  });
});

cy.elements().unbind("mouseout");
cy.elements().bind("mouseout", (event) => {
  if (event.target.popper) {
    event.target.popperRefObj.state.elements.popper.remove();
    event.target.popperRefObj.destroy();
  }
});
Cherida answered 11/8, 2021 at 17:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.