类别筛选重叠内容

时间:2014-01-20 18:04:47

标签: google-apps-script google-visualization

我在表格图表上设置了类别过滤器。类别列表来自工作表中的列表。多个类别具有冗长的名称。选择类别过滤器上的下拉菜单时,它会在面板边框外部呈现选区,并与其后面的内容重叠。我可以在Apps脚本中做些什么来清理它吗?

screenshot

这是'Sheet1'中的数据,采用csv格式(便于导入):

column1,column2,heading
data,   data,   category0
data,   data,   category1
data,   data,   category2
data,   data,   category3
data,   data,   the category that had a lengthy name and is overlapping content
data1,  data1,  category0
data1,  data1,  category1
data1,  data1,  category2
data1,  data1,  category3
data1,  data1,  the category that had a lengthy name and is overlapping content
data2,  data2,  category0
data2,  data2,  category1
data2,  data2,  category2
data2,  data2,  category3
data2,  data2,  the category that had a lengthy name and is overlapping content
data3,  data3,  category0
data3,  data3,  category1
data3,  data3,  category2
data3,  data3,  category3
data3,  data3,  the category that had a lengthy name and is overlapping content

代码:

  function doGet() {
    var templateDocId = "1UH....";
    var ss0 = SpreadsheetApp.openById(templateDocId).getSheetByName('Sheet1');
    var data0 = ss0.getDataRange();

    var quarterfilter = Charts.newCategoryFilter().setFilterColumnIndex(2).build();

    var tableChart = Charts.newTableChart()
    .setDataViewDefinition(Charts.newDataViewDefinition().setColumns([0,1,2])).setDimensions(700,300).build()

    var dashboard0 = Charts.newDashboardPanel().setDataTable(data0).bind([quarterfilter],[tableChart]).build();

    var app0 = UiApp.createApplication()
    var filterpanel = app0.createVerticalPanel().add(app0.createHorizontalPanel().add(app0.createLabel("List").setStyleAttribute("fontSize","20")))
    var chartpanel = app0.createHorizontalPanel().add(app0.createVerticalPanel().add(tableChart))

    filterpanel.add(quarterfilter);
    chartpanel.setSpacing(20);
    dashboard0.add(app0.createVerticalPanel().add(filterpanel).add(chartpanel));
    app0.add(dashboard0);
    return app0;

  }

1 个答案:

答案 0 :(得分:0)

过去一周我花了好几个小时和几个小时,我无法调整选择框的大小或强制其中的项目符合小部件宽度。

您可以使用.setLabelStacking(orientation)控制所选类别的布局,但没有类似的方法可以控制这些类别在选择器中的显示方式。

Google Apps Script Issues Tracker没有关于此提交的报告。您应该报告此问题。如果你在这里添加一个问题的链接,那么将鼓励其他分享这种痛苦的人去投票。

变通

选择器会自动调整其宽度,达到可容纳约30个字符的限制。因此,一个不太理想的选择是截断电子表格中的类别名称。这样可以最好地控制显示的内容。

让电子表格保持不变的替代方法是从电子表格中提取数据,并在自己构建dataTable时截断更宽的列。这会给你这样的东西:

Screenshot

代码

由于dataTable一旦构建(或从Range生成)就无法修改,我们需要自己制作。为了简化这一点,该函数使用Range进行相同的假设。它接受一个二维值数组,并返回一个dataTable我们可以用于图表。 (Available as a gist.

/**
 * Produce a dataTable object suitable for use with Charts, from
 * an array of rows (such as you'd get from Range.getValues()).
 * Assumes labels are in row 0, and the data types in row 1 are
 * representative for the table.
 *
 * @param {Array} data  Array of table rows
 *
 @ @returns {DataTable} Refer to GAS documentation
 */
function dataTableFromArray( data ) {
 var dataTable = Charts.newDataTable();
  for (var col=0; col<data[0].length; col++) {
    var label = data[0][col];
    var firstCell = data[1][col];
    if (typeof firstCell == 'string')
      dataTable.addColumn(Charts.ColumnType.STRING, label);
    else
      dataTable.addColumn(Charts.ColumnType.NUMBER, label);
  }
  for (var row = 1; row < data.length; row++) {
    dataTable.addRow(data[row]);
  }  
  return dataTable.build();
}

下一个函数负责截断我们想要在选择器中用作类别的数据。它不是盲目操作所有列,而是接受一个可选的列号数组(从0开始),它将强制执行最大长度。

/**
 * Ensure the text in the indicated columns does not exceed the
 * given maximum length. The data table is changed in place, but
 * is also returned for chaining.
 *
 * @param {Array}    data    Array of Rows
 * @param {Number}   maxLen  Maximum string length to enforce
 * @param {Array}    columns (optional) Array of column numbers
 *                           for enforcement
 *
 * @returns {Array}  Resulting array for chaining.
 */
function truncateLongText( data, maxLen, columns ) {
  if (maxLen < 10) throw new Error( 'maxLen too small' );  // Truncating becomes pointless
  var elipses = '...';
  var frontLen = Math.ceil(2*maxLen / 3);
  var backlen = (maxLen-frontLen-elipses.length);
  for (var row=0; row < data.length; row++) {
    for (var col=0; col<data[row].length; col++) {
      if (columns != undefined && columns.indexOf(col) != -1) {
        var cell = data[row][col];
        if (typeof cell == 'string' && cell.length > maxLen) {
          var front = cell.slice(0,frontLen);
          var back = backlen > 0 ? cell.slice(-backlen) : '';
          cell = front + elipses + back;  // Truncate cell contents
          data[row][col] = cell;
        }
      }
    }
  }
  return data;
}

这是使用这些函数生成上面显示的屏幕截图的示例图表。请注意,data0不再是dataTable,现在是array

function doGet() {
    var templateDocId = "1UH....";
    var ss0 = SpreadsheetApp.openById(templateDocId).getSheetByName('Sheet1');
    var data0 = truncateLongText(ss0.getDataRange().getValues(),30,[2]);

    var quarterfilter = Charts.newCategoryFilter().setFilterColumnIndex(2).build();

    var tableChart = Charts.newTableChart()
    .setDataViewDefinition(Charts.newDataViewDefinition().setColumns([0,1,2])).setDimensions(700,300).build()

    var dashboard0 = Charts.newDashboardPanel().setDataTable(dataTableFromArray(data0)).bind([quarterfilter],[tableChart]).build();

    var app0 = UiApp.createApplication()
    var filterpanel = app0.createVerticalPanel().add(app0.createHorizontalPanel().add(app0.createLabel("List").setStyleAttribute("fontSize","20")))
    var chartpanel = app0.createHorizontalPanel().add(app0.createVerticalPanel().add(tableChart))

    filterpanel.add(quarterfilter);
    chartpanel.setSpacing(20);
    dashboard0.add(app0.createVerticalPanel().add(filterpanel).add(chartpanel));
    app0.add(dashboard0);
    return app0;

  }