2017-07-07 59 views
2

我试图用下面的代码递归地创建多个Google图表。我使用AJAX来获取图表数据并将其存储在数组histogramData中。在Javascript中递归地创建多个Google图表

使用此代码,我可以创建多个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-inclosing – dlaliberte

回答

1

第一,setOnLoadCallback只应每个页面加载调用一次,
一旦发生火灾,你可以画出许多图表需要...

你也可以取决于callback知道什么时候该页面已准备就绪,
代替 - >$(document).ready - 或者类似的东西...

因为如此,建议装载谷歌第一之前别的,
然后使用AJAX来获取数据,然后绘制图表...

尝试类似的设置如下,放置callbackload声明...

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调用总是适用于最近的加载调用,在调用回调之前等待加载它的资源。两者现在都会返回Promises,因此您也可以google.charts.load(...),然后(drawChart1)。然后(drawChart2)。 – dlaliberte