2016-07-17 15 views
0

JavascriptとD3.jsが新しく、forループでサークルエレメントを連続的に変更しようとしています。 これは毎秒円の半径を変更することを意図していますが、半径はちょうど50にジャンプし、26から49を無視します。forループがD3.jsで機能しない

ここに私のコードです。

<!DOCTYPE html> 
<meta charset="utf-8"> 
<style> 

</style> 
<body> 
<script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script> 
<script src="//d3js.org/topojson.v1.min.js"></script> 
<script> 
    var width = 960, 
      height = 1160; 
    var svg = d3.select("body").append("svg") 
      .attr("width", width) 
      .attr("height", height); 

    svg.append("circle").attr("cx", 100).attr("cy", 100).attr("r", 25).style("fill", "purple").attr('id','cc'); 

    for(i=26;i<=50;i++){ 
     var now=d3.select('#cc'); 
     now.transition().duration(1000).attr("r",i); 
    } 
</script> 

答えて

2

for(i=26;i<=50;i++){ 
    var now=d3.select('#cc'); 
    now.transition().duration(1000).attr("r",i); 
} 

は、forループを待つことになることを考えてはいけませんi=26は、i=27に移動する前に終了に遷移します。実際にはi=26の文now.transition().duration(1000).attr("r",i);を呼び出し、次にループの次の繰り返しに直ちに移動します。 i=26i=50の間の時間差は無限である(速度はプロセッサの速度によってのみ制限されています。これは現在のGHzです)、すべてのトランジションが同時に呼び出されると考えることができ、最後の1つは、すぐにが観察されます。

これを行う1つの方法は、すべての反復がほぼ同じ瞬間に呼び出されるため、各呼び出しの前に時間遅延を設定し、その時間遅延が絶対的である必要があることです。たとえば、

0秒後に最初の文が呼び出されます。
2番目の文は1秒後に呼び出されます。
3番目のステートメントは2秒後に呼び出されます。

この場合に限り、コールの間に1秒の相対的な差が表示されます。

もう1つのアプローチは、setTimeout()ルーチンを使用して再帰的に行うことです。 この方法が推奨されます。代わりに、複数のトランジションを作成するか、半径をトゥイーンする遅延をいじりの

var i = 26; 

function myLoop() { 
    setTimeout(function() { 
     var now=d3.select('#cc'); 
     now.transition().duration(1000).attr("r",i); 
     i++; 
     if (i < 50) { 
      myLoop(); 
     } 
    }, 1000) // change this time (in milliseconds) to whatever you desire 
} 

myLoop(); // first call 
+0

説明してくれてありがとうございました。私は今どこに問題があるのか​​理解しています:) –

+0

嬉しいです。あなたはStackOverflowがどのように働くので、この回答をupvoting/acceptすることを検討するかもしれません:) –

+0

こんにちは、私はすでにupvotedして、それは私に言ったフィードバック!評判が15未満の人の投票が記録されますが、公開されている投稿のスコアは変更されません。そして、私は左の緑の√をクリックしました、それは受け入れのために正しいですか? –

0

問題は、forループがすべての変更をただちに反復していることです。 transitionへの各呼び出しの間に1秒間待つ必要があります。おそらくd3は、現在の移行が終了した後で何かをするより良い方法がありますが、このような何かがうまくいくはずですか?

function changeRadius(i) { 
    d3.select('#cc').transition().duration(1000).attr("r", i); 

    // "loop" by calling ourselves 1 second later with the next radius 
    if (i < 50) { 
     window.setTimeout(function() { 
      changeRadius(i + 1); 
     }, 1000); 
    } 
} 
// first change 
changeRadius(26); 

the d3 documentationを見て、私はこれが働くかもしれないと思う:

あなたが言うのJavaScriptでは、
var current = d3.select('#cc'); 
for (var i = 26; i <= 50; i++) { 
    current = current.transition().duration(1000).attr("r", i); 
} 
+0

これは機能します。ありがとうございました! –

0

Demo

d3.select('#cc') 
    .transition() 
    .duration(25*1000) 
    .attrTween('r', function() { 
     return d3.interpolateNumber(25, 50) 
    }) 
+0

ありがとう!できます –

関連する問題