在d3中的树节点上调用操作符



我正在写一个可折叠的树与d3,我想添加和删除节点。从d3网站(http://bl.ocks.org/mbostock/4339083)的例子开始,我在每个节点旁边添加了两个用于添加/删除节点的符号,我使用call()函数调用add_node()或remove_node()函数。

相关代码为:

function update(source) {
    // Compute the new tree layout.
    nodes = tree.nodes(root).reverse(),
    links = tree.links(nodes);
    // Normalize for fixed-depth.
    nodes.forEach(function (d) {
        d.y = d.depth * 80;
    });
    // Update the nodes…
    var node = svg.selectAll("g.node")
    .data(nodes, function (d) {
        return d.id || (d.id = ++i);
    });
    // Enter any new nodes at the parent's previous position.
    var nodeEnter = node.enter().append("g")
    .attr("class", "node")
    .attr("transform", function (d) {
        return "translate(" + source.x0 + "," + source.y0 + ")";
    })
    .on("click", click);
    nodeEnter.append("circle")
    .attr("r", 1e-6)
    .style("fill", function (d) {
        return d._children ? "lightsteelblue" : "#fff";
    });
    nodeEnter.append("text")
    .attr("text-anchor", "middle")
    .attr("dy", "4px")
    .attr("font-size", 0)
    .text(function (d) {
        return d.value;
    })
    .style("fill-opacity", 0.1);

    // X sign and circle for clicking on it
    // ...
    node.append("circle")
    .attr("r", radius *0.8)
    .attr("cx", -radius*1.5)
    .attr("cy", "0px")
    .style("fill-opacity", 0)
    .style("opacity", 0)
    .call(remove_node);
    // plus sign and circle for clicking on it
    // ...
    node.append("circle")
    .attr("r", radius)
    .attr("cx", radius * 1.5)
    .attr("cy", "0px")
    .style("fill-opacity", 0)
    .style("opacity", 0)
    .call(add_node);
    // ...
}
function add_node(node) {
    console.log("add node")
}

function remove_node(node) {
   console.log("remove node");
}

问题是我是否点击节点,添加或删除符号象征,结果总是节点扩展或倒塌的(取决于起始状态)和两个add_node()和remove_node()函数调用,就好像三个电话连接到同一个事件,而我想要的是点击节点的节点展开/折叠,并点击添加符号只调用add_node()函数,点击remove符号只调用remove_node()函数。

这里有一个小提琴:http://jsfiddle.net/andreaiacono/yd5r6u4t/1/

有什么提示我错了吗?

谢谢,安德里亚

您已经添加了节点,它的文本添加符号组件和删除符号组件下的单个g元素。把他们分成3个子组。

然后将.call更改为.on('click'...。因此

// plus sign and circle for clicking on it
node.append("line")
.attr("stroke", "#AAA")
.attr("stroke-width", "2")
.attr("x1", radius * 1.2)
.attr("y1", "0px")
.attr("x2", radius * 1.8)
.attr("y2", "0px")
node.append("line")
.attr("stroke", "#AAA")
.attr("stroke-width", "2")
.attr("x1", radius * 1.5)
.attr("y1", -radius * 0.3)
.attr("x2", radius * 1.5)
.attr("y2", radius * 0.3)
node.append("circle")
.attr("r", radius)
.attr("cx", radius * 1.5)
.attr("cy", "0px")
.style("fill-opacity", 0)
.style("opacity", 0)
.call(add_node);

变成

// plus sign group
var gan = node.append("g")
    .on('click', add_node);
gan.append("line")
    .attr("stroke", "#AAA")
    .attr("stroke-width", "2")
    .attr("x1", radius * 1.2)
    .attr("y1", "0px")
    .attr("x2", radius * 1.8)
    .attr("y2", "0px")
gan.append("line")
    .attr("stroke", "#AAA")
    .attr("stroke-width", "2")
    .attr("x1", radius * 1.5)
    .attr("y1", -radius * 0.3)
    .attr("x2", radius * 1.5)
    .attr("y2", radius * 0.3)

对于其他2组组件也是如此(我看到您已经为节点扩展/折叠提供了一部分)

顺便说一下,如果你需要更多的点击区域,你可以把x和+的圆圈加回去。


更新提琴- http://jsfiddle.net/6egecqzt/

最新更新