(编辑:问题已解决,见下文)我是一名生物学家,负责制定突触连接和分析数据。我有一些关于可视化网络的想法,我认为这很酷,我一直在努力学习D3,以便能够通过网络共享可视化的方式来实现它们。我有一个由节点和链接组成的图表。当我将鼠标悬停在节点上时,我希望该节点以及所有连接的节点移动到图形的顶部,以免被周围的节点遮挡。我对编程很新,所以请原谅这是一个愚蠢的问题。现在,我让它直接使用迈克博斯托克提出的建议,以回应别人的问题,直接使用该模式......也就是说,定义一个将某些内容移动到第一个子位置的函数:
d3.selection.prototype.moveToFront = function() {
return this.each(function() { this.parentNode.appendChild(this);});
};
还要创建连接节点的索引(从另一个帖子中获取)
var linkedByIndex = {};
links.forEach(function(d) {
linkedByIndex[d.source.Id + "," + d.target.Id] = 1;
});
function isConnectedNode(a, b) {
linkedByIndex[a.Id + "," + b.Id] || linkedByIndex[b.Id + "," + a.Id] || a.Id == b.Id;
}
然后有一个使用这些东西的鼠标悬停功能:
function nodeMouseover(d){
d3.select(this).moveToFront();
svg.selectAll("circle").transition()
.duration(250)
.attr("r", function(e){return isConnectedNode(d, e) ? 15 : 6;})
.attr("class", function(e){return isConnectedNode(d,e) ? "active":"inactive";});
}
现在,这一切都适用于将我已经将moused移到前面的节点。我也希望所有的CONNECTED节点都被带到前面,所以我想做的是:使用.active节点的class属性(成功分配给所有连接的节点)再次在mouseover函数中调用moveToFront,因此它们也被移动到前面,如下所示:
function nodeMouseover(d){
d3.select(this).moveToFront();
svg.selectAll("circle").transition()
.duration(250)
.attr("r", function(e){return isConnectedNode(d, e) ? 15 : 6;})
.attr("class", function(e){return isConnectedNode(d,e) ? "active":"inactive";});
svg.selectAll(".active").moveToFront();
}
但是,这不起作用,我似乎无法弄清楚为什么......任何想法?有什么简单的方法吗?我正在玩这个并尝试真正理解这里的工作原理,所以非常感谢任何帮助。
解: 好的,一切都通过使用.each()语句来解决。我的nodeMouseover现在看起来像这样:
function nodeMouseover(d){
svg.selectAll(".link").attr("display", function(p){return isConnectedEdge(d, p) ? "block" : "none";});
svg.selectAll("circle").each(function(e){if (isConnectedNode(d,e)){d3.select(this).moveToFront();}})
.transition()
.duration(250)
.attr("r", function(e){return isConnectedNode(d, e) ? 15 : 6;})}
请注意,我不再使用class属性。这是完成它的最佳方式吗?再次感谢任何看过它的人。