从电子表格数据的单列制作条形图

Ale*_*xRu 1 google-visualization google-sheets google-apps-script

我有一个包含分类数据列的大型电子表格.我想为每列创建一个条形图,表示该列中不同值的计数.我尝试使用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);
}
Run Code Online (Sandbox Code Playgroud)

这是带有嵌入式条形图的电子表格:

嵌入式条形图

并且期望的结果将是这样

期望的结果

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

Mog*_*dad 6

EmbeddedCharts不公开Spreadsheet Charts可用的所有功能,也不公开Visualization API的所有功能.您在这里遇到的具体限制:

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

    所需的图表不仅仅是绘制单个数据列,它通过聚合有效地生成一个表.当您选择单列文本单元格时,默认图表将是标题为"[列标题]的计数"的条形图,其中启用了"聚合列",如下所示:

    设置

如何通过脚本获得相同的结果

比方说,A栏包含受访者最喜欢的宠物名单:

Favourite Pet
-------------
Cat
Cat
Dog
Alpaca
Budgie
Budgie
Cat
Dog
Hamster
Cat
Gerbil
Rabbit
Dog
Rabbit
Cat
Dog
Run Code Online (Sandbox Code Playgroud)

总和数据看起来像:

Favourite Pet   Count
---------------------
Cat               5
Dog               4
Alpaca            1
Budgie            2
Hamster           1
Gerbil            1
Rabbit            2
Run Code Online (Sandbox Code Playgroud)

选项1:电子表格功能

由于EmbeddedCharts的限制,要显示的数据必须位于"表",范围或范围集中,因此您需要满足该要求.一种方法是使用Sheets QUERY()函数,如计算列中出现的次数?:

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

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

选项2:全部按脚本

该脚本需要生成类似的聚合数据表.JavaScript中有很多这样的例子,比如计算JavaScript数组元素的出现次数.有了这个,还有来自Google Spreadsheet Script的数组转置函数- 如何转置/旋转多维数组?,我们可以像这样把它们放在一起:

/**
 * 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]; }); });
}
Run Code Online (Sandbox Code Playgroud)

使用该函数来生成图表所需的总和表,我们只需要生成数据并将其放入电子表格中.

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);  
}
Run Code Online (Sandbox Code Playgroud)

结果:

截图