繁体   English   中英

从 d3js 树布局中删除节点及其子节点

[英]Removing node and its children from d3js tree layout

我从 d3js 开始玩 d3js 树布局。 我从这个block.cks 示例开始

我正在尝试删除路径,它是单击路径的子项,以下是我当前的代码。

 var treeData = [ { "name": "Top Level", "parent": "null", "children": [ { "name": "Level 2: A", "parent": "Top Level", "children": [ { "name": "Son of A", "parent": "Level 2: A" }, { "name": "Daughter of A", "parent": "Level 2: A" } ] }, { "name": "Level 2: B", "parent": "Top Level" } ] } ]; // ************** Generate the tree diagram ***************** var margin = {top: 20, right: 120, bottom: 20, left: 120}, width = 960 - margin.right - margin.left, height = 500 - margin.top - margin.bottom; var i = 0, duration = 750, root; var tree = d3.layout.tree() .size([height, width]); var diagonal = d3.svg.diagonal() .projection(function(d) { return [dy, dx]; }); var svg = d3.select("body").append("svg") .attr("width", width + margin.right + margin.left) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); root = treeData[0]; root.x0 = height / 2; root.y0 = 0; update(root); d3.select(self.frameElement).style("height", "500px"); function update(source) { // Compute the new tree layout. var nodes = tree.nodes(root).reverse(), links = tree.links(nodes); // Normalize for fixed-depth. nodes.forEach(function(d) { dy = d.depth * 180; }); // 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.y0 + "," + source.x0 + ")"; }) .on("click", click); nodeEnter.append("circle") .attr("r", 1e-6) .style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; }); nodeEnter.append("text") .attr("x", function(d) { return d.children || d._children ? -13 : 13; }) .attr("dy", ".35em") .attr("text-anchor", function(d) { return d.children || d._children ? "end" : "start"; }) .text(function(d) { return d.name; }) .style("fill-opacity", 1e-6); // Transition nodes to their new position. var nodeUpdate = node.transition() .duration(duration) .attr("transform", function(d) { return "translate(" + dy + "," + dx + ")"; }); nodeUpdate.select("circle") .attr("r", 10) .style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; }); nodeUpdate.select("text") .style("fill-opacity", 1); // Transition exiting nodes to the parent's new position. var nodeExit = node.exit().transition() .duration(duration) .attr("transform", function(d) { return "translate(" + source.y + "," + source.x + ")"; }) .remove(); nodeExit.select("circle") .attr("r", 1e-6); nodeExit.select("text") .style("fill-opacity", 1e-6); // Update the links… var link = svg.selectAll("path.link") .data(links, function(d) { return d.target.id; }); // Enter any new links at the parent's previous position. link.enter().insert("path", "g") .attr("class", "link") .attr("d", function(d) { var o = {x: source.x0, y: source.y0}; return diagonal({source: o, target: o}); }) .on("click",removeNode); //remove node on click //function to remove node function removeNode() { this.remove(); } // Transition links to their new position. link.transition() .duration(duration) .attr("d", diagonal); // Transition exiting nodes to the parent's new position. link.exit().transition() .duration(duration) .attr("d", function(d) { var o = {x: source.x, y: source.y}; return diagonal({source: o, target: o}); }) .remove(); // Stash the old positions for transition. nodes.forEach(function(d) { d.x0 = dx; d.y0 = dy; }); } // Toggle children on click. function click(d) { if (d.children) { d._children = d.children; d.children = null; } else { d.children = d._children; d._children = null; } update(d); }
 .node { cursor: pointer; } .node circle { fill: #fff; stroke: steelblue; stroke-width: 3px; } .node text { font: 12px sans-serif; } .link { fill: none; stroke: #ccc; stroke-width: 2px; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

现在点击路径,路径被删除。 我还想删除连接的节点(子节点)及其所有后继节点(如果有)。

如何访问路径触发的点击功能内的子节点?

这是错误的:

function removeNode()
  {
     this.remove();//it will remove only the link.
  }

您可以执行类似操作来删除节点及其所有子节点。

function removeNode(d)
{
  //this is the links target node which you want to remove
     var target = d.target;
     //make new set of children
     var children = [];
     //iterate through the children 
     target.parent.children.forEach(function(child){
       if (child.id != target.id){
         //add to the child list if target id is not same 
         //so that the node target is removed.
         children.push(child);
       }
     });
     //set the target parent with new set of children sans the one which is removed
     target.parent.children = children;
     //redraw the parent since one of its children is removed
     update(d.target.parent)
}

这里的工作示例

希望这可以帮助!

上面的答案是正确的,但有时它不适用于 d3 v4。

在 v4 中,您不能添加空子数组,而应将其设置为 null

所以,只需添加

if (children.length === 0) {
    children = null;
}

在更新target.parent.children之前

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM