124 votes

Comment ajouter une infobulle à un graphique svg ?

J'ai une série de rectangles svg (utilisant D3.js) et je veux afficher un message au survol de la souris, le message doit être entouré d'une boîte qui agit comme arrière-plan. Le message doit être entouré d'une boîte qui sert de fond. Les deux doivent être parfaitement alignés l'un sur l'autre et sur le rectangle (en haut et centré). Quelle est la meilleure façon de procéder ?

J'ai essayé d'ajouter un texte svg en utilisant les attributs "x", "y", "width" et "height", puis d'ajouter un rect svg. Le problème est que le point de référence du texte est au milieu (comme je veux qu'il soit centré, j'ai utilisé l'attribut text-anchor: middle ), mais pour le rectangle, c'est la coordonnée supérieure gauche, et je voulais une marge autour du texte, ce qui est un peu pénible.

L'autre option était d'utiliser une div html, ce qui serait bien, parce que je peux ajouter le texte et le padding directement, mais je ne sais pas comment obtenir les coordonnées absolues pour chaque rectangle. Est-ce qu'il y a un moyen de faire cela ?

214voto

Phrogz Points 112337

Pouvez-vous utiliser simplement le SVG <title> élément et le rendu par défaut du navigateur qu'il véhicule ? (Note : il s'agit de no la même que celle de la title que vous pouvez utiliser sur les div/img/spans en html, il doit s'agir d'un attribut child élément nommée title )

rect {
  width: 100%;
  height: 100%;
  fill: #69c;
  stroke: #069;
  stroke-width: 5px;
  opacity: 0.5
}

<p>Mouseover the rect to see the tooltip on supporting browsers.</p>

<svg xmlns="http://www.w3.org/2000/svg">
  <rect>
    <title>Hello, World!</title>
  </rect>
</svg>

Par ailleurs, si vous souhaitez vraiment afficher du HTML dans votre SVG, vous pouvez l'intégrer directement :

rect {
  width: 100%;
  height: 100%;
  fill: #69c;
  stroke: #069;
  stroke-width: 5px;
  opacity: 0.5
}

foreignObject {
  width: 100%;
}

svg div {
  text-align: center;
  line-height: 150px;
}

<svg xmlns="http://www.w3.org/2000/svg">
  <rect/>
  <foreignObject>
    <body xmlns="http://www.w3.org/1999/xhtml">
      <div>
        Hello, <b>World</b>!
      </div>
    </body>      
  </foreignObject>
</svg>

mais il faudrait alors un JS pour allumer et éteindre l'écran. Comme indiqué ci-dessus, une façon de faire apparaître l'étiquette au bon endroit est d'envelopper le rectangle et le code HTML dans le même fichier <g> qui les positionne tous les deux ensemble.

Pour utiliser JS afin de trouver l'emplacement d'un élément SVG à l'écran, vous pouvez utiliser getBoundingClientRect() , par exemple http://phrogz.net/svg/html_location_in_svg_in_html.xhtml

73voto

Timmmm Points 9909

La seule bonne méthode que j'ai trouvée consiste à utiliser Javascript pour déplacer une info-bulle. <div> autour. Évidemment, cela ne fonctionne que si le SVG se trouve à l'intérieur d'un document HTML, et non pas de manière autonome. Et cela nécessite du Javascript.

function showTooltip(evt, text) {
  let tooltip = document.getElementById("tooltip");
  tooltip.innerHTML = text;
  tooltip.style.display = "block";
  tooltip.style.left = evt.pageX + 10 + 'px';
  tooltip.style.top = evt.pageY + 10 + 'px';
}

function hideTooltip() {
  var tooltip = document.getElementById("tooltip");
  tooltip.style.display = "none";
}

#tooltip {
  background: cornsilk;
  border: 1px solid black;
  border-radius: 5px;
  padding: 5px;
}

<div id="tooltip" display="none" style="position: absolute; display: none;"></div>

<svg>
  <rect width="100" height="50" style="fill: blue;" onmousemove="showTooltip(evt, 'This is blue');" onmouseout="hideTooltip();" >
  </rect>
</svg>

17voto

paxRoman Points 1381

Vous pouvez utiliser l'élément title comme l'a indiqué Phrogz. Il existe également de bonnes infobulles comme Tipsy de jQuery http://onehackoranother.com/projects/jquery/tipsy/ (qui peut être utilisé pour remplacer tous les éléments de titre), le nvd3 de Bob Monteverde ou même l'infobulle de Twitter dans leur Bootstrap http://twitter.github.com/bootstrap/

12voto

Imtiaz Pabel Points 3432

Sur svg, la bonne façon d'écrire le titre

<svg>
  <title id="unique-id">Checkout</title>
</svg>

voir ici pour plus de détails https://css-tricks.com/svg-title-vs-html-title-attribute/

7voto

mhdi Points 119

J'ai trouvé quelque chose en utilisant uniquement HTML + CSS. J'espère que cela fonctionnera pour vous

.mzhrttltp {
  position: relative;
  display: inline-block;
}
.mzhrttltp .hrttltptxt {
  visibility: hidden;
  width: 120px;
  background-color: #040505;
  font-size:13px;color:#fff;font-family:IranYekanWeb;
  text-align: center;
  border-radius: 3px;
  padding: 4px 0;
  position: absolute;
  z-index: 1;
  top: 105%;
  left: 50%;
  margin-left: -60px;
}

.mzhrttltp .hrttltptxt::after {
  content: "";
  position: absolute;
  bottom: 100%;
  left: 50%;
  margin-left: -5px;
  border-width: 5px;
  border-style: solid;
  border-color: transparent transparent #040505 transparent;
}

.mzhrttltp:hover .hrttltptxt {
  visibility: visible;
}

<div class="mzhrttltp"><svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 24 24" fill="none" stroke="#e2062c" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="feather feather-heart"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><div class="hrttltptxt">علاقه&zwnj;مندی&zwnj;ها</div></div>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X