如何在同一页上添加两个谷歌图表?

55

我做了什么

我在页面头部添加了Google图表。这将返回一张图表图片。

我需要做什么

我只需要在同一页上添加第二个图表。

问题

第二个图表的代码被忽略了。我很大程度上怀疑这是因为我错误地组合了每个图表的代码。

代码

第一个图表(折线图):

    <!--Load the AJAX API-->
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">

  // Load the Visualization API and the piechart package.
  google.load('visualization', '1.0', {'packages':['corechart']});

  // Set a callback to run when the Google Visualization API is loaded.
  google.setOnLoadCallback(drawChart);

  // Callback that creates and populates a data table,
  // instantiates the pie chart, passes in the data and
  // draws it.
  function drawChart() {

    var data = new google.visualization.DataTable();
    data.addColumn('string', 'Month');
    data.addColumn('number', 'Apples');
    data.addColumn('number', 'Oranges');
    data.addRows([
      ['Oct 11', 20, 0],
      ['Nov 11', 0, 0],
      ['Dec 12',  0, 20],
      ['Jan 12', 0, 10],
      ['Feb 12', 0, 10],
      ['March 12', 10, 10]
    ]);

    // Set chart options
    var options = {'width':960,
                   'height':300};

    // Instantiate and draw our chart, passing in some options.
    var chart = new google.visualization.LineChart(document.getElementById('line_chart'));
    chart.draw(data, options);
  }

</script>

第二个图表(饼状图):

    <!--Load the AJAX API-->
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">

  // Load the Visualization API and the piechart package.
  google.load('visualization', '1.0', {'packages':['corechart']});

  // Set a callback to run when the Google Visualization API is loaded.
  google.setOnLoadCallback(drawChart);

  // Callback that creates and populates a data table,
  // instantiates the pie chart, passes in the data and
  // draws it.
  function drawChart() {

    // Create the data table.
    var data = new google.visualization.DataTable();
    data.addColumn('string', 'Topping');
    data.addColumn('number', 'Slices');
    data.addRows([
      ['Mushrooms', 3],
      ['Onions', 1],
      ['Olives', 1],
      ['Zucchini', 1],
      ['Pepperoni', 2]
    ]);

    // Set chart options
    var options = {'title':'How Much Pizza I Ate Last Night',
                   'width':400,
                   'height':300};

    // Instantiate and draw our chart, passing in some options.
    var chart = new google.visualization.PieChart(document.getElementById('chart_div'));
    chart.draw(data, options);
  }
</script>

每个图表都使用带有唯一ID的容器div在页面中调用:

<div id="chart_div"></div>

我的问题

我该如何将这两个代码块拼接在一起?我尝试过复制drawChart()函数并指定唯一的函数名称和变量名,但没有成功。


1
你应该将你的解决方案发布为一个答案,而不是编辑你的问题。回答自己的问题完全没有问题。 - Kevin Reid
1
@Kevin Reid - 我已将解决方案重新发布为答案。我需要等待两天才能选择自己的答案作为被接受的答案。感谢您的提示。 - Dominor Novus
我遇到了一个问题,后来发现是因为我的 div 元素被写成了 <div ... /> 而不是显式的开始/结束元素 <div ...></div>。如果其他人在渲染多个图表时遇到问题,请检查一下这个。 - dviljoen
最佳简易解决方案 - Mahesh G
9个回答

71

解决方案

现在我已经有了一个可行的解决方案。它涉及区分哪些部分需要复制,哪些不需要复制(正如Oofpez所建议的)。对于每个图表,数据、选项和图表变量都在一个drawChart()函数中定义。

这里是一个可行的示例(只需将其复制粘贴到HTML文档中):

...此示例进一步演示了如何组合不同类型的图表,例如饼图和折线图...

