在创建折线图的可调用函数中,我需要有条件地更改系列号可以变化的系列的轴和线宽

问题描述 投票:0回答:1

该函数将从许多其他函数中调用。 对于系列颜色,在报告状态(固定数字)时,我使用从更大的数组加载的状态颜色,然后进行修剪。在报道学校(相对固定的数量)时,我使用学校的颜色。在报告其他实体时,我使用相关子集。这段代码运行良好。

我的要求是,当最后一行要突出显示为平均值或突出显示并在右轴上显示时,我选择一种与黑色背景形成鲜明对比的颜色,并尝试增加线宽。我使用的技术是在

.setOption
系列中使用变量来表示系列号、系列宽度和系列轴。这似乎不起作用。我做错了什么?

function lineChart1(rowa, cola, rowl, coll, rowo, chtTitle, sheetName, position, suffix, second, groups) {
  /**
   *  @param: rowa is the anchor row for the input range
   *  @param: cola is the anchor column for the input range
   *  @param: rowl is the length of the input range in rows
   *  @param: coll is the length of the input range in columns
   *  @param: chtTitle is the title to be inserted in the chart
   *  @param: sheetName is the name of the target sheet for output
   *  @param: position Selects whether the chart is placed on the first, 
   *          second or third column (column defined in script properties)
   *  @param: suffix true/false indicates if last row should be highlighted  
   *  @param: second true/false specifies if the last series should be mapped 
   *          to the second axis and highlighted */

  /**  Define current spreadsheet  and name of sheet to contain chart */
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sh = ss.getSheetByName(sheetName);

  /** Get default chart attributes from script properties */
  const ps = PropertiesService.getScriptProperties();
  var chartHeight = Number(ps.getProperty('chartHeight'));
  var chartWidth = Number(ps.getProperty('chartWidth'));
  var column1Chart = Number(ps.getProperty('column1Chart'));
  var column2Chart = Number(ps.getProperty('column2Chart'));
  var column3Chart = Number(ps.getProperty('column3Chart'));

  /** Check if the anchor cell contains the chart ID of a previous chart 
   *  If so delete using that id, otherwise */
  var chtSheet = ss.getSheetByName(sheetName);
  var rng = chtSheet.getRange(rowo, outputColumn);
  var oldID = rng.getValue();
  if (oldID !== '' && oldID !== null) {
    deleteChartById(oldID, sheetName);
  }

  /** Setup default colours for series */
   /** Get corporate colours is a group; otherwise get colours
    * with the first 5 colours matching state colours */
  var seriesColoursArray = [];
  if (groups) { var seriesColoursArray = getSelectedGroupColours(); }
  else { var seriesColoursArray = getSeriesColours(); }

  /** Conditionally capture the colours for the left axis */
  var seriesColours = [];

  /** Determine how many series are for left axis */
  /** Subtract one for the header, one more if suffix or second specified */
  if (second !== true && suffix !== true) { var numPrimary = rowl - 1; }
  else { numPrimary = rowl - 2 }

  for (var r = 0; r < numPrimary; r++) {
    if (groups) { var colour = seriesColoursArray[r]; }
    else { var colour = seriesColoursArray[r][0]; }
    seriesColours.push(colour);
  }

  /** Add another colour if there is a suffix or right axis 
   *  and set the seriesWidth for the suffix or secondary series */
  if (suffix || second) {
    seriesColours.push('#ff00ff');
    var seriesWidth = 4;
  }
  else {
    var seriesWidth = 2;
  }

  /** Set variable for axis for last series  */
  if (second) { var axisNum = 1 } else { var axisNum = 0 };

  /** Set series number variable for last series */
  var seriesNum = seriesColours.length - 1;

  /** Set the chart position */
  switch (position) {
    case null:
      outputColumn = column1Chart
      break;
    case 1:
      outputColumn = column1Chart
      break;
    case 2:
      outputColumn = column2Chart
      break;
    case 3:
      outputColumn = column3Chart
      break;
    default:
      outputColumn = column1Chart
  }

  /** Set the chart element colour defaults */
  var chartElementColours = [];
  var chartElementColours = getChartColours();
  var chartAreaColour = chartElementColours[0][1];
  var chartPlotColour = chartElementColours[0][1];
  var chartTextColour = chartElementColours[2][1];
  var chartGridColour = chartElementColours[4][1];

  /** --------------------------------------------------------------
   * Select the input data to build the chart
   * --------------------------------------------------------------*/
  var chtRange = sh.getRange(rowa, cola, rowl, coll);
  var lineChartBuilder = sh.newChart().asLineChart();
  var chart = lineChartBuilder
    .addRange(chtRange)
    .setPosition(rowo, outputColumn, 0, 0)
    .setTransposeRowsAndColumns(true)
    .setTitle(chtTitle)
    .setColors(seriesColours)
    .setOption('titleTextStyle', { color: '#ffff00', fontName: 'Arial', bold: false, fontSize: 16 })
 //   .setOption('applyAggregateData', 0)
    .setNumHeaders(1)    /** First row contains headers */
    .setOption('chartArea', { backgroundColor: chartPlotColour })
    .setOption('legend', { position: 'bottom', textStyle: { color: chartTextColour, fontSize: 12 } })
    .setOption('XAxis', { position: 'bottom', textStyle: { color: chartTextColour, fontSize: 12 } })
    .setOption('hAxis', { format: "#", textStyle: { color: chartTextColour, fontSize: 12 }, gridlines: { count: 0 }, minorGridlines: { count: 0 }, majorGridlines: { count: 0 } })
    .setBackgroundColor(chartAreaColour)
    .setOption('applyAggregateData', 0)
    .setOption("useFirstColumnAsDomain", true) /** Get the the labels from the first column */
    .setCurveStyle(Charts.CurveStyle.SMOOTH)
    .setOption('series', { seriesNum: { textStyle: { color: chartTextColour, fontName: 'Arial', fontSize: 12, visibleInLegend: true }, lineWidth: seriesWidth, targetAxisIndex: axisNum } })
    .setOption('vAxes', {
      0: { textStyle: { color: chartTextColour, fontName: 'Arial', fontSize: 12 }, gridlines: { count: -1, color: chartGridColour, lineDashStyle: [4, 4] } },
      1: { textStyle: { color: 'white', fontName: 'Arial', fontSize: 12 } }
    })
    .setOption('vAxis', { textStyle: { color: chartTextColour, fontSize: 12 } })
    .setOption('width', chartWidth)
    .setOption('height', chartHeight)
    .build();

  sh.insertChart(chart);
  var newID = chart.getChartId();

  /** Store the chart ID in case we want to subsequently delete or modify it  */
  var rng = chtSheet.getRange(rowo, outputColumn);
  rng.setValue(newID);

};

