为谷歌折线图动态透视数据

时间:2016-05-12 01:59:40

标签: dynamic google-visualization pivot linechart dataview

我想在同一折线图中显示多年来各国的“人口”。显示的数据基于多选下拉菜单“国家/地区”中的选择。基础数据表有3列:

年,国家,人口
2012年,countryA,33个
2013年,countryA,35个
2014年,countryA,40个
2012年,countryB,65个
2013年,countryB,70个
2014年,countryB,75个
2012年,countryC,15个
2013年,countryC,20个
2014年,countryC,25

我正在尝试从基础数据表创建一个透视数据视图 我正在使用的代码是:

  function drawLineChart() {

      var arr = $('#country').val();

      var lineChartJson = $.ajax({
      url: "../json/lineChart.json",
      dataType: "json",
      async: false
      }).responseText;

    var lineChartData = new google.visualization.DataTable(lineChartJson);
    var view = new google.visualization.DataView(lineChartData);

    var viewCols = [0];

    for(var i = 0; i < arr.length; i++) {

           var viewCols1 = [{
                type: 'number',
                label: arr[i],
                calc: function (dt, row) {
                    return (dt.getValue(row, 1) == arr[i]) ? dt.getValue(row, 2) : null;
                        }
                    }];

                    viewCols = viewCols.concat(viewCols1);

            }

 view.setColumns(viewCols);

var aggCols = [{
                    column: 1,
                    type: 'number',
                    label: view.getColumnLabel(1),
                    aggregation: google.visualization.data.sum
                }];

    for(var i = 2; i < 4; i++) {

            var aggCols1 = [{
                    column: i,
                    type: 'number',
                    label: view.getColumnLabel(i),
                    aggregation: google.visualization.data.sum
                }];

            aggCols = aggCols.concat(aggCols1);
        }

    var pivotedData = google.visualization.data.group(view, [0], aggCols);

但这似乎没有按预期工作,我只是在图表中得到1行,所有国家的值都加起来(虽然我可以看到3个国家的传奇)

另一方面,如果我将View列设置如下,则按预期工作。

    view.setColumns([0, {
    type: 'number',
    label: arr[0],
    calc: function (dt, row) {
        return (dt.getValue(row, 1) == arr[0]) ? dt.getValue(row, 2) : null;
    }
}, {
    type: 'number',
    label: arr[1],
    calc: function (dt, row) {
        // return values of C only for the rows where B = "bar"
        return (dt.getValue(row, 1) == arr[1]) ? dt.getValue(row, 2) : null;
    }
}, {
    type: 'number',
    label: arr[2],
    calc: function (dt, row) {
        return (dt.getValue(row, 1) == arr[2]) ? dt.getValue(row, 2) : null;
    }
}]);

循环中出了什么问题?在我创建View Columns的循环中,“concat”有问题吗?我也通过使用console.log看到了viewCols数组,它似乎有正确的元素

我试图按照以下帖子: Creating pivoted DataView from existing google charts DataTable object

2 个答案:

答案 0 :(得分:1)

问题与范围

有关 {p> arr[i]undefined

范围内calc: function (dt, row)

这是另一种转动数据的方法......

google.charts.load('current', {
  callback: function () {
    var arr = [
      'countryA',
      'countryB',
      'countryC'
    ];

    var lineChartData = google.visualization.arrayToDataTable([
      ['Year', 'Country', 'Population'],
      [2012,'countryA',33],
      [2013,'countryA',35],
      [2014,'countryA',40],
      [2012,'countryB',65],
      [2013,'countryB',70],
      [2014,'countryB',75],
      [2012,'countryC',15],
      [2013,'countryC',20],
      [2014,'countryC',25]
    ]);

    // sort by year
    lineChartData.sort([{column: 0}]);

    // get unique countries
    var countryGroup = google.visualization.data.group(
      lineChartData,
      [1]
    );

    // build country data table
    var countryData = new google.visualization.DataTable({
      cols: [
        {label: 'Year', type: 'number'},
      ]
    });

    // add column for each country
    for (var i = 0; i < countryGroup.getNumberOfRows(); i++) {
      countryData.addColumn(
        {label: countryGroup.getValue(i, 0), type: 'number'}
      );
    }

    // add row for each year / country
    var rowYear;
    var rowIndex;
    for (var i = 0; i < lineChartData.getNumberOfRows(); i++) {
      if (rowYear !== lineChartData.getValue(i, 0)) {
        rowYear = lineChartData.getValue(i, 0);
        rowIndex = countryData.addRow();
        countryData.setValue(rowIndex, 0, rowYear);
      }
      for (var x = 1; x < countryData.getNumberOfColumns(); x++) {
        if (countryData.getColumnLabel(x) === lineChartData.getValue(i, 1)) {
          countryData.setValue(rowIndex, x, lineChartData.getValue(i, 2));
        }
      }
    }

    // draw agg table
    new google.visualization.ChartWrapper({
      chartType: 'Table',
      containerId: 'table-div',
      dataTable: countryData
    }).draw();

    // draw line chart
    new google.visualization.ChartWrapper({
      chartType: 'LineChart',
      containerId: 'chart-div',
      dataTable: countryData
    }).draw();
  },
  packages: ['corechart', 'table']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="table-div"></div>
<div id="chart-div"></div>

答案 1 :(得分:0)

我可以用上面的代码找出问题。

&#34;计算值&#34;是循环中的回调函数。所以只有循环变量的最后一个值&#34; i&#34;在循环中可见。

使用包装函数修复它:

  for(var i = 0; i <= arr.length; i++)(function(i) {
           var viewCols1 = [{
                type: 'number',
                label: arr[i],
                calc: function (dt, row) {
                    return (dt.getValue(row, 1) == arr[i]) ? dt.getValue(row, 2) : null;
                        }
                    }];
        viewCols = viewCols.concat(viewCols1);  
            })(i);