2012-01-18 4 views
0

私は3つの円グラフを隣り合わせに配置するためにGoogleグラフの例を修正しようとしていますが、それをうまく機能させることはできますが、論理的に私が残すべきだと感じるカウンターを減らす必要がある。誰かがこの作業用のコードスニペットを見て、ループカウンタを手動で減らす必要がある理由を説明すると感謝します(コメントは参照)。コールバック関数内のカウンタの振る舞いによってひどくなる

<html> 
    <head> 
    <script type="text/javascript" src="https://www.google.com/jsapi"></script> 
    <script type="text/javascript"> 
     google.load("visualization", "1", {packages:["corechart"]}); 
     var num_charts = 3; 
     var userdata = new Array(num_charts); 
     var fn_array = new Array(num_charts); 

     for (var i=0; i<num_charts; i++) 
     { 
     userdata[i] = new Array(
      ['Work',  1 + Math.floor(Math.random()*10)], 
      ['Eat',  1 + Math.floor(Math.random()*10)], 
      ['Commute', 1 + Math.floor(Math.random()*10)], 
      ['Watch TV', 1 + Math.floor(Math.random()*10)], 
      ['Sleep',  1 + i ] 
     ); 

     fn_array[i] = function() { 
      // Need to decrement i for it to work, but why??? The value 
      // of i inside this function is one greater than the corresponding 
      // fn_array index, but I don't see why. 
      i--; 

      var data = new google.visualization.DataTable(); 
      data.addColumn('string', 'Task'); 
      data.addColumn('number', 'Hours per Day'); 
      data.addRows(userdata[i]); 

      var options = { 
      width: 400, height: 300, 
      title: 'Hello ' + i 
      }; 

      var chart = new google.visualization.PieChart(document.getElementById('chart_div'+i)); 
      chart.draw(data, options); 
     } 
     } 

     for (var j=0; j<num_charts; j++) 
     google.setOnLoadCallback(fn_array[j]); 

    </script> 
    </head> 
    <body> 
    <span id="chart_div0"></span> 
    <span id="chart_div1"></span> 
    <span id="chart_div2"></span> 
    </body> 
</html> 

答えて

0

あなたは、コールバック内で同じ変数を使用しているため、コールバックのすべての呼び出しは、その値が毎回異なることが原因となり、コールバック内でその値を下げ、同じ値を持つことになります。 javascriptはシングルスレッド(ウェブワーカーを数えない)なので、これは「きれい」です。あなたがそれで厄介になった場合は、簡単にしてください:

for (var i=0; i<num_charts; i++) 
{ 
    userdata[i] = new Array(
    ['Work',  1 + Math.floor(Math.random()*10)], 
    ['Eat',  1 + Math.floor(Math.random()*10)], 
    ['Commute', 1 + Math.floor(Math.random()*10)], 
    ['Watch TV', 1 + Math.floor(Math.random()*10)], 
    ['Sleep',  1 + i ] 
); 

    fn_array[i] = (function(local_i){ 
    return function() { 
     // Need to decrement i for it to work, but why??? The value 
     // of i inside this function is one greater than the corresponding 
     // fn_array index, but I don't see why. 
     //i--; 

     var data = new google.visualization.DataTable(); 
     data.addColumn('string', 'Task'); 
     data.addColumn('number', 'Hours per Day'); 
     //data.addRows(userdata[i]); 
     data.addRows(userdata[local_i]); 

     var options = { 
     width: 400, height: 300, 
     //title: 'Hello ' + i 
     title: 'Hello ' + local_i 
     }; 

     //var chart = new google.visualization.PieChart(document.getElementById('chart_div'+i)); 
     var chart = new google.visualization.PieChart(document.getElementById('chart_div'+local_i)); 
     chart.draw(data, options); 
    } 
    })(i); 
} 
+0

これは間違いですが、本当に厄介です。ループの内部全体を無名関数にラップし、iをlocal_iではなくiとして渡すことは明らかです。 –

+0

私はちょうど最小限の変更を提案しました。実際には 'fn_array'が他の場所で使われていなければ、それは避けられ、2番目のループのコードは最初のループの中に置かれます。 – Prusse

+0

説明と解決策をありがとう、Prusse。正気が回復する。 –

関連する問題