Google 带有目标的可视化图表水平条(垂直线

Google Visualization Chart horizontal bar with target (vertical line

我想使用 Google Visualizion 图表设置一个小而轻的图表。

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

此外,我想包括一个指标 (red/green),以便轻松识别谁在目标之下和谁在目标之上(+ 可选地在 green/red 点之后的标签)。

知道如何进行吗?

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

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

请参阅以下工作片段...

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);
  }
});

请参阅以下工作片段...

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>