D3JS - Tooltip

Ajouter un tooltip professionel à une visualisation avec JQuery
d3js7.x
Sources :

Présentation

Ce court tutoriel présente un tooltip que nous avons réalisé et qui offre les fonctionnalités suivantes :
  • Gestion d'un header et d'un footer
  • Gestion de N data-block
  • Le tooltip est prévu pour rester dans le SVG auquel il est associé

Les deux fichiers nécessaires à son fonctionnement sont ekseerg-tooltip.js et ekseerg-tooltip.css. Vous êtes libre de les modifier à votre convenance (ils ne sont pas parfaits). Ces deux fichiers seront à inclure à chaque fois que vous voulez mettre en oeuvre ce tooltip. Il vous faudra également JQuery mais nous verrons un peu plus loin qu'il n'est pas obligatoire.

Construction

const eetooltip = new EETooltip({
	'svgId': 'svg', 
	'tooltipId': 'tooltipDiv',
	'headerText': "Information",
	'footerText': "Données DataVis 2015",
	//'keepInSVG': false
});

Rien de bien sorcier ici, nous fournissons l'ID du svg auquel est associé le tooltip ainsi que l'ID du div de notre tooltip (il doit exister dans la page). Le paramètre keepInSVG définit à false permet de faire sortir le tooltip du SVG par le haut, dans le cas contraire (par défaut) le tooltip va passer en dessous de la souris. Le tutoriel suivant montre le comportement avec ce paramètre à false.

Utilisation

rect.on("mouseover", function(d) {
	eetooltip.addDataBlock("height", this.getBBox().height);
	eetooltip.addDataBlock("x", this.getBBox().x);
	eetooltip.show();
});

rect.on("mouseout", function(d) {
	eetooltip.hide();
	eetooltip.removeAllDataBlocks();
});

C'est tout ce qu'il vous faudra pour utiliser ce tooltip. Evidemment nous avons avant cela ajouté des rectangles de hauteur aléatoire à notre SVG (vous pouvez jeter un oeil au code source). Chaque data-block est composé d'un nom et d'une valeur. Il est préférable de rendre visible le tooltip après avoir ajouté tous les data-block. De la même façon on cache le tooltip avant d'enlever les data-blocks. Le tooltip que nous avons réalisé possède quelques options supplémentaires (ajout d'un séparateur, changement du titre et du bas de page).

eetooltip.updateTitle("Information sur la couleur");
eetooltip.addDataBlock("Rouge", 31);
eetooltip.addDataBlock("Vert", 141);
eetooltip.addDataBlock("Bleu", 214);
eetooltip.addDataSeparator();
eetooltip.addDataBlock("Hexa", "#1F8DD6");
eetooltip.updateFooter("Données précalculées");

Et sans JQuery ?

Pour supprimer l'importation de JQuery, il faut modifier le code source du fichier ekseerg-tooltip.js partout ou le $ est utilisé (la 1ere ligne de ce fichier qui vérifie la présence de JQuery doit donc être entièrement supprimé). Le $ est utilisé pour récupérer la hauteur et la largeur du tooltip (celle-ci étant dynamique). Pour supprimer l'usage de JQuery, on peut utiliser le code suivant.

document.getElementById("mydiv").offsetWidth

Attention toute fois, offsetWidth inclut la taille d'une éventuelle bordure alors qu'avec clientWidth on récupère la taille sans bordure. Les mêmes champs existent pour la hauteur. JQuery est aussi utilisé pour récupérer la position du svg dans la page (son offset). Ici c'est déjà un peu plus délicat et c'est la raison pour laquelle nous utilisons JQuery, il y a plusieurs difficultés lorsque l'on veut s'assurer de la compatibilité avec tous les navigateurs et tous les cas. Néanmoins vous trouverez plusieurs solutions sur ces deux pages en anglais de stackoverflow : ici et ici. Prenez bien le temps de lire les différentes propositions ainsi que les commentaires associés.

Enfin, sachez que le tutoriel suivant présente un usage en condition réelle de ce tooltip. Par ailleurs n'hésitez pas à laisser vos propositions d'améliorations en commentaire.

COMMENTAIRES

Apple


Bonjour,

Déjà merci beaucoup pour tous ces magnifiques tutoriels :) !

J'aurai une question par rapport à ce tutoriel, je ne comprends pas comment vous calculez la position de la souris à tout moment pour que la toolkit suive la souris en continu.

J'ai beau essayer ce type de code :
-----------------------
document.body.addEventListener("mousemove", function(event) {
myFunction(event);
});
function myFunction(e) {
var x = e.clientX;
var y = e.clientY;
};
-----------------------

Je ne vois pas du tout comment je pourrai le faire interagir avec cela :
-------------------
.style("left", (d3.event.pageX + 70) + "px")
.style("top", (d3.event.pageY - 50) + "px");
-------------------

Pouvez vous m'aider ! :D

ericfrigot


Bonjour,
Merci pour le compliment !
Concernant votre problème, je n'ai pas tous les éléments pour en être sûr mais il faut pour que l'application du style left et top fonctionne que vous ayez définit le composant HTML associé (un DIV par exemple) avec une position absolute sinon ça n'a pas de sens. Pensez à regarder également le CSS associé au fichier JS. Si ça ne suffit pas, il serait préférable que vous puissiez me montrer un code plus complet (en le faisant héberger sur https://jsfiddle.net/ par exemple. Je viens de faire une version simplifiée de la fonction : https://www.datavis.fr/d3js...
Eric

Apple


Merci beaucoup, tout marche, grâce à votre exemple :)

Bonne Journées à vous et bonne continuation !

Tim


Bonsoir,
J'obtiens l'erreur suivante (image jointe) et je ne comprends pas d'où ça vient ...

Voici ma définition du tooltip :

var eetooltip = new EETooltip({
'svgId': 'svgInlineDiv',
'tooltipId': 'tooltipDiv',
'headerText': "",
'footerText': "",
'keepInSVG': false
});

Et son utilisation :

// Tooltips

[].slice.call(svgInlineDiv.querySelectorAll('g#g36-2>path'))
.forEach(function (path) {
path.on("mouseover", function (d) {
console.log("Mouse over !");
eetooltip.addDataBlock("height", this.getBBox().height);
eetooltip.addDataBlock("x", this.getBBox().x);
eetooltip.show();
});

path.on("mouseout", function (d) {
eetooltip.hide();
eetooltip.removeAllDataBlocks();
});
});

ericfrigot


Bonjour, pas évident de comprendre d’où vient l'erreur. Pourriez-vous me donner un lien vers une page sur laquelle le code serait présent ? Ou alors mettre à disposition sur un site un fichier ZIP avec le code à exécuter ? Eric

Tim


http://we.tl/fLZlssimFT

Voici une archive contenant l’intégralité du code !

ericfrigot


J'ai mis à jour le fichier ekseerg-tooltip.js, vous pouvez le récupérer à nouveau. Il y avait une erreur dans le code. Ca devrait fonctionner maintenant. Eric

Tim


Merci pour votre aide !
Ce site est très utile, merci de partager tout ça ;)