【问题标题】:Google Visualization Chart horizontal bar with target (vertical line带有目标的 Google 可视化图表水平条(垂直线
【发布时间】:2020-02-21 10:55:26
【问题描述】:

我想使用谷歌可视化图表设置一个小而轻的图表。

我们的想法是制作一个水平条形图(我知道该怎么做),但要结合一条垂直线来显示是否超过了目标。 每个数据的目标可以不同。

此外,我想包括一个指示器(红色/绿色),轻松识别谁在目标之下和谁在目标之上(+ 可选地,在绿/红点之后的标签)。

知道如何进行吗?

【问题讨论】:

  • 您可以使用combo chart,带有条形、线条和散点系列...
  • 您认为使用组合图来制作水平条可行吗?我没能在表格中找到它。

标签: charts google-visualization


【解决方案1】:

实际上,您可以使用BarChart
并更改最后两列的系列类型...

series: {
  1: {
    type: 'line'
  },
  2: {
    type: 'scatter'
  }
}

请参阅以下工作 sn-p...

google.charts.load('current', {
  packages: ['corechart']
}).then(function () {
  var dataTable = new google.visualization.DataTable();
  dataTable.addColumn({type: 'string', id: 'x'});
  dataTable.addColumn({type: 'number', id: 'bar'});
  dataTable.addColumn({type: 'string', role: 'annotation'});
  dataTable.addColumn({type: 'number', id: 'line'});
  dataTable.addColumn({type: 'number', id: 'scatter'});
  dataTable.addColumn({type: 'string', role: 'style'});
  dataTable.addRows([
    ['', 300, '300', 300, 800, '#4caf50'],
    ['', 600, '600', 600, 800, '#f44336'],
    ['', 200, '200', 200, 800, '#4caf50'],
    ['', 150, '150', 150, 800, '#f44336'],
  ]);

  var options = {
    annotations: {
      alwaysOutside: true,
      textStyle: {
        color: '#000000'
      }
    },
    colors: ['#9e9e9e', '#2196f3'],
    legend: 'none',
    hAxis: {
      gridlines: {
        count: 0
      },
      textPosition: 'none'
    },
    series: {
      1: {
        lineWidth: 4,
        type: 'line'
      },
      2: {
        type: 'scatter'
      }
    }
  };

  var chart = new google.visualization.BarChart(document.getElementById('chart'));
  chart.draw(dataTable, options);
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart"></div>

编辑

在散点旁边添加自定义标签,
你可以使用图表方法 --> getChartLayoutInterface()

其中有一个方法 --> getBoundingBox(id)
这可用于查找图表元素的位置。
其中id是点的字符串id,格式如下 --> point#series#row -- point#0#0

在图表的'ready' 事件中,我们可以在点旁边放置自定义标签。

google.visualization.events.addListener(chart, 'ready', function (sender) {
  var padding = 16;
  var chartLayout = chart.getChartLayoutInterface();
  var containerBounds = chart.getContainer().getBoundingClientRect();

  for (var row = 0; row < dataTable.getNumberOfRows(); row++) {
    var pointBounds = chartLayout.getBoundingBox('point#2#' + row);
    var dataLabel = document.createElement('span');
    dataLabel.className = 'data-label';
    dataLabel.innerHTML = 'Label ' + row;
    dataLabel.style.top = (containerBounds.top + pointBounds.top - (pointBounds.height / 2)) + 'px';
    dataLabel.style.left = (containerBounds.left + pointBounds.left + pointBounds.width + padding) + 'px';
    chart.getContainer().appendChild(dataLabel);
  }
});

请参阅以下工作 sn-p...

google.charts.load('current', {
  packages: ['corechart']
}).then(function () {
  var dataTable = new google.visualization.DataTable();
  dataTable.addColumn({type: 'string', id: 'x'});
  dataTable.addColumn({type: 'number', id: 'bar'});
  dataTable.addColumn({type: 'string', role: 'annotation'});
  dataTable.addColumn({type: 'number', id: 'line'});
  dataTable.addColumn({type: 'number', id: 'scatter'});
  dataTable.addColumn({type: 'string', role: 'style'});
  dataTable.addRows([
    ['', 300, '300', 300, 800, '#4caf50'],
    ['', 600, '600', 600, 800, '#f44336'],
    ['', 200, '200', 200, 800, '#4caf50'],
    ['', 150, '150', 150, 800, '#f44336'],
  ]);

  var options = {
    annotations: {
      alwaysOutside: true,
      textStyle: {
        color: '#000000'
      }
    },
    colors: ['#9e9e9e', '#2196f3'],
    legend: 'none',
    hAxis: {
      gridlines: {
        count: 0
      },
      textPosition: 'none'
    },
    series: {
      1: {
        lineWidth: 4,
        type: 'line'
      },
      2: {
        type: 'scatter'
      }
    }
  };

  var chart = new google.visualization.BarChart(document.getElementById('chart'));

  google.visualization.events.addListener(chart, 'ready', function (sender) {
    var padding = 16;
    var chartLayout = chart.getChartLayoutInterface();
    var containerBounds = chart.getContainer().getBoundingClientRect();

    for (var row = 0; row < dataTable.getNumberOfRows(); row++) {
      var pointBounds = chartLayout.getBoundingBox('point#2#' + row);
      var dataLabel = document.createElement('span');
      dataLabel.className = 'data-label';
      dataLabel.innerHTML = 'Label ' + row;
      dataLabel.style.top = (containerBounds.top + pointBounds.top - (pointBounds.height / 2)) + 'px';
      dataLabel.style.left = (containerBounds.left + pointBounds.left + pointBounds.width + padding) + 'px';
      chart.getContainer().appendChild(dataLabel);
    }
  });

  chart.draw(dataTable, options);
});
.data-label {
  position: absolute;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart"></div>

【讨论】:

  • 不仅仅是帮助,您还拯救了我的一天!非常感谢您提供正确的方向!现在我可以想象使用 Google Suite 从 Excel 宏转移到服务器端解决方案。如果可以,您知道是否可以在点之后添加标签?
  • 这是可能的,但不能使用谷歌图表中的标准选项。如果您使用注释,它将把标签放在上面。但您可以添加自己的自定义标签。并使用图表方法定位点旁边。让我找个例子……
  • 你好@WhiteHat,很抱歉我迟到的回答,但我有一些忙碌的日子,在回答你之前绝对想自己尝试一下。在我的代码中,由于您的代码,我在提议的图表左侧有另一个图表。标签显示不正确。它们出现在另一张图表中,但没有出现在想要的图表中。有没有办法获得当前图表的相对坐标?
  • 不确定我是否关注,您正在尝试向当前图表添加标签,但它们出现在另一个图表上?
  • 哼,我不确定我在说什么。我想办法让它现在工作。第一次刷新页面时(同一行上有 2 个图表),我感觉标签是绝对显示在页面而不是图表框架上的。反正。它现在可以正常工作,并衷心感谢您的帮助。当然,我将其标记为已解决!谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-28
  • 1970-01-01
  • 2019-09-07
  • 1970-01-01
  • 1970-01-01
  • 2013-02-05
相关资源
最近更新 更多