簡體   English   中英

d3 樹形圖 v4 添加 Toggle 功能

[英]Add a Toggle function to d3 tree chart v4

我是 d3 的新手,我正在嘗試使用左右節點渲染此 d3 樹形圖。 初始樹渲染工作正常,我添加了一個切換函數,該函數將使孩子為空並調用渲染方法,但它不起作用。 請幫忙。

 var data = { "name": "Root", "children": [{ "name": "Branch 1" }, { "name": "Branch 2", "children": [{ "name": "Branch 2.1" }, { "name": "Branch 2.2", "children": [{ "name": "Branch 2.2.1" }, { "name": "Branch 2.2.2" }] }] }, { "name": "Branch 3" }, { "name": "Branch 4", "children": [{ "name": "Branch 4.1" }, { "name": "Branch 4.2" }] }, { "name": "Branch 5" }, { "name": "Branch 6" }, { "name": "Branch 7", "children": [{ "name": "Branch 7.1" }, { "name": "Branch 7.2", "children": [{ "name": "Branch 7.2.1" }, { "name": "Branch 7.2.2" }] }] }, { "name": "Branch 8" }, { "name": "Branch 9", "children": [{ "name": "Branch 9.1" }, { "name": "Branch 9.2" }] }, { "name": "Branch 10" } ] }; var split_index = Math.round(data.children.length / 2) // Left data var data1 = { "name": data.name, "children": JSON.parse(JSON.stringify(data.children.slice(0, split_index))) }; // Right data var data2 = { "name": data.name, "children": JSON.parse(JSON.stringify(data.children.slice(split_index))) }; // Create d3 hierarchies var right = d3.hierarchy(data1); var left = d3.hierarchy(data2); // Render both trees drawTree(right, "right") drawTree(left, "left") // draw single tree function drawTree(root, pos) { var SWITCH_CONST = 1; if (pos === "left") { SWITCH_CONST = -1; } var svg = d3.select("svg"), width = +svg.attr("width"), height = +svg.attr("height") // Shift the entire tree by half it's width var g = svg.append("g").attr("transform", "translate(" + width / 2 + ",0)"); // Create new default tree layout var tree = d3.tree() // Set the size // Remember the tree is rotated // so the height is used as the width // and the width as the height .size([height, SWITCH_CONST * (width - 150) / 2]); tree(root) var nodes = root.descendants(); var links = root.links(); // Set both root nodes to be dead center vertically nodes[0].x = height / 2 // Create links var link = g.selectAll(".link") .data(links) .enter() link.append("path") .attr("class", "link") .attr("d", function(d) { return "M" + d.target.y + "," + d.target.x + "C" + (d.target.y + d.source.y) / 2.5 + "," + d.target.x + " " + (d.target.y + d.source.y) / 2 + "," + d.source.x + " " + d.source.y + "," + d.source.x; }); // Create nodes var node = g.selectAll(".node") .data(nodes) .enter() .append("g") .attr("class", function(d) { return "node" + (d.children ? " node--internal" : " node--leaf"); }) .attr("transform", function(d) { return "translate(" + dy + "," + dx + ")"; }).on("click", function(e, d) { toggle(d, pos); }) node.append("circle") .attr("r", function(d, i) { return 2.5 }); node.append("text") .attr("y", -10) .style("text-anchor", "middle") .text(function(d) { return d.data.name }); } function toggle(d, pos) { console.log(d, pos); if (d.children) { d._children = d.children; d.children = null; } else { d.children = d._children; d._children = null; } this.drawTree(d, pos); }
 .node circle { fill: #999; } .node text { font: 12px sans-serif; } .node--internal circle { fill: #555; } .link { fill: none; stroke: #555; stroke-opacity: 0.4; stroke-width: 1.5px; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.2.0/d3.min.js"></script> <svg width="900" height="600"></svg>

您只添加了新節點,從未刪除它們。 這樣,舊節點將在單擊后留在那里。 您可以使用.join()來解決這個問題。

此外,您使用單擊的節點作為樹的新根,但這是無效的。 相反,傳遞真正的根並完全重繪樹的那部分。 否則,樹的其余部分將被完全遺忘。

 var data = { "name": "Root", "children": [{ "name": "Branch 1" }, { "name": "Branch 2", "children": [{ "name": "Branch 2.1" }, { "name": "Branch 2.2", "children": [{ "name": "Branch 2.2.1" }, { "name": "Branch 2.2.2" }] }] }, { "name": "Branch 3" }, { "name": "Branch 4", "children": [{ "name": "Branch 4.1" }, { "name": "Branch 4.2" }] }, { "name": "Branch 5" }, { "name": "Branch 6" }, { "name": "Branch 7", "children": [{ "name": "Branch 7.1" }, { "name": "Branch 7.2", "children": [{ "name": "Branch 7.2.1" }, { "name": "Branch 7.2.2" }] }] }, { "name": "Branch 8" }, { "name": "Branch 9", "children": [{ "name": "Branch 9.1" }, { "name": "Branch 9.2" }] }, { "name": "Branch 10" } ] }; var split_index = Math.round(data.children.length / 2) // Left data var data1 = { "name": data.name, "children": JSON.parse(JSON.stringify(data.children.slice(0, split_index))) }; // Right data var data2 = { "name": data.name, "children": JSON.parse(JSON.stringify(data.children.slice(split_index))) }; // Create d3 hierarchies var right = d3.hierarchy(data1); var left = d3.hierarchy(data2); var svg = d3.select("svg"), width = +svg.attr("width"), height = +svg.attr("height"); // Shift the entire tree by half it's width var g = svg.append("g") .attr("transform", "translate(" + width / 2 + ",0)"); // Render both trees drawTree(right, "right") drawTree(left, "left") // draw single tree function drawTree(root, pos) { var SWITCH_CONST = 1; if (pos === "left") { SWITCH_CONST = -1; } // Create new default tree layout var tree = d3.tree() // Set the size // Remember the tree is rotated // so the height is used as the width // and the width as the height .size([height, SWITCH_CONST * (width - 150) / 2]); tree(root) var nodes = root.descendants(); var links = root.links(); // Set both root nodes to be dead center vertically nodes[0].x = height / 2 // Create links var link = g.selectAll(".link." + pos) .data(links) .join( enter => enter.append("path"), update => update, exit => exit.remove() ) .attr("class", "link " + pos) .attr("d", function(d) { return "M" + d.target.y + "," + d.target.x + "C" + (d.target.y + d.source.y) / 2.5 + "," + d.target.x + " " + (d.target.y + d.source.y) / 2 + "," + d.source.x + " " + d.source.y + "," + d.source.x; }); // Create nodes var node = g.selectAll(".node." + pos) .data(nodes) .join( enter => { const n = enter .append("g") .on("click", (e, d) => toggle(d, pos, pos === "left" ? left : right)); n.append("circle").attr("r", 2.5); n.append("text").attr("y", -10).style("text-anchor", "middle"); return n; }, update => update, exit => exit.remove() ) .attr("class", function(d) { return "node " + pos + (d.children ? " node--internal" : " node--leaf"); }) .attr("transform", function(d) { return "translate(" + dy + "," + dx + ")"; }) .select("text") .text(function(d) { return d.data.name }); } function toggle(d, pos, root) { if (d.children) { d._children = d.children; d.children = null; } else { d.children = d._children; d._children = null; } this.drawTree(root, pos); }
 .node circle { fill: #999; } .node text { font: 12px sans-serif; } .node--internal circle { fill: #555; } .link { fill: none; stroke: #555; stroke-opacity: 0.4; stroke-width: 1.5px; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.2.0/d3.min.js"></script> <svg width="900" height="600"></svg>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM