現在D3.jsを使用したForce layoutでデータビジュアライズをやっています。
サンプルで見つけたレミゼラブルのjsonファイルを元にしてnodeとlinkを作成しています。
そこで、nodeをクリックしたらそこに向かってズームしてカメラが動くようなアニメーションを作りたいのですが、いまいち検討がつきません。ご教授いただけると嬉しいです。
html
1<!DOCTYPE html> 2<html lang="en"> 3 4<head> 5 <meta charset="UTF-8"> 6 <title>D3.js_demo</title> 7 <link rel="stylesheet" href="style.css"> 8 <!-- <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.1.1/d3.js"></script>--> 9</head> 10 11<body> 12 <svg style="background-color:#231f20"> 13 </svg> 14 <script src="https://d3js.org/d3.v4.min.js"></script> 15 16 <script> 17 var svg = d3.select("svg"), 18 width = +svg.attr("width"), 19 height = +svg.attr("height"); 20 21 var color = d3.scaleOrdinal() 22 .range(["#f7d147", "#03a6a6", "#fe736c", "#ec5a31", "#d8345f", "#a7d129", "#f8eeb4", "#fe736c", "#616f39", "#ff6363", "#a7d129", "#d8345f", "#db2ae2"]); 23 24 var simulation = d3.forceSimulation() 25 .velocityDecay(0.4) //摩擦 26 .force('charge', d3.forceManyBody()) //詳細設定は後で 27 .force('link', d3.forceLink().id(function(d) { 28 return d.id; 29 })) //詳細設定は後で 30 .force('colllision', d3.forceCollide(40)) //nodeの衝突半径:Nodeの最大値と同じ 31 .force('positioningX', d3.forceX()) //詳細設定は後で 32 .force('positioningY', d3.forceY()) //詳細設定は後で 33 .force('center', d3.forceCenter(width / 2, height / 2)); //重力の中心 34 //"svg"にZoomイベントを設定 35 var zoom = d3.zoom() 36 .scaleExtent([1 / 4, 4]) 37 .on('zoom', SVGzoomed); 38 39 svg.call(zoom); 40 41 //"svg"上に"g"をappendしてdragイベントを設定 42 var g = svg.append("g") 43 .call(d3.drag() 44 .on('drag', SVGdragged)) 45 46 function SVGzoomed() { 47 g.attr("transform", d3.event.transform); 48 } 49 50 function SVGdragged(d) { 51 d3.select(this).attr('cx', d.x = d3.event.x).attr('cy', d.y = d3.event.y); 52 }; 53 54 d3.json("miserables.json", function(error, graph) { 55 if (error) throw error; 56 57 58 var link = g.append("g") //svg⇒gに 59 .attr("class", "links") 60 .selectAll("line") 61 .data(graph.links) 62 .enter().append("line") 63 .attr("stroke", "#666666") //輪郭線の色指定追加 64 .attr("stroke-width", function(d) { 65 return Math.sqrt(d.value); 66 }); 67 68 // nodeの定義 69 var node = g.append('g') 70 .attr('class', 'nodes') 71 .selectAll('g') 72 .data(graph.nodes) 73 .enter() 74 .append('g') 75 .call(d3.drag() 76 .on('start', dragstarted) 77 .on('drag', dragged) 78 .on('end', dragended)); 79 80 // node circleの定義 81 node.append("use") 82 .attr("xlink:href", function(d) { 83 return "#" + nodeTypeID(d.group) 84 }) //図形判定 85 .attr('fill', function(d) { 86 return color(d.group); 87 }) 88 .on('click', function(){d3.select(this).attr('fill', 'red')}) //今はとりあえずnodeを赤くするという処理を書いているが、ここでクリックしたnodeに向かってカメラがズームするようなアニメーションをつけたい!! 89 90 91 //node textの定義 92 node.append('text') 93 .attr('text-anchor', 'middle') 94 .attr('fill', 'black') 95 .style('pointer-events', 'none') 96 .attr('font-size', function(d) { 97 return '10px'; 98 }) 99 .text(function(d) { 100 return d.id; 101 }); 102 103 //図形判定 104 function nodeTypeID(d) { 105 var nodetype 106 var arrRect = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0] 107 108 if (arrRect.indexOf(d) >= 0) { 109 //Rect 110 return "rect" 111 } else { 112 //Circle 113 return "circle" 114 } 115 } 116 117 var Defs = svg.append("defs"); 118 119 //Rect 120 var figRect = Defs.append('rect') 121 .attr("id", "rect") 122 .attr('width', 60) 123 .attr('height', 30) 124 .attr('rx', 7) 125 .attr('ry', 7) 126 .attr('x', -(60 / 2)) 127 .attr('y', -(40 / 2)); 128 129 130 simulation 131 .nodes(graph.nodes) 132 .on("tick", ticked); 133 134 simulation.force("link") 135 .links(graph.links); 136 137 simulation.force('charge') 138 .strength(function(d) { 139 return -1000 140 }) //node間の力 141 142 simulation.force('positioningX') //X方向の中心に向けた引力 143 .strength(0.04) 144 145 simulation.force('positioningY') //Y方向の中心に向けた引力 146 .strength(0.04) 147 148 function ticked() { 149 link 150 .attr("x1", function(d) { 151 return d.source.x; 152 }) 153 .attr("y1", function(d) { 154 return d.source.y; 155 }) 156 .attr("x2", function(d) { 157 return d.target.x; 158 }) 159 .attr("y2", function(d) { 160 return d.target.y; 161 }); 162 163 node 164 .attr("cx", function(d) { 165 return d.x; 166 }) 167 .attr("cy", function(d) { 168 return d.y; 169 }) 170 .attr('transform', function(d) { 171 return 'translate(' + d.x + ',' + d.y + ')' 172 }); //nodesの要素が連動して動くように設定 173 } 174 }); 175 176 function dragstarted(d) { 177 if (!d3.event.active) simulation.alphaTarget(0.3).restart(); 178 d.fx = d.x; 179 d.fy = d.y; 180 } 181 182 function dragged(d) { 183 d.fx = d3.event.x; 184 d.fy = d3.event.y; 185 } 186 187 function dragended(d) { 188 if (!d3.event.active) simulation.alphaTarget(0); 189 d.fx = null; 190 d.fy = null; 191 ![イメージ説明](218fdc8611e70250115ee18687392769.png) </script> 192 193 194 195</body> 196 197</html>
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/05/03 09:55