2016-03-19 24 views
1

D3の仕組みを理解するのは難しいです。私は単純なネットワークグラフ(アニメーションも "強制"効果もない)をプレーンDIV(フォーマットされたテキストを含む)をノードとして使用したいと思っています。ノードにはSVGを使用しません。DIVをノードとして使用して単純なd3.jsネットワークグラフをコーディングする方法

div要素は、例えば、次のようになります。

<div id="div1">One</div> 
<div id="div2"><b>Two</b></div> 
<div id="div3"><span style="color: red;">Three</span></div> 
<div id="div4"><p class="someclass">Four</p></div> 

のDIV /ノード間のリンクは、(おそらく擬似JSONである)このようなものになるだろう:どのようになるか

{ 
    "myDIVs":[ 
     {"name":"div1"}, 
     {"name":"div2"}, 
     {"name":"div3"}, 
     {"name":"div4"} 
    ], 
    "myLinks":[ 
     {"source":1,"target":2}, 
     {"source":1,"target":3}, 
     {"source":2,"target":1}, 
     {"source":4,"target":3} 
    ] 
} 

右のD3コード?

+0

はあなたが可能です欲しいものが、なぜあなたの代わりに、ここで 'html'をdivs''と協力したいです:は、私は0ベースの配列インデックスにあなたのリンクを変更しました'svg'ノード?ネットワークグラフにはノード間に線がありますが、これらの線をどのように描くのでしょうか? – Mark

+0

あなたは正しい:ノードが普通の古いDIVである限り、私はSVGであることに気付かないだろう。 (ちょうどそれに応じて私の質問を編集しました。)しかし、少なくともD3を使用して、DIVノードとSVGラインを混在させることが可能かどうかはわかりません。 – JYF

答えて

2

はい、ビルド前のdivとd3の強制レイアウトを混在させてSVGラインを作成することは可能です。 divを絶対的に配置する必要があります。ここでは、HTMLとデータ構造を使った簡単な例を示します。

<!DOCTYPE html> 
 
<html> 
 

 
<head> 
 
    <meta charset='utf-8'> 
 
    <style> 
 
    .node { 
 
     fill: #ccc; 
 
     stroke: #fff; 
 
     stroke-width: 2px; 
 
    } 
 
    
 
    .link { 
 
     stroke: #777; 
 
     stroke-width: 2px; 
 
    } 
 
    </style> 
 
</head> 
 

 
<body> 
 

 
    <div id="div1">One</div> 
 
    <div id="div2"><b>Two</b></div> 
 
    <div id="div3"><span style="color: red;">Three</span></div> 
 
    <div id="div4"> 
 
    <p class="someclass">Four</p> 
 
    </div> 
 

 
    <script src='http://d3js.org/d3.v3.min.js'></script> 
 
    <script> 
 
    var width = 400, 
 
     height = 400; 
 

 
    var data = { 
 
     "myDIVs": [{ 
 
     "name": "div1" 
 
     }, { 
 
     "name": "div2" 
 
     }, { 
 
     "name": "div3" 
 
     }, { 
 
     "name": "div4" 
 
     }], 
 
     "myLinks": [{ 
 
     "source": 0, 
 
     "target": 1 
 
     }, { 
 
     "source": 0, 
 
     "target": 2 
 
     }, { 
 
     "source": 1, 
 
     "target": 0 
 
     }, { 
 
     "source": 3, 
 
     "target": 2 
 
     }] 
 
    }; 
 

 
    var nodes = data.myDIVs, 
 
     links = data.myLinks; 
 

 
    var svg = d3.select('body').append('svg') 
 
     .attr('width', width) 
 
     .attr('height', height); 
 

 
    var force = d3.layout.force() 
 
     .size([width, height]) 
 
     .nodes(nodes) 
 
     .links(links) 
 
     .linkDistance(250) 
 
     .charge(-50); 
 

 
    var link = svg.selectAll('.link') 
 
     .data(links) 
 
     .enter().append('line') 
 
     .attr('class', 'link'); 
 

 
    var node = d3.selectAll('div') 
 
     .data(nodes) 
 
     .each(function(d) { 
 
     var self = d3.select('#' + d.name); 
 
     self.style("position", "absolute"); 
 
     }); 
 

 
    force.on('end', function() { 
 
     node 
 
     .style('left', function(d) { 
 
      return d.x + "px"; 
 
     }) 
 
     .style('top', function(d) { 
 
      return d.y + "px"; 
 
     }); 
 

 
     link.attr('x1', function(d) { 
 
      return d.source.x; 
 
     }) 
 
     .attr('y1', function(d) { 
 
      return d.source.y; 
 
     }) 
 
     .attr('x2', function(d) { 
 
      return d.target.x; 
 
     }) 
 
     .attr('y2', function(d) { 
 
      return d.target.y; 
 
     }); 
 
    }); 
 
    
 
    force.start(); 
 
    for (var i = 0; i < 100; ++i) force.tick(); 
 
    force.stop(); 
 
    </script> 
 
</body> 
 

 
</html>

+0

ありがとうございました。 "力"アニメーションを完全に無効にする方法はありますか?それで、グラフが最終状態になったら?また、DIVが重複しないようにする方法はありますか? – JYF

+0

@JYF、はい、上記のコード変更を参照してください。ただし、ノードの位置を制御したい場合は、フォースレイアウトが最適なレイアウト選択ではないことをお勧めします。おそらく[クラスタレイアウト](https://github.com/mbostock/d3/wiki/Cluster-Layout)が適しています。 – Mark

+0

もう一度ありがとう。私がうまく理解していれば、クラスターレイアウトによって生成された樹状図は、階層内のいくつかのランダム要素を別のランダム要素にリンクすることを許可しません(これは達成したいことです)。あなたのコードによって生成されたDIVのランダムな位置も気に入っています。重複を防ぐ方法や、DIV間の最小距離を設定する方法もなければなりませんが、これらの改良はD3のドキュメントに埋め込まれていると思います...? – JYF

関連する問題