web-dev-qa-db-ja.com

ツールチップをSVGグラフィックに追加する方法は?

一連のsvg四角形(D3.jsを使用)があり、マウスオーバーでメッセージを表示したい場合、メッセージは背景として機能するボックスで囲まれる必要があります。これらは、互いに完全に整列し、長方形(上部および中央)に完全に整列する必要があります。これを行う最良の方法は何ですか?

「x」、「y」、「width」、および「height」属性を使用してsvgテキストを追加し、svg rectを先頭に追加しようとしました。問題は、テキストの参照点が中央にあることです(中央揃えにしたいのでtext-anchor: middleを使用しました)が、四角形の場合は左上の座標であり、さらにテキストの周りに少しマージンが必要ですそれは一種の痛みになります。

もう1つのオプションは、HTML divを使用することでした。これは、テキストとパディングを直接追加できますが、各四角形の絶対座標を取得する方法がわからないため、ニースになります。これを行う方法はありますか?

79
nachocab

Phrogzが示すように、title要素を使用できます。 jQueryのTipsy http://onehackoranother.com/projects/jquery/tipsy/ (すべてのタイトル要素を置き換えるために使用できます)、Bob Monteverdeのnvd3、Twitterのツールチップなど、いくつかの優れたツールチップもあります。 Bootstrapから http://Twitter.github.com/bootstrap/

12
paxRoman

SVG <title>要素 と、それが伝えるデフォルトのブラウザレンダリングを単純に使用できますか? (注:これはnothtmlのdiv/img/spansで使用できるtitle属性と同じです。 titleという名前の子element

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>

あるいは、本当にSVGにHTMLを表示したい場合は、HTMLを直接埋め込むことができます。

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>

…しかし、ディスプレイのオンとオフを切り替えるにはJSが必要です。上記のように、ラベルを適切な場所に表示する1つの方法は、長方形とHTMLを同じ<g>でラップして、両方を一緒に配置することです。

JSを使用して画面上のSVG要素の場所を見つけるには、getBoundingClientRect()を使用できます。 http://phrogz.net/svg/html_location_in_svg_in_html.xhtml

134
Phrogz

私が見つけた唯一の良い方法は、Javascriptを使用してツールチップ<div>を移動することでした。これは明らかに、スタンドアロンではなくHTMLドキュメント内にSVGがある場合にのみ機能します。また、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

私はいつも自分の設定で一般的なCSSタイトルを使います。ブログの管理ページの分析を作成しています。派手なものは必要ありません。ここにいくつかのコードがあります...

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);

そして、クロムのスクリーンショット...

enter image description here

1
VocoJax