前提・実現したいこと
JavaScript(D3.js)でこちらのURL(D3.js v4/v5 treeを開閉する方法 – サンプル)を参考にして、開閉するグラフを作成しています。
このグラフを同じページに複数作成したいのです。
下記のソースコードにより、複数表示自体はできるのですが、開閉する機能を全てにつけることができません。
一番下に描画されたグラフには、開閉機能が付いているのですが、それ以外のグラフは、ノードをクリックしても動きません。
これを、全ての木に対して、開閉するグラフにしようとしているのですが、どのように作成すればよいでしょうか。
当方D3.js初心者ですよろしくお願いいたします。
該当のソースコード
html
1<!DOCTYPE html> 2<html> 3 4 <head> 5 <meta charset="utf-8"> 6 <title>D3 collapsible tree in v4/v5</title> 7 <!-- 1. スタイルの設定 --> 8 <style> 9 .node { 10 cursor: pointer; 11 } 12 13 .node circle { 14 fill: #fff; 15 stroke: steelblue; 16 stroke-width: 1.5px; 17 } 18 19 .link { 20 fill: none; 21 stroke: #555; 22 stroke-opacity: 0.6; 23 stroke-width: 1.5px; 24 } 25 </style> 26 </head> 27 28 <body> 29 <svg id="tree0" width="800" height="600"></svg> 30 <svg id="tree1" width="800" height="600"></svg> 31 <svg id="tree2" width="800" height="600"></svg> 32 <script src="https://d3js.org/d3.v5.min.js"></script> 33 <script> 34 for(var j=0;j<3;j++){ 35 // 2. 描画用データの準備 36 var width = document.querySelector(`#tree${j}`).clientWidth; 37 var height = document.querySelector(`#tree${j}`).clientHeight; 38 var data = { 39 "name": "A", 40 "children": [ 41 { "name": "B" }, 42 { 43 "name": "C", 44 "children": [{ "name": "D" }, { "name": "E" }, { "name": "F" }] 45 }, 46 { "name": "G" }, 47 { 48 "name": "H", 49 "children": [{ "name": "I" }, { "name": "J" }] 50 }, 51 { "name": "K" } 52 ] 53 }; 54 55 // 3. 描画用データの変換 56 root = d3.hierarchy(data); 57 root.x0 = height / 2; 58 root.y0 = 0; 59 60 var tree = d3.tree().size([height, width - 160]); 61 62 // 4. svgデータの描画用データの変換 63 g = d3.select(`#tree${j}`).append("g").attr("transform", "translate(80,0)"); 64 update(root); 65 } 66 67 // 5. クリック時の呼び出し関数 68 function toggle(d) { 69 if(d.children) { 70 d._children = d.children; 71 d.children = null; 72 } else { 73 d.children = d._children; 74 d._children = null; 75 } 76 } 77 78 // 6.svg要素の更新関数 79 var i = 0; 80 function update(source) { 81 82 // tree レイアウト位置を計算 83 tree(root); 84 85 // 子、孫方向の位置設定 86 root.each(function(d) { d.y = d.depth * 320; }); 87 88 // ノードデータをsvg要素に設定 89 var node = g.selectAll('.node') 90 .data(root.descendants(), function(d) { return d.id || (d.id = ++i); }); 91 92 // ノード enter領域の設定 93 var nodeEnter = node 94 .enter() 95 .append("g") 96 .attr("class", "node") 97 .attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; }) 98 .on("click", function(d) { 99 toggle(d); 100 update(d); 101 }); 102 103 nodeEnter.append("circle") 104 .attr("r", 5) 105 .style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; }); 106 107 nodeEnter.append("text") 108 .attr("x", function(d) { return d.children || d._children ? -13 : 13; }) 109 .attr("dy", "3") 110 .attr("font-size", "150%") 111 .attr("text-anchor", function(d) { return d.children || d._children ? "end" : "start"; }) 112 .text(function(d) { return d.data.name; }) 113 .style("fill-opacity", 1e-6); 114 115 // ノード enter+update領域の設定 116 var nodeUpdate = nodeEnter.merge(node); 117 var duration = 500; 118 119 nodeUpdate.transition() 120 .duration(duration) 121 .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; }); 122 123 nodeUpdate.select("circle") 124 .attr("r", 8) 125 .style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; }); 126 127 nodeUpdate.select("text") 128 .style("fill-opacity", 1); 129 130 // ノード exit領域の設定 131 var nodeExit = node 132 .exit() 133 .transition() 134 .duration(duration) 135 .attr("transform", function(d) { return "translate(" + source.y + "," + source.x + ")"; }) 136 .remove(); 137 138 nodeExit.select("circle") 139 .attr("r", 1e-6); 140 141 nodeExit.select("text") 142 .style("fill-opacity", 1e-6); 143 144 // リンクデータをsvg要素に設定 145 var link = g.selectAll(".link") 146 .data(root.links(), function(d) { return d.target.id; }); 147 148 // リンク enter領域のsvg要素定義 149 var linkEnter = link.enter().insert('path', "g") 150 .attr("class", "link") 151 .attr("d", d3.linkHorizontal() 152 .x(function(d) { return source.y0; }) 153 .y(function(d) { return source.x0; })); 154 155 // リンク enter+update領域の設定 156 var linkUpdate = linkEnter.merge(link); 157 linkUpdate 158 .transition() 159 .duration(duration) 160 .attr("d", d3.linkHorizontal() 161 .x(function(d) { return d.y; }) 162 .y(function(d) { return d.x; })); 163 164 // リンク exit領域の設定 165 link 166 .exit() 167 .transition() 168 .duration(duration) 169 .attr("d", d3.linkHorizontal() 170 .x(function(d) { return source.y; }) 171 .y(function(d) { return source.x; }) 172 ) 173 .remove(); 174 175 // 次の動作のために現在位置を記憶 176 node.each(function(d) { 177 d.x0 = d.x; 178 d.y0 = d.y; 179 }); 180 } 181 182 </script> 183 </body> 184 185</html>
試したこと
rootやgといった変数を自分で新たに設定したり、update関数の中の変数を全てグローバルスコープにしたりと色々試したのですが実現せず・・・
どうやら、 (///ノードデータをsvg要素に設定) とコメントアウトに書いてる部分 のidの設定が上手くいってない模様・・・
それ以外にも原因はあると思いますが。
補足情報(FW/ツールのバージョンなど)
D3.js v5
ブラウザはChromeを使用しています。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/08/17 08:57