66

首先,我使用 d3.js 在数组中显示不同大小的圆圈。在鼠标悬停时,我希望鼠标悬停的圆圈变大,我可以做到,但我不知道如何将它带到前面。目前,一旦它被渲染,它就会隐藏在多个其他圆圈后面。我怎样才能解决这个问题?

这是一个代码示例:

   .on("mouseover", function() { 
    d3.select(this).attr("r", function(d) { return 100; })
  })

我尝试使用 sort 和 order 方法,但它们不起作用。我很确定我没有正确地做到这一点。有什么想法吗?

4

4 回答 4

122

TL;博士

使用最新版本的 D3,您可以selection.raise()按照tmpearce其答案中的说明使用。请向下滚动并投票!


原始答案

您将不得不更改对象的顺序并使鼠标悬停的圆圈成为添加的最后一个元素。正如您在此处看到的:https ://gist.github.com/3922684并按照nautat的建议,您必须在主脚本之前定义以下内容:

d3.selection.prototype.moveToFront = function() {
  return this.each(function(){
    this.parentNode.appendChild(this);
  });
};

然后你只需要在鼠标悬停时调用moveToFront你的对象(比如circles)上的函数:

circles.on("mouseover",function(){
  var sel = d3.select(this);
  sel.moveToFront();
});

编辑:正如Henrik Nordberg所建议的,有必要使用.data(). 这对于不失去对元素的约束是必要的。请阅读 Henrick 的回答(并投赞成票!)以获取更多信息。作为一般建议,始终使用将.data()数据绑定到 DOM 时的第二个参数,以利用 d3 的全部性能功能。


编辑: 正如Clemens Tolboom所提到的,反向功能将是:

d3.selection.prototype.moveToBack = function() {
    return this.each(function() {
        var firstChild = this.parentNode.firstChild;
        if (firstChild) {
            this.parentNode.insertBefore(this, firstChild);
        }
    });
};
于 2013-01-20T16:18:52.357 回答
31

从 d3 版本 4 开始,有一组内置函数可以处理这种类型的行为,而无需自己实现。有关详细信息,请参阅d3v4 文档

长话短说,要将元素放在前面,请使用selection.raise()

选择.raise()

按顺序重新插入每个选定元素,作为其父元素的最后一个子元素。相当于:

selection.each(function() {
this.parentNode.appendChild(this);
});

于 2017-03-08T13:52:23.657 回答
25

如果您使用该moveToFront()方法,请确保为data()join 方法指定第二个参数,否则您的数据将与您的 DOM 不同步。

d3.js 将您的数据(提供给 a parse())方法与您创建的 DOM 元素连接起来。data()如果您按照上述建议操作 DOM,d3.js 将不知道哪个 DOM 元素对应于哪个数据“点”,除非您在调用中为每个数据“点”指定唯一值,如API 参考所示:

.data(data, function(d) { return d.name; })

于 2013-04-04T17:14:22.410 回答
13

根据我对 IE9 的痛苦体验,使用 parentNode.appendChild 可能会导致节点中的事件处理程序丢失。所以我倾向于使用另一种方法,即对节点进行排序,使选中的节点在其他节点之上:

     .on("mouseover", function(selected) {
        vis.selectAll('.node')
        .sort(function(a, b) {
          if (a.id === selected.id) {
            return 1;
          } else {
            if (b.id === selected.id) {
              return -1;
            } else {
              return 0;
            }
          }
        });
      })
于 2013-12-06T14:24:32.430 回答