<html>
      <head>
        <!--Load the AJAX API-->
        <script type="text/javascript" src="https://www.google.com/jsapi"></script>
        <script type="text/javascript">

          // Load the Visualization API and the piechart package.
          google.load('visualization', '1.0', {'packages':['corechart']});

          // Set a callback to run when the Google Visualization API is loaded.
          google.setOnLoadCallback(drawChart);

          // Callback that creates and populates a data table,
          // instantiates the pie chart, passes in the data and
          // draws it.
          function drawChart() {

            // Create the data table.
            var data = new google.visualization.DataTable();
            data.addColumn('string', 'Topping');    
            data.addColumn('number', 'Slices');
            data.addRows([
              ['Mushrooms', 3],
              ['Onions', 1],
              ['Olives', 1],
              ['Zucchini', 1],
              ['Pepperoni', 2]
            ]);
            // Create the data table.
            var data2 = new google.visualization.DataTable();
            data2.addColumn('string', 'Topping');
            data2.addColumn('number', 'Slices');
            data2.addRows([
              ['Mushrooms', 3],
              ['Onions', 1],
              ['Olives', 15],
              ['Zucchini', 1],
              ['Pepperoni', 2]
            ]);

            var data3 = new google.visualization.DataTable();
            data3.addColumn('string', 'Year');
            data3.addColumn('number', 'Sales');
            data3.addColumn('number', 'Expenses');
            data3.addRows([
              ['2004', 1000, 400],
              ['2005', 1170, 460],
              ['2006',  860, 580],
              ['2007', 1030, 540]
            ]);

            // Set chart options
            var options = {'title':'How Much Pizza I Ate Last Night',
                           'width':400,
                           'height':300};
            // Set chart options
            var options2 = {'title':'How Much Pizza You Ate Last Night',
                           'width':400,
                           'height':300};
            // Set chart options
            var options3 = {'title':'Line chart',
                           'width':400,
                           'height':300};

            // Instantiate and draw our chart, passing in some options.
            var chart = new google.visualization.PieChart(document.getElementById('chart_div'));
            chart.draw(data, options);
            var chart2 = new google.visualization.PieChart(document.getElementById('chart_div2'));
            chart2.draw(data2, options2);
            var chart3 = new google.visualization.LineChart(document.getElementById('chart_div3'));
            chart3.draw(data3, options3);

          }
        </script>
      </head>

      <body>
        <!--Divs that will hold the charts-->
        <div id="chart_div"></div>
        <div id="chart_div2"></div>
        <div id="chart_div3"></div>
      </body>
    </html>

1
这只有在您知道任何给定时间将有多少图表时才有效。 - avoliva
1
@avoliva 请查看 https://dev59.com/x5Lea4cB1Zd3GeqP6sm1 - user5037156

14
基本上,您可以使用函数drawChart来包装参数,并传递如下所示:
function drawChart(chartType, containerID, dataArray, options)

call google.setOnLoadCallback(function() {
    drawChart('barChart', 'div_id_1', test_array, null);
}); 

您可以根据需要多次呈现图形:

var test_array = [
    ['Name', 'Count-A', 'Count-B'],
    ['Test-A', 4, 3],
    ['Test-B', 1, 2],
    ['Test-C', 3, 4],
    ['Test-D', 2, 0],
    ['Test-E', 2, 5]
];

google.load("visualization", "1", {packages: ["corechart",'table']});

google.setOnLoadCallback(function() {
    drawChart('barChart', 'div_id_1', test_array, null);
});

google.setOnLoadCallback(function() {
    drawChart('columnChart', 'div_id_2', test_array, null);
});


function drawChart(chartType, containerID, dataArray, options) {
    var data = google.visualization.arrayToDataTable(dataArray);
    var containerDiv = document.getElementById(containerID);
    var chart = false;

    if (chartType.toUpperCase() == 'BARCHART') {
        chart = new google.visualization.BarChart(containerDiv);
    }
    else if (chartType.toUpperCase() == 'COLUMNCHART') {
        chart = new google.visualization.ColumnChart(containerDiv);
    }
    else if (chartType.toUpperCase() == 'PIECHART') {
        chart = new google.visualization.PieChart(containerDiv);
    }
    else if (chartType.toUpperCase() == 'TABLECHART')
    {
        chart = new google.visualization.Table(containerDiv);
    }

    if (chart == false) {
        return false;
    }

    chart.draw(data, options);
}

这是我选择的路线,但发现它无法与新的 Material Line 图表配合使用。在经典模式下运行良好。在 Material 模式下,每次刷新时显示的图表都不同 :) - Wyrmwood
一个JSFiddle的例子会很有帮助。 - 3kstc

5

2
我知道这是谷歌的一个bug。这节省了我几个小时的时间。 - Richard Nienaber

5

基于 @Dominor 的回答,但如果您正在从任意位置注册图表,只需构建一个函数堆栈,在回调函数中执行,可以像这样实现:

google.setOnLoadCallback(drawChart);

// Callback that creates and populates a data table,
// instantiates the pie chart, passes in the data and
// draws it.
googleChartStack = [];

function drawChart() {
    for (var i = googleChartStack.length - 1; i >= 0; i--) {
        googleChartStack[i]();
    }
}

然后,在模板的其他地方,您可以将其推送到此堆栈中。在我的示例中,我正在迭代一些模板片段。
<script>
  googleChartStack.push(function() {
    var data = google.visualization.arrayToDataTable([
      ['A', 'B'],
      ['A', 1],
      ['B', 2]
    ]);

    var options = {
      title: 'none',
      legend: 'none'
    };

    var chart = new google.visualization.PieChart(document.getElementById("relevant-id"));
    chart.draw(data, options);          
  })
</script>

这很接近我最终要做的事情。我本来是要在这里发布我的工作,但我会点赞你的,因为它捕捉到了同样的精神。构建一个Google图表堆栈,然后一次性加载它们所有。 - crush

4

在上面的回答中,仅添加了饼图包。要在同一页上打印饼图和折线图,我们还必须包括线条包:

