2017-07-07 26 views
2

以下のコードを使用して複数のGoogle Chartsを再帰的に作成しようとしています。私はAJAXを使用してチャートデータを取得し、配列histogramDataに格納しています。Javascriptで複数のGoogle Chartsを再帰的に作成する

このコードでは、複数のi_histogramグラフを作成できますが、各ループの相互作用時に、前のグラフに最後のグラフが上書きされているようです。

HTMLコード:

<div id="histogramCharts"></div> 

Javascriptコード:

var histogramChartElement = document.getElementById('histogramCharts'); 
// remove histogram chart element children 
while (histogramChartElement.hasChildNodes()) { 
    histogramChartElement.removeChild(histogramChartElement.childNodes[0]); 
} 

for (var i = 0; i < histogramLabels.length; i++) { 
    var label = histogramLabels[i]; 
    var node = document.createElement('div'); 

    node.setAttribute('id', i + '_histogram'); 

    histogramChartElement.appendChild(node); 

    var dataTable = new google.visualization.DataTable(); 
    dataTable.addColumn('string', 'A'); 
    dataTable.addColumn('number', 'B'); 
    dataTable.addRows(histogramData[i]); 

    google.charts.setOnLoadCallback(function() { 
     var options = { 
      title: histogramLabels[i], 
      legend: {position: 'none'}, 
      histogram: {bucketSize: 0.1} 
     }; 
     var histogramChart = new google.visualization.Histogram(node); 
     histogramChart.draw(dataTable, options); 
    }); 
} 

私はこの結果を得た:

<div id="histogramCharts"> 
    <div id="0_histogram"></div> 
    <div id="1_histogram"></div> 
    <div id="2_histogram"> 
     <div style="position: relative;">....</div> 
    </div> 
</div> 
+1

ループ内の最後の値だけが適用される理由は、あなたのforループが期待したことをしていないということです。ループのたびにノードのような変数が変更され、グラフを作成している内部関数は内部関数が作成されたときの値ではなく、それらの変数を参照しています。したがって、ノード変数には、各グラフが作成されるまでに最後の値が常に含まれます。これは、JavaScriptを使用する人々が頻繁に抱える問題です。 https://stackoverflow.com/questions/2828718/javascript-scope-problem-when-lambda-function-refers-to-a-variable-in-enclosing – dlaliberte

答えて

1

最初に、setOnLoadCallback
、一度、ページの読み込みごとに呼び出される必要があります一度発生すると、次のように多くのグラフを描画できます。必要に応じて...

あなたはまた、ページの準備ができると知ってcallbackに依存することができ、
代わりに - >$(document).ready - または似たような...など

、お勧めのロード最初にGoogle以下のように、何か他のものの前に、
はその後、その後、グラフを描き、データを取得するために、AJAXを使用して...

... load文で callbackを配置し、同様の設定を試してみてください
google.charts.load('current', { 
    callback: getData, 
    packages:['corechart'] 
}); 

function getData() { 
    $.ajax({ 
    url: '...', 
    }).done(drawCharts); 
} 

function drawCharts(data) { 

    // use data to build histogramData 

    var histogramChartElement = document.getElementById('histogramCharts'); 
    // remove histogram chart element children 
    while (histogramChartElement.hasChildNodes()) { 
     histogramChartElement.removeChild(histogramChartElement.childNodes[0]); 
    } 

    for (var i = 0; i < histogramLabels.length; i++) { 
     var label = histogramLabels[i]; 
     var node = document.createElement('div'); 

     node.setAttribute('id', i + '_histogram'); 

     histogramChartElement.appendChild(node); 

     var dataTable = new google.visualization.DataTable(); 
     dataTable.addColumn('string', 'A'); 
     dataTable.addColumn('number', 'B'); 
     dataTable.addRows(histogramData[i]); 

     var options = { 
      title: histogramLabels[i], 
      legend: {position: 'none'}, 
      histogram: {bucketSize: 0.1} 
     }; 
     var histogramChart = new google.visualization.Histogram(node); 
     histogramChart.draw(dataTable, options); 
    } 
} 
+1

こちらが役立つことを願って、[こちらは動作例です](https ://stackoverflow.com/a/42725725/5090771)。 – WhiteHat

+0

最近のバージョンでは、google.charts.loadとgoogle.charts.setOnLoadCallbackを複数回呼び出すことができます。 setOnLoadCallbackの呼び出しは常に最新のロード呼び出しに適用され、コールバックを呼び出す前にそのリソースがロードされるのを待ちます。両方とも約束を返すので、あなたもやることができます。 google.charts.load(...)。then(drawChart1).then(drawChart2)。 – dlaliberte

関連する問題