从电子表格数据的单列创建条形图

时间:2015-11-06 11:45:18

标签: google-apps-script google-sheets google-visualization

我有一个包含分类数据列的大型电子表格。我想为每列创建一个条形图,表示该列中不同值的计数。我尝试使用Google Apps脚本自动完成此过程,但我得到的结果非常错误。

以下是我正在使用的代码

function myFunction() {

var responseSpreadSheet = SpreadsheetApp.openByUrl("https://mySpreadsheetLink")
                          .getActiveSheet();
Logger.log(responseSpreadSheet.getName());

var titles = responseSpreadSheet.getRange(1, 4, 1, 25).getValues(); 

var barChart = responseSpreadSheet.newChart()
               .setChartType(Charts.ChartType.BAR)
               .setOption('title', titles[0][0])
               .addRange(responseSpreadSheet.getRange("D2:D57"))
               .setPosition(5, 5, 0,0)
               .build();


responseSpreadSheet.insertChart(barChart);
}

以下是包含嵌入式条形图的电子表格:

embedded bar chart

期望的结果将是这个

desired outcome

如何在我的列上创建此类图表?

1 个答案:

答案 0 :(得分:6)

EmbeddedCharts不公开电子表格图表可用的所有功能,也不公开Visualization API的所有功能。您在此处遇到的具体限制:

  • EmbeddedCharts仅将电子表格范围用于数据源。
  • 表单UI中支持的自动聚合设置无法以编程方式提供。

    所需的图表并不是简单地绘制单列数据,而是通过聚合从中有效地生成表格。当您选择单列文本单元格时,默认图表将是标题为" [列标题]"的计数的条形图,其中"聚合列"启用,像这样:

    settings

如何通过脚本

获得相同的结果

让我们说A列由受访者列表组成。最喜欢的宠物:

Favourite Pet
-------------
Cat
Cat
Dog
Alpaca
Budgie
Budgie
Cat
Dog
Hamster
Cat
Gerbil
Rabbit
Dog
Rabbit
Cat
Dog

总和汇总数据如下:

Favourite Pet   Count
---------------------
Cat               5
Dog               4
Alpaca            1
Budgie            2
Hamster           1
Gerbil            1
Rabbit            2

选项1:电子表格功能

由于EmbeddedCharts的限制,要显示的数据必须位于"表",范围或范围集中,因此您需要满足该要求。一种方法是使用表格QUERY()功能,如Counting number of occurrences in column?

=QUERY({A:A,A:A},"select Col1, count(Col2) where Col1 != '' group by Col1 label count(Col2) 'Count'",1)

要以编程方式插入图表,请使用现有脚本中上述QUERY生成的范围。

选项2:全部按脚本

脚本需要生成类似的聚合数据表。 JavaScript中有很多例子,例如Counting the occurrences of JavaScript array elements。有了这个,以及来自Google Spreadsheet Script - How to Transpose / Rotate Multi-dimensional Array?的数组转置函数,我们可以将它们组合在一起:

/**
 * Generate a table with summed categories (counts).
 *
 * @param {Object[][]} data   Single column of values to be counted.
 *
 * @returns {Object[][]}      Two columns, categories and counts
 */
function sumAggregate( data ) {
  // transpose spreadsheet column; we want just column 0.
  var arr = transpose( data )[0];

  // Magically aggregate array items. From https://stackoverflow.com/a/28832203/1677912
  var agg = arr.reduce(function(countMap, word) {countMap[word] = ++countMap[word] || 1;return countMap}, {});

  // Convert aggregated data into a 2-D array
  var result = [];
  for (var item in agg) {
    result.push( [item,agg[item]] );
  }
  return result;
}

// From https://stackoverflow.com/a/16705104/1677912
function transpose(a)
{
  return Object.keys(a[0]).map(function (c) { return a.map(function (r) { return r[c]; }); });
}

由于该功能负责生成图表所需的总和表,我们只需要生成数据并将其放入电子表格中。

function generateChart() {
  var sheet = SpreadsheetApp.getActiveSheet();

  var chart = sheet.getCharts()[0];
  var options = chart.getOptions();
  var a = JSON.stringify(options.get('width'))

  var data = sheet.getRange("A1:A17").getValues();
  var header = data.splice(0, 1);                // remove header row
  var aggregateData = sumAggregate( data );
  aggregateData.unshift([header[0][0],"Count"]); // replace & expand header row

  // Store in spreadsheet
  var tableRange = sheet.getRange(1, 3, aggregateData.length, aggregateData[0].length);
  tableRange.setValues(aggregateData);

  var barChart = sheet.newChart()
               .setChartType(Charts.ChartType.BAR)
               .setOption('title', 'Count of '+header[0][0])
               .setPosition(5, 5, 0,0)
               .addRange(tableRange)
               .build();

  sheet.insertChart(barChart);  
}

结果:

screenshot