我有一个 DAG 的 D3.js 可视化,使用力导向布局。有时我想改变某些节点的颜色。到目前为止,我已经使用 this
在点击监听器中完成了此操作:
function clickNode(node) {
d3.select(this).attr("fill", nodeHighlightColour);
}
但是,现在我想更改监听器调用的函数中的节点颜色,而不是监听器本身。它必须是一个单独的函数的原因是我想“突出显示”一系列节点,从单击的节点追溯,因此我需要递归调用该函数 (tracePath
)。
如果我从监听器调用 tracePath
,当我尝试 d3.select(this).attr("fill")
时,我会收到“未定义函数”运行时错误。我猜这是因为 this
不再在范围内。我可以将 node
对象传递给 tracePath
,但这是节点数据而不是 DOM 元素。如何仅使用绑定(bind)到 DOM 元素的数据对象来获取 DOM 元素?
编辑:
正如我在给 Felix Kling 的评论中所写,我不能简单地将 this
传递给 tracePath
。这适用于第一个节点,但我仍然必须递归调用该函数。这是到目前为止我的 tracePath
函数:
// Trace the back from a node - node_el is "this", node is the node data
function tracePath(node_el, node) {
var this_id = node.id;
if (node.logic == null) {
console.log("Highlighting!");
// Using "this" to change colour
d3.select(node_el).attr("fill", nodeHighlightColour);
}
// Look for edges that point to this node
for (var i=0; i<edges.length; i++) {
var e = edges[i];
if (e.target == this_id) {
var next_node = None;
// Get the node at the source of the edge
for (var j = 0; j<nodes.length; j++) {
if (nodes[j].id == e.source) {
next_node = nodes[j];
}
}
// Recursively trace back from that node
if (next_id != None) {
// How do I get the DOM element to pass to tracepath?
tracePath(???, next_node);
}
}
}
}
最佳答案
感谢 Felix Kling 的回答!按照他的建议,我向每个 SVG 圆形元素添加了一个与节点数据 id 相同的 id
,如下所示:
circle = d3.select('#graphics').append("g").selectAll("circle")
.data(force.nodes())
.enter().append("svg:circle")
.attr("id", function(d) {
return d.id;
})
.on("click", clickNode)
然后,我可以使用节点 id 访问 DOM 元素。这是我完成的 tracePath
函数:
// Trace the path back from a node
function tracePath(node_el, node) {
var this_id = node.id;
console.log("in tracepath");
if (node.logic == null) {
console.log("Highlighting!");
d3.select(node_el).attr("fill", nodeHighlightColour);
}
console.log("this_id:", this_id);
// Look for edges that point to this node
for (var i=0; i<edges.length; i++) {
var e = edges[i];
if (e.target.id == this_id) {
console.log("edge from ", e.source.name);
// Recursively trace back from that node
var next_el = document.getElementById(e.source.id);
tracePath(next_el, e.source);
}
}
}
我还注意到 e.target
(其中 e
是一条边)为我提供了目标节点本身,而不仅仅是 id,所以我不需要通过节点进行搜索。
关于jquery - 使用绑定(bind)到 DOM 元素的 D3 数据更改 DOM 元素的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18195709/