【问题标题】:Changing attribute of a DOM element using D3 data that is bound to it使用绑定到它的 D3 数据更改 DOM 元素的属性
【发布时间】:2013-08-14 06:42:04
【问题描述】:

我有一个 DAG 的 D3.js 可视化,使用强制导向布局。有时我想更改某些节点的颜色。到目前为止,我已经在点击监听器中使用this

function clickNode(node) {
    d3.select(this).attr("fill", nodeHighlightColour);
}

但是,现在我想更改由侦听器调用的函数中的节点颜色,而不是侦听器本身。它必须是一个单独的函数的原因是我想“突出显示”一系列节点,从被点击的节点回溯,所以我需要递归调用函数 (tracePath)。

如果我从侦听器调用tracePath,当我尝试d3.select(this).attr("fill") 时会收到“未定义函数”运行时错误。我猜这是因为this 不再在范围内。我可以将node 对象传递给tracePath,但这是节点数据而不是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);
                    }
            }
    }
}

【问题讨论】:

  • this DOM 元素,所以只需将this 传递给tracePath?
  • @FelixKling 哦哈哈谢谢...应该想到这一点。
  • @FelixKling 实际上这并不完全...因为我需要在不同的节点上递归调用tracePath。我可以通过从相关边缘获取其id 来获取节点数据,但我仍然需要访问其 DOM 元素。我会编辑我的问题,抱歉我忘记了。
  • 如果您设置代码以便为代表节点的 SVG 元素提供一个 ID(相当于您的节点数据的 id 值),那么您可以使用 document.getElementById(next_id) 来获取对下一个节点的引用。

标签: jquery dom d3.js highlight force-layout


【解决方案1】:

感谢 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,所以我不需要搜索节点。

【讨论】:

    猜你喜欢
    • 2017-10-30
    • 1970-01-01
    • 1970-01-01
    • 2013-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多