【问题标题】:Google Sheets : Color dots in scatter plot based on data range cell background colorGoogle表格:基于数据范围单元格背景颜色的散点图中的颜色点
【发布时间】:2021-07-21 10:50:39
【问题描述】:

我有一个 Google 表格文件,其中存储了不同区域(后、前、左、右)的不同汽车的油漆厚度值。然后将所有内容汇总在散点图中,按车龄(X 轴)显示油漆厚度(Y 轴)。

每个区域都有它自己的系列,它给出的是那辆或每辆汽车,它会在汽车的年龄值上创建一条垂直的点线(序列号只是一个标签)。每个点都表示相应区域的油漆厚度,其位置在 Y 轴上。

我正在根据每个区域报告的损坏情况更改单元格的背景颜色。我希望散点图中每个对应的点都具有相同的颜色,而不是一一着色。

(我不能包含任何链接/屏幕截图,因为这是机密数据)

例子:

SerialNumber AGE ZONE1 ZONE2 ZONE3 ZONE4
42 15 178 210 246 143

序列号 42 是 15 个月大。它的左侧有 246 的油漆厚度,并且已经报告了损坏。我将包含 246 的单元格着色为红色,这会改变散点图中相应点的颜色。

脚本必须将散点图中的每个点与其对应的单元格相关联,获取单元格的背景颜色并根据它设置点的颜色。

我无法为整个系列着色,因为每种颜色都需要特定于一辆车的一个区域

这个文件曾经是一个 Excel 文件,我找到了一个 VBA 宏可以做到这一点,但我的公司正在切换到 Gsuite,我对它还不够熟悉,无法翻译宏。

这是 VBA 代码:

Sub CellColorsToChart()
'Update by Extendoffice
    Dim xChart As Chart
    Dim I As Long, J As Long
    Dim xRowsOrCols As Long, xSCount As Long
    Dim xRg As Range, xCell As Range
    On Error Resume Next
    Set xChart = ActiveSheet.ChartObjects("Chart 1").Chart
    If xChart Is Nothing Then Exit Sub
    xSCount = xChart.SeriesCollection.Count
    For I = 1 To xSCount
        J = 1
        With xChart.SeriesCollection(I)
            Set xRg = ActiveSheet.Range(Split(Split(.Formula, ",")(2), "!")(1))
            If xSCount > 4 Then
                xRowsOrCols = xRg.Columns.Count
            Else
                xRowsOrCols = xRg.Rows.Count
            End If
            For Each xCell In xRg
                .Points(J).Format.Fill.ForeColor.RGB = ThisWorkbook.Colors(xCell.Interior.ColorIndex)
                .Points(J).Format.Line.ForeColor.RGB = ThisWorkbook.Colors(xCell.Interior.ColorIndex)
                J = J + 1
            Next
        End With
    Next
End Sub

