円のマウスオーバーでデータを表示


162

散布図にプロットする一連のデータがあります。円の1つにマウスカーソルを合わせると、データ(x、yの値など)がポップアップ表示されます。これが私が使ったものです:

vis.selectAll("circle")
   .data(datafiltered).enter().append("svg:circle")
   .attr("cx", function(d) { return x(d.x);})
   .attr("cy", function(d) {return y(d.y)})
   .attr("fill", "red").attr("r", 15)
   .on("mouseover", function() {
        d3.select(this).enter().append("text")
            .text(function(d) {return d.x;})
            .attr("x", function(d) {return x(d.x);})
            .attr("y", function (d) {return y(d.y);}); });

入力するデータについてもっと情報を提供する必要があると思いますか?


1
私も試しました:vis.selectAll( "circle")。each(function(d){vis.append( "svg:text")。attr( "x"、dx).attr( "y"、dy) .text(function(d){return dx;});}); 悲しいかな何もない。
ScottieB

回答:


181

あなたが欲しいのはツールチップだと思います。これを行う最も簡単な方法は、svg:title各円に要素を追加することです。これは、ブラウザーがツールチップの表示を処理し、マウスハンドラーが不要になるためです。コードは次のようになります

vis.selectAll("circle")
   .data(datafiltered).enter().append("svg:circle")
   ...
   .append("svg:title")
   .text(function(d) { return d.x; });

より洗練されたツールチップが必要な場合は、たとえば、ほろ酔いを使用できます。例については、こちらをご覧ください。


