首页 > 解决方案 > 谷歌图表,柱形图 - 如何在 x 轴标签上居中列?

问题描述

在两组的分组柱形图中,当另一列的高度为 0 时,我想将该列居中。

例如,

在此处输入图像描述

2013 年至 2016 年的条形应以年份标签为中心。这是因为组中的第二个值是 0,所以 bar 的高度是 0,所以没有 bar 显示:

  data = [
     ["2012", 900, 950],
     ["2013", 1000, 0],
     ["2014", 1170, 0],
     ["2015", 1250, 0],
     ["2016", 1530, 0]
  ];

我怎样才能用谷歌图表做到这一点?

标签: chartsgoogle-visualization

解决方案


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

条形图位于其对应空白处的中心。
但是,一旦用户将鼠标悬停在一个栏上,它就会中断。

条由<rect>元素表示,
这些元素用于绘制图表本身、网格线、图例条等
。3 个<rect>元素用于突出显示悬停的条。

这就是破坏下面代码的原因,它抛出了查找条形的例程。

这就是它现在的工作方式......

即使条形不可见,条形/<rect>元素的数量也会与行和系列的数量相同。 它们将在元素列表中的倒数第二个。 最后一个元素是 x 轴。


<rect>

下面的代码向后工作,跳过最后一个元素,
并计算行数/系列数以收集可能需要移动的条形图。

当用户悬停时,插入了 3 个元素,因此需要更改例程以适应。
并且它们也需要移动才能正确突出显示。

否则,您可以关闭交互性并完成...

enableInteractivity: false

google.charts.load('current', {
  packages: ['corechart']
}).then(function () {
  var data = google.visualization.arrayToDataTable([
    ["Year", "Asia", "Mama"],
    ["2012", 900, 950],
    ["2013", 1000, 0],
    ["2014", 1170, 0],
    ["2015", 1250, 0],
    ["2016", 1530, 0]
  ]);

  var options = {
    chartArea: {
      height: '100%',
      width: '100%',
      top: 32,
      left: 48,
      right: 128,
      bottom: 48
    },
    height: 400,
    width: '100%'
  };

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

  google.visualization.events.addListener(chart, 'ready', function () {
    // get chart layout
    var chartLayout = chart.getChartLayoutInterface();

    // create mutation observer
    var observer = new MutationObserver(function () {
      // get bar elements
      var rects = container.getElementsByTagName('rect');
      var barLength = data.getNumberOfRows() * (data.getNumberOfColumns() - 1);
      var bars = [];
      for (var i = rects.length - 1; i > ((rects.length - 1) - (barLength + 1)); i--) {
        if (i < (rects.length - 1)) {
          bars.unshift(rects[i]);
        }
      }

      // process each row
      for (var r = 0; r < data.getNumberOfRows(); r++) {
        // process each series
        for (var s = 1; s < data.getNumberOfColumns(); s++) {
          // get chart element bounds
          var boundsBar = chartLayout.getBoundingBox('bar#' + (s - 1) + '#' + r);
          var boundsLabel = chartLayout.getBoundingBox('hAxis#0#label#' + r);

          // determine if bar is hidden
          if (boundsBar.height < 1) {
            // determine series shown, new x coordinate
            var seriesShown = (s === 1) ? 1 : 0;
            var xCoord = boundsLabel.left + (boundsLabel.width / 2);

            // move bar
            bars[r + (data.getNumberOfRows() * seriesShown)].setAttribute('x', (xCoord - (boundsBar.width / 2)));
          }
        }
      }
    });
    observer.observe(container, {
      childList: true,
      subtree: true
    });
  });

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


推荐阅读