web-dev-qa-db-fra.com

D3.js: Positionnez les info-bulles en utilisant la position de l'élément, pas la position de la souris?

J'utilise D3 pour dessiner un graphe de dispersion. J'aimerais afficher des info-bulles lorsque l'utilisateur passe la souris sur chaque cercle. 

Mon problème est que je peux ajouter des info-bulles, mais elles sont positionnées à l'aide de l'événement de souris d3.event.pageX et d3.event.pageY, de sorte qu'elles ne sont pas positionnées de manière uniforme sur chaque cercle. 

Certains sont légèrement à gauche du cercle, d'autres à droite - cela dépend de la manière dont la souris entre dans le cercle. 

Ceci est mon code: 

circles
  .on("mouseover", function(d) {         
    tooltip.html(d)  
      .style("left", (d3.event.pageX) + "px")     
      .style("top", (d3.event.pageY - 28) + "px");    
  })                  
  .on("mouseout", function(d) {       
    tooltip.transition().duration(500).style("opacity", 0);   
  });

Et est un JSFiddle montrant le problème: http://jsfiddle.net/WLYUY/5/

Est-il possible d'utiliser le centre du cercle lui-même comme position pour orienter l'info-bulle, et non la position de la souris?

36
Richard

Dans votre cas particulier, vous pouvez simplement utiliser d pour positionner l'info-bulle, c'est-à-dire.

tooltip.html(d)  
  .style("left", d + "px")     
  .style("top", d + "px");

Pour rendre ceci un peu plus général, vous pouvez sélectionner l’élément survolé et obtenir ses coordonnées pour positionner l’info-bulle, c-à-d.

tooltip.html(d)  
  .style("left", d3.select(this).attr("cx") + "px")     
  .style("top", d3.select(this).attr("cy") + "px");
28
Lars Kotthoff

Vous avez trouvé quelque chose ici qui pourrait résoudre votre problème même si <body> et <svg> ont un positionnement différent. Cela suppose que vous avez défini la position absolute pour votre info-bulle.

.on("mouseover", function(d) {
    var matrix = this.getScreenCTM()
        .translate(+ this.getAttribute("cx"), + this.getAttribute("cy"));
    tooltip.html(d)
        .style("left", (window.pageXOffset + matrix.e + 15) + "px")
        .style("top", (window.pageYOffset + matrix.f - 30) + "px");
})
14
Boxuan

Je suis nouveau sur D3, donc cela ne fonctionnera peut-être pas pour les diagrammes de dispersion ... mais cela semble fonctionner pour les graphiques à barres ... où v1 et v2 correspondent aux valeurs tracées .. et il semble que la valeur des données tableau.

.on("mouseover", function(d) {
                  divt .transition()
                      .duration(200)
                      .style("opacity", .9);
                  divt .html(d.v1)
                      .style("left", x(d.v2)+50 + "px")
                      .style("top",y(d.v1)+ "px");})
0
timemirror