google.load('visualization', '1.0', {'packages':['corechart','line']});

完整代码如下:

      // Load the Visualization API and the piechart package.
      google.load('visualization', '1.0', {'packages':['corechart','line']});

      // Set a callback to run when the Google Visualization API is loaded.
      google.setOnLoadCallback(drawChart);

      // Callback that creates and populates a data table,
      // instantiates the pie chart, passes in the data and
      // draws it.
      function drawChart() {

        // Create the data table.
        var data = new google.visualization.DataTable();
        data.addColumn('string', 'Topping');    
        data.addColumn('number', 'Slices');
        data.addRows([
          ['Mushrooms', 3],
          ['Onions', 1],
          ['Olives', 1],
          ['Zucchini', 1],
          ['Pepperoni', 2]
        ]);
        // Create the data table.
        var data2 = new google.visualization.DataTable();
        data2.addColumn('string', 'Topping');
        data2.addColumn('number', 'Slices');
        data2.addRows([
          ['Mushrooms', 3],
          ['Onions', 1],
          ['Olives', 15],
          ['Zucchini', 1],
          ['Pepperoni', 2]
        ]);

        var data3 = new google.visualization.DataTable();
        data3.addColumn('string', 'Year');
        data3.addColumn('number', 'Sales');
        data3.addColumn('number', 'Expenses');
        data3.addRows([
          ['2004', 1000, 400],
          ['2005', 1170, 460],
          ['2006',  860, 580],
          ['2007', 1030, 540]
        ]);

        // Set chart options
        var options = {'title':'How Much Pizza I Ate Last Night',
                       'width':400,
                       'height':300};
        // Set chart options
        var options2 = {'title':'How Much Pizza You Ate Last Night',
                       'width':400,
                       'height':300};
        // Set chart options
        var options3 = {'title':'Line chart',
                       'width':400,
                       'height':300};

        // Instantiate and draw our chart, passing in some options.
        var chart = new google.visualization.PieChart(document.getElementById('chart_div'));
        chart.draw(data, options);
        var chart2 = new google.visualization.PieChart(document.getElementById('chart_div2'));
        chart2.draw(data2, options2);
        var chart3 = new google.visualization.LineChart(document.getElementById('chart_div3'));
        chart3.draw(data3, options3);

      }
    </script>
  </head>

  <body>
    <!--Divs that will hold the charts-->
    <div id="chart_div"></div>
    <div id="chart_div2"></div>
    <div id="chart_div3"></div>
  </body>
</html>

4
也许当你指定时,

google.setOnLoadCallback(drawChart);

两次覆盖第一次的回调事件?

仅仅是一个猜测...


2
谢谢。我明白了。我找到了避免两次使用那个函数的方法。请参考我的原始帖子,以获取完整的解决方案说明。 - Dominor Novus

1
你想要做的是为每个图表编写一个函数,然后执行。
google.setOnLoadCallback(initialize);

并且需要对每个函数进行初始化调用以创建图表。这样做比在一个函数中绘制多个图表要干净得多。它还将有助于调试。


0
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
  google.load("visualization", "1.1", {packages:["bar"]});
  google.setOnLoadCallback(drawChart);
  function drawChart() {
    var data = google.visualization.arrayToDataTable([
      ['Day/Month', 'Sales', 'Goal'],
      ['Daily', 33549.17,47328.04],
      ['M-T-D', 96114.18,141984.12]
    ]);


    var data1 = google.visualization.arrayToDataTable([
      ['Day/Month', 'Bookings', 'Goal'],

      ['Daily', 37991.21,47659.09],

      ['M-T-D', 95610.47,142977.27]

    ]);
   var options = {
  colors: ['#e0aa0e', '#ecbb6e','green'],
      width: 800,
      chart: {
        title: 'Test Company Sales',
        subtitle: 'Sales vs Goal',
      }
    };
    var options1 = {
  colors: ['#e0440e', '#ec8f6e','green'],
      width: 800,
      chart: {
        title: 'Test Company Bookings',
        subtitle: 'Bookings',
      }
    };

    var chart = new google.charts.Bar(document.getElementById('sales'));
    chart.draw(data, options);
    var chart2 = new google.charts.Bar(document.getElementById('bookings'));

    chart2.draw(data1, options1);
  }
</script>





  <div style="display: table; width: 100%;">
      <div style="display: table-row">
           <div id="sales" style="width: 900px; height: 500px; display: table-cell;"></div>
          <div id="bookings" style="width: 900px; height: 500px; display: table-cell;"></div>
     </div>
</div>

1
我无法让上述代码同时呈现两个图形。 - stan

0

步骤1.(将id curve_chart更改为其他名称(例如ajay))

<body>
<div id="ajay" style="width: 900px; height: 500px"></div>

步骤2.(将此ID分配给脚本元素中的图表)。

    var chart = new google.visualization.LineChart(document.getElementById('ajay'));

    chart.draw(data, options);
  }
</script>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接