D3.js v4/v5 force simulation ラジアルフォース – サンプル
D3.js forceSimulationのforceRadialのデモです (v4/v5対応)。要素をサークル状に配置することが可能です。
サンプルデモ
サンプルプログラム
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | <!DOCTYPE html> <html> <head>   <meta charset="utf-8">   <title>D3 v5 force simulation force radial</title> </head> <body>   <svg width="800" height="600"></svg>   <script src="https://d3js.org/d3.v5.min.js"></script>   <script>   // 1. 描画用のデータ準備   var width = document.querySelector("svg").clientWidth;   var height = document.querySelector("svg").clientHeight;   var nodesData = [];   for(var i = 0; i < 50; i++) {     nodesData.push({       "x": width * Math.random(),       "y": height * Math.random(),       "r": parseInt(20 * Math.random() + 2)     });   }   // 2. svg要素を配置   var node = d3.select("svg")     .selectAll("circle")     .data(nodesData)     .enter()     .append("circle")     .attr("r", function(d) { return d.r })     .attr("fill", "Gold")     .attr("stroke", "black")     .attr("opacity", 0.7)     .call(d3.drag()       .on("start", dragstarted)       .on("drag", dragged)       .on("end", dragended));   // 3. forceSimulation設定   var simulation = d3.forceSimulation()     .force("collide",       d3.forceCollide()       .radius(function(d) { return d.r + 1 })       .iterations(16))     .force("charge", d3.forceManyBody().strength(-30))     .force("r",       d3.forceRadial()       .radius(height * 0.35)       .x(width / 2)       .y(height / 2)       .strength(0.5)     );   simulation.velocityDecay(0.2);   simulation     .nodes(nodesData)     .on("tick", ticked);   // 4. forceSimulation 描画更新用関数   function ticked() {     node       .attr("cx", function(d) { return d.x; })       .attr("cy", function(d) { return d.y; });   }   // 5. ドラッグ時のイベント関数   function dragstarted(d) {     if(!d3.event.active) simulation.alphaTarget(0.3).restart();     d.fx = d.x;     d.fy = d.y;   }   function dragged(d) {     d.fx = d3.event.x;     d.fy = d3.event.y;   }   function dragended(d) {     if(!d3.event.active) simulation.alphaTarget(0);     d.fx = null;     d.fy = null;   }   </script> </body> </html> | 
解説
基本は ノード相互作用のサンプルと同じです。3. forceSimulation設定のみ解説します。
3. forceSimulation設定
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |   // 3. forceSimulation設定   var simulation = d3.forceSimulation()     .force("collide",       d3.forceCollide()       .radius(function(d) { return d.r + 1 })       .iterations(16))     .force("charge", d3.forceManyBody().strength(-30))     .force("r",       d3.forceRadial()       .radius(height / 2 * 0.7)       .x(width / 2)       .y(height / 2)       .strength(0.5)     );   simulation.velocityDecay(0.2);   simulation     .nodes(nodesData)     .on("tick", ticked); | 
forceSimulation.force()で設定できるパラメータをまとめました。
"r" : ラジアルフォース
| radius | サークル半径。値が指定されていない場合は現在の設定値を返します。 | 
| x | サークルの中心x座標。デフォルトは0。 | 
| y | サークルの中心y座標。デフォルトは0。 | 
| strength | サークル上の位置にノードが移動する速さです。1ステップで距離×strengthの値分変化します。1.0以上の数値は非推奨です。0.0~1.0の小数点で設定します。デフォルトは0.1。 | 
まとめ
この重力場は、相関分析などの因果関係の結果を表示するようなリンクが複雑に絡み合っている場合などの表示に役立ちます。