3
ほろ酔いが好きです。私の唯一の問題は、それがそのデモのようにエッジではなく、円の左上隅を指していることです。理由はわかりません。 jsfiddle.net/scottieb/JwaaV(一番下の
ティプシー

そのjsfiddleにはツールチップがないようです?
Lars Kotthoff、2012年

svg:g実際の円でオーバーレイしたものにツールチップを追加してみてください。ただし、幅と高さはゼロにしてください。現在は、境界ボックスを取得し、ツールチップを端に配置しています。ほろ酔いのオプションをいじるのも役立つかもしれません。
Lars Kotthoff、2012年

1
もう動かないようです。また、失敗したsvg:titleを使用した例を見つけました:bl.ocks.org/ilyabo/1339996
nos

1
@nosは私のために働く。
Lars Kotthoff、2016年

144

ツールチップを作成するための本当に良い方法をここで説明します:単純なD3ツールチップの例

あなたはdivを追加する必要があります

var tooltip = d3.select("body")
    .append("div")
    .style("position", "absolute")
    .style("z-index", "10")
    .style("visibility", "hidden")
    .text("a simple tooltip");

次に、それを使用してそれを切り替えることができます

.on("mouseover", function(){return tooltip.style("visibility", "visible");})
.on("mousemove", function(){return tooltip.style("top",
    (d3.event.pageY-10)+"px").style("left",(d3.event.pageX+10)+"px");})
.on("mouseout", function(){return tooltip.style("visibility", "hidden");});

d3.event.pageX/ d3.event.pageYは現在のマウス座標です。

あなたが使用できるテキストを変更したい場合 tooltip.text("my tooltip text");

実例


4
このツールチップにデータをバインドできますか?
ホルヘレイタオ2013

2
Afaikでは、すべてのDOM要素にデータをバインドできます。
Pwdr 2013

データをこれにバインドするには、次のように括弧内にdを追加するだけです。たとえば、次のような名前があるとします。tooltip.text(d.name):
thatOneGuy

39

私が最近発見した、それを行うための素晴らしいライブラリがあります。使い方は簡単で、結果は非常にきれいです:d3-tip。

あなたはここに例を見ることができます

ここに画像の説明を入力してください

基本的には、ダウンロード(index.js)を実行し、スクリプトを含めるだけです。

<script src="index.js"></script>

そして、ここからの指示に従ってください (例と同じリンク)

しかし、あなたのコードでは、それは次のようになります:

メソッドを定義します。

var tip = d3.tip()
  .attr('class', 'd3-tip')
  .offset([-10, 0])
  .html(function(d) {
    return "<strong>Frequency:</strong> <span style='color:red'>" + d.frequency + "</span>";
  })

svgを作成する(既に行っているように)

var svg = ...

メソッドを呼び出します。

svg.call(tip);

オブジェクトにヒントを追加します。

vis.selectAll("circle")
   .data(datafiltered).enter().append("svg:circle")
...
   .on('mouseover', tip.show)
   .on('mouseout', tip.hide)

CSSを追加することを忘れないでください:

<style>
.d3-tip {
  line-height: 1;
  font-weight: bold;
  padding: 12px;
  background: rgba(0, 0, 0, 0.8);
  color: #fff;
  border-radius: 2px;
}

/* Creates a small triangle extender for the tooltip */
.d3-tip:after {
  box-sizing: border-box;
  display: inline;
  font-size: 10px;
  width: 100%;
  line-height: 1;
  color: rgba(0, 0, 0, 0.8);
  content: "\25BC";
  position: absolute;
  text-align: center;
}

/* Style northward tooltips differently */
.d3-tip.n:after {
  margin: -1px 0 0 0;
  top: 100%;
  left: 0;
}
</style>

2
最新のd3-tipはd3v4を問題なくサポートしています。グーグルで回るかどうかは明らかではありませんが、d3v4を使用するとうまく機能します。
moodboom 2017

6

次のように、マウスオーバーで使用するデータを渡すことができます。マウスオーバーイベントでは、以前にenter編集したデータを引数として(そしてインデックスを2番目の引数として)関数を使用するためenter()、2回目に使用する必要はありません。

vis.selectAll("circle")
.data(datafiltered).enter().append("svg:circle")
.attr("cx", function(d) { return x(d.x);})
.attr("cy", function(d) {return y(d.y)})
.attr("fill", "red").attr("r", 15)
.on("mouseover", function(d,i) {
    d3.select(this).append("text")
        .text( d.x)
        .attr("x", x(d.x))
        .attr("y", y(d.y)); 
});

ありがとう。私は本当にd3.select(this)形状を変更する必要があり、入力/更新でインスタンスを取得する方法がわかりませんでした。
ターボ

コードで定義されていないいくつかの関数x()およびy()を使用しています。取り外しできると思います。
ロバート

彼らはOPで与えられました
ダニ

5

この簡潔な例は、d3でカスタムツールチップを作成する一般的な方法を示しています。

var w = 500;
var h = 150;

var dataset = [5, 10, 15, 20, 25];

// firstly we create div element that we can use as
// tooltip container, it have absolute position and
// visibility: hidden by default

var tooltip = d3.select("body")
  .append("div")
  .attr('class', 'tooltip');

var svg = d3.select("body")
  .append("svg")
  .attr("width", w)
  .attr("height", h);

// here we add some circles on the page

var circles = svg.selectAll("circle")
  .data(dataset)
  .enter()
  .append("circle");

circles.attr("cx", function(d, i) {
    return (i * 50) + 25;
  })
  .attr("cy", h / 2)
  .attr("r", function(d) {
    return d;
  })
  
  // we define "mouseover" handler, here we change tooltip
  // visibility to "visible" and add appropriate test
  
  .on("mouseover", function(d) {
    return tooltip.style("visibility", "visible").text('radius = ' + d);
  })
  
  // we move tooltip during of "mousemove"
  
  .on("mousemove", function() {
    return tooltip.style("top", (event.pageY - 30) + "px")
      .style("left", event.pageX + "px");
  })
  
  // we hide our tooltip on "mouseout"
  
  .on("mouseout", function() {
    return tooltip.style("visibility", "hidden");
  });
.tooltip {
    position: absolute;
    z-index: 10;
    visibility: hidden;
    background-color: lightblue;
    text-align: center;
    padding: 4px;
    border-radius: 4px;
    font-weight: bold;
    color: orange;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.11.0/d3.min.js"></script>


オブジェクトの位置に対してツールチップが移動する必要がある場合。ツリーグラフの場合のように。属性で使用return tooltip.style("top", (d.x + 40) + "px") .style("left", (d.y + 80) + "px");したい場合があり'mousemove'ます。d.x意志のヘルプはオブジェクトではなく、ページ全体にツールチップを動かす
チャンドラKanth
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.