在鼠标悬停在圆上时显示数据


162

我有一组要分散绘制的数据。当我将鼠标悬停在一个圆圈上时,我希望它弹出数据(例如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 2012年

Answers:


181

我认为您想要的是一个工具提示。最简单的方法是在svg:title每个圆上添加一个元素,因为浏览器将负责显示工具提示,并且您不需要鼠标处理程序。该代码将类似于

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

如果您想获得更高级的工具提示,则可以使用Tipsy作为示例。请参阅此处的示例。


3
我喜欢醉酒。现在我唯一的问题是它指向圆的左上角,而不是该演示中的边缘。我没有找到任何明显的原因。 jsfiddle.net/scottieb/JwaaV(最底部的提示)
ScottieB 2012年

那个jsfiddle似乎没有任何工具提示?
拉尔斯·科索夫

您可以尝试将工具提示添加到svg:g与实际圆重叠的,但宽度和高度为零。目前,它正在使用边界框并将工具提示放在边缘。尝试使用Tipsy的选项也可能会有所帮助。
拉尔斯·科特霍夫

1
它似乎不再起作用。此外,我发现了一个例子使用SVG:标题它失败:bl.ocks.org/ilyabo/1339996

1
@nos为我工作。
拉尔斯·科特霍夫

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
您可以将数据绑定到此工具提示吗?
豪尔赫·雷涛

2
Afaik您可以将数据绑定到每个DOM元素。
Pwdr

要将数据绑定到此,只需在括号内添加d,例如:function(d){...,然后将文本更改为所需的文本。例如,假设您有一个名称,它将是:tooltip.text(d.name):
thatOneGuy '16

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

6

您可以像这样传递要在鼠标悬停中使用的enter数据-mouseover事件使用一个函数,将先前编辑的数据作为参数(并将索引作为第二个参数),因此您无需再次使用enter()

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)修改形状,并且不知道如何在enter / update中获取实例。
涡轮增压

您正在使用一些未在代码中定义的函数x()和y()。我认为可以删除。
罗伯特

它们是在OP中提供的
-dannal

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将有助于相对于对象而不是整个页面移动工具提示
Chandra Kanth,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.