function deleteChartById(id, sheetName) {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var chtSheet = ss.getSheetByName(sheetName);
  const chart = chtSheet.getCharts().find(chart => chart.getChartId() === +id);
  if (!chart) {
    throw new Error('Chart with ID ' + id + ' not found.');
  } else {
    chtSheet.removeChart(chart);
  }
}

我期望当后缀或秒为真时,线宽将为 4,如果秒为真,则系列将映射到右轴

google-sheets google-apps-script charts google-visualization
1个回答
0
投票

如果我遵循正确,您将尝试使用变量

seriesNum
的值作为系列选项的属性名称

在当前代码中,它只是使用标签

'seriesNum'
作为属性名称

在 JavaScript 中,为了使用变量的值作为对象的属性名称,
设置属性名称时必须使用括号

例如,使用名为

seriesOption
...

的对象变量
var seriesOption = {};

以下...

seriesOption.A = 1;

与...相同

var name = 'A';
seriesOption[name] = 1;

因此,建议首先构建您的系列选项,如下......

/** Set series number variable for last series */
var seriesNum = seriesColours.length - 1;

/** Build series option for last series */
var seriesOption = {};
seriesOption[seriesNum] = {
  textStyle: {
    color: chartTextColour,
    fontName: 'Arial',
    fontSize: 12,
    visibleInLegend: true
  },
  lineWidth: seriesWidth,
  targetAxisIndex: axisNum
}

然后在图表中设置选项,使用...

/** Set series option for last series */
.setOption('series', seriesOption)
© www.soinside.com 2019 - 2024. All rights reserved.