it-swarm.com.de

Wie füge ich einen Tooltip zu einer Svg-Grafik hinzu?

Ich habe eine Reihe von SVG-Rechtecken (mit D3.js) und möchte eine Nachricht beim Mouseover anzeigen. Die Nachricht sollte von einem Kästchen umgeben sein, das als Hintergrund fungiert. Sie sollten beide perfekt zueinander und zum Rechteck (oben und zentriert) ausgerichtet sein. Wie geht das am besten?

Ich habe versucht, einen SVG-Text mit den Attributen "x", "y", "width" und "height" hinzuzufügen, und dann ein SVG-Rect vorangestellt. Das Problem ist, dass sich der Bezugspunkt für den Text in der Mitte befindet (da ich ihn zentriert ausrichten möchte, habe ich text-anchor: middle Verwendet), aber für das Rechteck ist es die linke obere Koordinate, und ich wollte etwas Rand um das Text, der es irgendwie schmerzhaft macht.

Die andere Option war die Verwendung eines HTML-Divs, was nett wäre, da ich den Text und das Auffüllen direkt hinzufügen kann, aber nicht weiß, wie die absoluten Koordinaten für jedes Rechteck ermittelt werden. Gibt es eine Möglichkeit, dies zu tun?

79
nachocab

Sie können das title-Element wie von Phrogz angegeben verwenden. Es gibt auch einige gute Tooltips wie jQueries Tipsy http://onehackoranother.com/projects/jquery/tipsy/ (das verwendet werden kann, um alle Titelelemente zu ersetzen), Bob Monteverdes nvd3 oder sogar den Tooltip von Twitter von ihrem Bootstrap http://Twitter.github.com/bootstrap/

12
paxRoman

Können Sie einfach das SVG <title> - Element und das von ihm übermittelte Standard-Browser-Rendering verwenden? (Hinweis: Dies ist nicht dasselbe wie das title -Attribut, das Sie für div/img/spans in HTML verwenden können, es muss sei ein Kind Element mit dem Namen 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>

Wenn Sie HTML in Ihrer SVG-Datei wirklich anzeigen möchten, können Sie HTML auch direkt einbetten:

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>

... aber dann brauchst du JS, um das Display ein- und auszuschalten. Wie oben gezeigt, besteht eine Möglichkeit, die Beschriftung an der richtigen Stelle anzuzeigen, darin, das Rect und HTML in dasselbe <g> Zu setzen, mit dem beide zusammen positioniert werden.

Um mit JS herauszufinden, wo sich ein SVG-Element auf dem Bildschirm befindet, können Sie getBoundingClientRect() verwenden, z. http://phrogz.net/svg/html_location_in_svg_in_html.xhtml

134
Phrogz

Der einzige gute Weg, den ich gefunden habe, war die Verwendung von Javascript zum Verschieben eines Tooltips <div> um. Dies funktioniert natürlich nur, wenn Sie SVG in einem HTML-Dokument haben - nicht eigenständig. Und es erfordert 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>
14
Timmmm

Ich gehe bei meinem Setup immer mit dem generischen CSS-Titel um. Ich erstelle gerade Analysen für meine Blog-Admin-Seite. Ich brauche nichts Besonderes. Hier ist ein Code ...

let comps = g.selectAll('.myClass')
   .data(data)
   .enter()
   .append('rect')
   ...styling...
   ...transitions...
   ...whatever...

g.selectAll('.myClass')
   .append('svg:title')
   .text((d, i) => d.name + '-' + i);

Und ein Screenshot von Chrome ...

enter image description here

1
VocoJax