我怎样才能用d3带来一个圆圈?
首先,我使用d3.js在数组中显示不同大小的圆。 在老鼠身上,我希望圈子被挖出变大,我可以做到,但我不知道如何把它带到前面。 目前,一旦渲染,它隐藏在其他多个圈子之后。 我该如何解决这个问题?
这是一个代码示例:
.on("mouseover", function() { d3.select(this).attr("r", function(d) { return 100; }) })
我尝试使用sorting和顺序的方法,但他们没有工作。 我很确定我没有做正确的。 有什么想法吗?
您将不得不改变对象的顺序,并使鼠标hover的圆圈成为最后添加的元素。 正如你可以在这里看到的: https : //gist.github.com/3922684和nautat的build议,你必须在你的主脚本之前定义以下内容:
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所build议的那样,通过使用.data()
的第二个参数,将数据绑定到DOM是必要的。 这是必要的,不要失去对元素的约束。 请阅读亨里克的答案(并upvote它!)的更多信息。 作为一般的build议,在将数据绑定到DOM时,请始终使用.data()
的第二个参数,以利用d3的全部性能。
编辑:正如Clemens Tolboom所提到的,相反的function是:
d3.selection.prototype.moveToBack = function() { this.each(function() { this.parentNode.firstChild && this.parentNode.insertBefore(this, firstChild); } }); };
如果使用moveToFront()
方法,请确保指定data()
join方法的第二个参数,否则数据将与DOM不同步。
d3.js将您创build的DOM元素(提供给parse()
)方法的数据连接起来。 如果你按照上面提出的方法操作DOM,d3.js将不知道哪个DOM元素对应于什么数据的“点”,除非你为data()
调用中的每个数据“点”指定一个唯一的值,如API参考所示:
.data(data, function(d) { return d.name; })
从我对IE9的痛苦经历中,使用parentNode.appendChild可能会导致节点中丢失事件处理程序。 所以我倾向于使用另一种方法,即对节点进行sorting,以便select的节点高于其他节点:
.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; } } }); })
从d3版本4起,有一组内置的函数可以处理这种types的行为,而不需要自己实现它。 有关更多信息,请参阅d3v4文档 。
长话短说,把元素放在前面,使用selection.raise()
selection.raise()
按顺序重新插入每个选定元素作为其父项的最后一个子项。 相当于:
selection.each(function() {
this.parentNode.appendChild(this);
});