2016-04-18 13 views
5

igraphを使用して安定した力の有向グラフの位置を事前に計算し、それらをd3.jsグラフに渡そうとしています。これは私が使用するデータセットのサイズによるものです。つまり、クライアント側で完全な力の計算が行われても、フリーズしないようにクライアントに依存することはできません。私はJSON形式でポジションを持ち、d3.jsで便利なようにリニアスケールを使用しました。D3.jsのノードの事前計算を計算して設定します

var positions = 
{"positions": [{"x":"-68.824367374", "y": "-6.10824525755"}, 
{"x":"-80.8080803911", "y": "-3.38997541264"}, 
{"x":"6.75334817585", "y": "-49.6040729697"}, 
{"x":"14.6608797291", "y": "-81.8897019921"}, 
.... 
var force = d3.layout.force() 
       .charge(-100) 
       .linkDistance(3) 
       .size([width, height]) 
       .nodes(data.nodes) 
       .links(data.links) 
       .start(); 

var posX = d3.scale.linear() 
       .range([0,960]) 
       .domain([-125,120]); 

var posY = d3.scale.linear() 
       .range([0,500]) 
       .domain([-125,125]); 

これが私のやり方です。私はpxとpyで実験しましたが、結果は同じです。これは、このコードが実行されなかったかのようです。下の図のconsole.logを投げた場合、値は印刷されません。これは、私がこのコードをどこに置くかに関わらず、力を始める前か後かにかかわらずです。

force.on("start", function() { 
        node 
        .data(positions.positions) 
        .attr("cx", function(d) { 
          console.log(posX(d.x)); 
          return posX(d.x); 
         }) 
         .attr("cy", function(d) { 
          return posY(d.y); 
         }) 
       }); 

なぜ起動イベントが自分のノードの初期位置を設定しないのですか?彼らはまだランダムに初期化されているようです。あるいは、d3.js force directedグラフの安定した状態を事前に計算する良い方法は何ですか?私はPhantomjsでやってみたが、あきらめた。

私の質問を読んでいただきありがとうございます!

EDITここ

はダウン易しく書き直さ例です。https://jsfiddle.net/xp0zgqes/ あなたはそれを数回実行し、ノードの開始位置に注意を払う場合は、彼らがランダムに初期化されて見ることができます。

+0

あなたは自分の持っているものを使って作業フィドルを提供できますか? – iulian

+0

修正された質問をご覧ください。 –

+0

本当に、誰もいませんか?私は好奇心が強いです... –

答えて

4

本当に自分の質問に答えるのが好きではありませんが、これは本当に便利だと思います。まず、最初の位置データがノード/リンクデータとは異なるデータオブジェクトから来ている場合は、これは私の場合のみです)、結合すれば2つのデータソースにバインドする必要がなくなります。私よりスマートになり、xとyの位置を持つ元のjsonオブジェクトを作成するだけです)。私の場合:

for (var i = 0; i < data.nodes.length; i++){ 
        data.nodes[i].x = posX(positions.positions[i].x); 
        data.nodes[i].y = posY(positions.positions[i].y); 
        data.nodes[i].newAttribute = value; 
       } 

JSONの魔法のおかげで、新しい属性をデータに簡単に追加できます。あなたのノードを修正したい場合。

問題はforce.start()コールであるようです。そのような力を初期化するときに呼び出さ場合:

var force = d3.layout.force() 
       .charge(-100) 
       .linkDistance(3) 
       .size([width, height]) 
       .nodes(data.nodes) 
       .links(data.links) 
       .start(); 

レイアウトがランダムにデフォルトでノードを初期化します。私がそれを回避する方法は、チックイベントを追加し、後で力を開始することです。

var force = d3.layout.force() 
        .charge(-100) 
        .linkDistance(3) 
        .size([width, height]) 
        .nodes(data.nodes) 
        .links(data.links) 
        .on("tick", tick); 

        force.start(); //Note, not chained 


//Standard code that goes in the on.tick event 
function tick() { 
    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; }); 

    node.attr("cx", function(d) { return d.x; }) 
     .attr("cy", function(d) { return d.y; }); 
} 

そしてVoilà!私たちは今、jsonから初期の位置を設定した、完全に機能的な力の有向グラフを持っています。

作業中:https://jsfiddle.net/zbxbzmen/

関連する問題