【问题讨论】:

    标签: google-apps-script scatter-plot google-workspace


    【解决方案1】:

    相当笨拙,但无论如何,这是我的尝试:

    function myFunction() {
      var sheet = SpreadsheetApp.getActiveSheet();
    
      var colors = sheet.getRange('C2:F2').getBackgrounds().flat();
      
      var chart = sheet.getCharts()[0];
      chart = chart.modify()
        .setOption('series.0.items.0.color', colors[0])
        .setOption('series.0.items.1.color', colors[1])
        .setOption('series.0.items.2.color', colors[2])
        .setOption('series.0.items.3.color', colors[3])
        .build();
      sheet.updateChart(chart);
    }
    

    更新

    我仍然不确定我是否理解正确。可能是这样的吗?

    function myFunction() {
    
      var sheet = SpreadsheetApp.getActiveSheet();
      var chart = sheet.getCharts()[0];
      var colors = [];
      
      colors = sheet.getRange('C2:C5').getBackgrounds().flat();
      chart = recolor(chart, colors, 0);
    
      colors = sheet.getRange('D2:D5').getBackgrounds().flat();
      chart = recolor(chart, colors, 1);
    
      colors = sheet.getRange('E2:E5').getBackgrounds().flat();
      chart = recolor(chart, colors, 2);
        
      colors = sheet.getRange('F2:F5').getBackgrounds().flat();
      chart = recolor(chart, colors, 3);
        
      sheet.updateChart(chart);
      
      function recolor(chart, colors, series) {
        return chart.modify()
          .setOption('series.' + series + '.items.0.color', colors[0])
          .setOption('series.' + series + '.items.1.color', colors[1])
          .setOption('series.' + series + '.items.2.color', colors[2])
          .setOption('series.' + series + '.items.3.color', colors[3])
          .build();
      }
    
    }
    

    更新 2

    代码的更新版本。现在它可以为任意数量的汽车(行)着色:

    function myFunction() {
    
      var sheet  = SpreadsheetApp.getActiveSheet();
      var last   = sheet.getLastRow();
      var chart  = sheet.getCharts()[0];
      var colors = [];
    
      // recolor zone 1
      colors = sheet.getRange('C2:C' + last).getBackgrounds().flat();
      chart = recolor(chart, colors, 0);
    
      // recolor zone 2
      colors = sheet.getRange('D2:D' + last).getBackgrounds().flat();
      chart = recolor(chart, colors, 1);
    
      // recolor zone 3
      colors = sheet.getRange('E2:E' + last).getBackgrounds().flat();
      chart = recolor(chart, colors, 2);
        
      // recolor zone 4
      colors = sheet.getRange('F2:F' + last).getBackgrounds().flat();
      chart = recolor(chart, colors, 3);
    
      // update the chart    
      sheet.updateChart(chart);
      
      function recolor(chart, colors, series) {
        colors.forEach((color,i) => {
          chart = chart.modify()
            .setOption('series.' + series + '.items.' + i + '.color', color)
            .build();
        });
        return chart;
      }
    }
    

    也许它可以扩展为能够占用任意数量的区域。


    这是一个可以处理任意数量区域的最终版本:

    function myFunction() {
    
      var sheet = SpreadsheetApp.getActiveSheet();
      var chart = sheet.getCharts()[0];
      var last_cell = chart.getRanges()[1].getA1Notation().split(':')[1]; // the bottom right cell of the chart
      var data  = sheet.getRange('C2:' + last_cell).getBackgrounds();
    
      for (var i in data) chart = recolor(chart, data.map(x => x[i]), i);
      
      sheet.updateChart(chart);
      
      function recolor(chart, colors, series) {
        colors.forEach((color,i) => {
          chart = chart.modify()
            .setOption('series.' + series + '.items.' + i + '.color', color)
            .build();
        });
        return chart;
      }
    
    }
    

    【讨论】:

    • 感谢您的回答!它改变了一些颜色,但部分改变了,因为我的图表与您在工作表上所做的不完全一样。实际上,X 轴上的是汽车的年龄,而不是区域。不过,我真的不明白那是如何工作的。
    • 我实际上对图表几乎一无所知,所以如果你不向我展示你的图表是什么样子,我帮不了你。
    • 我什至不能包含我的文件的模拟版本的屏幕截图,因为我的计算机已经掌握并阻止了任何类型的所有导出......我编辑了我的问题以澄清图表是如何制作的,如果您想再试一次。
    • 嗯...对不起,也许我的英语也不够好。我无法从你的描述中弄清楚你的图表是什么样子的。可能对于了解图表的人来说显然是这样,但不适合我。
    • 不过,只是为了好玩,我只是制作了可以处理任意数量“区域”的版本。 )
    猜你喜欢
    • 2016-01-15
    • 2016-07-25
    • 2017-06-19
    • 1970-01-01
    • 2021-03-23
    • 2013-09-03
    • 2018-06-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多