Google 可视化图表中的垂直轴标签设置为中间

Vertical Axis labels set to middle in Google Visualization Chart

我正在使用 Google 的可视化气泡图。我需要将垂直轴上的标签对齐到中间。请看下图。像这样的东西。这些月份名称需要位于主要网格线之间。

这是我为这个气泡图添加的选项,但它只显示在轴线旁边。

var options = {
        sizeAxis: {
            maxSize: 7,
            minSize: 1
        },
        animation: {
            duration: 1500,
            easing: 'in',
            startup: true
        },

        fontSize: 10,
        legend: 'none',
        height: 230,
        chartArea: { left: "20%", right: 0, top: 0, width: "70%", height: "200px" },


        bubble: { stroke: '#ffca18', opacity: 1 },
        colors: ['#ffca18', '#ffca18'],
        tooltip: {
            trigger: 'none'
        },
        hAxis: {
            ticks: [
                { v: 2015, f: '2015' },
                { v: 2016, f: '2016' },
                { v: 2017, f: '2017' },
                { v: 2018, f: '2018' },
                { v: 2019, f: '2019' },
                { v: 2019, f: '2020' }
            ],

            gridlines: { color: '#dedede' },
            minorGridlines: { color: '#f7f7f7', count: 3 },
            textStyle: { color: '#5f5f5f' }
        },
        vAxis: {
            ticks: [                   
                { v: 1, f: 'May' },
                { v: 2, f: 'April' },
                { v: 3, f: 'March' },
                { v: 4, f: 'February' },
                { v: 5, f: 'January' }
            ],
            gridlines: { color: '#dedede' },
            textStyle: { color: '#5f5f5f' },
            viewWindowMode: 'explicit',
            viewWindow: {
                min: 1,
                max: 7
            }
        }
    };

我们可以在图表的 'ready' 事件中手动移动标签,
或者在这种情况下,'animationfinish' 事件,或两者。

图表有一个方法 getChartLayoutInterface()
这个 returns 一个对象,我们可以使用它来获取各种图表元素的位置。

我们可以得到网格线的位置,
并在其间移动标签。

function moveYAxisLabels() {
  var chartLayout = chart.getChartLayoutInterface();
  var labels = chart.getContainer().getElementsByTagName('text');
  var labelIndex = -1;
  Array.prototype.forEach.call(labels, function(label) {
    if (label.getAttribute('text-anchor') === 'end') {
      labelIndex++;
      labelHeight = chartLayout.getBoundingBox('vAxis#0#label#' + labelIndex).height;
      labelBottom = chartLayout.getBoundingBox('vAxis#0#gridline#' + labelIndex).top;
      labelTop = chartLayout.getBoundingBox('vAxis#0#gridline#' + (labelIndex + 1)).top;
      label.setAttribute('y', labelBottom - ((labelBottom - labelTop) / 2) + Math.floor(labelHeight / 2));
    }
  });
}

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

google.charts.load('current', {
  packages: ['corechart']
}).then(function () {
  var data = new google.visualization.DataTable({
    "cols": [
      {"label": "id", "type": "string"},
      {"label": "x", "type": "number"},
      {"label": "y", "type": "number"}
    ],
    "rows": [
      {"c":[{"v": ""}, {"v": 2015}, {"v": 1}]},
      {"c":[{"v": ""}, {"v": 2016}, {"v": 2}]},
      {"c":[{"v": ""}, {"v": 2017}, {"v": 3}]},
      {"c":[{"v": ""}, {"v": 2018}, {"v": 4}]},
      {"c":[{"v": ""}, {"v": 2019}, {"v": 5}]},
      {"c":[{"v": ""}, {"v": 2020}, {"v": 6}]}
    ]
  });

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

  google.visualization.events.addListener(chart, 'ready', moveYAxisLabels);
  google.visualization.events.addListener(chart, 'animationfinish', moveYAxisLabels);

  function moveYAxisLabels() {
    var chartLayout = chart.getChartLayoutInterface();
    var labels = chart.getContainer().getElementsByTagName('text');
    var labelIndex = -1;
    Array.prototype.forEach.call(labels, function(label) {
      if (label.getAttribute('text-anchor') === 'end') {
        labelIndex++;
        labelHeight = chartLayout.getBoundingBox('vAxis#0#label#' + labelIndex).height;
        labelBottom = chartLayout.getBoundingBox('vAxis#0#gridline#' + labelIndex).top;
        labelTop = chartLayout.getBoundingBox('vAxis#0#gridline#' + (labelIndex + 1)).top;
        label.setAttribute('y', labelBottom - ((labelBottom - labelTop) / 2) + Math.floor(labelHeight / 2));
      }
    });
  }

  var options = {
    sizeAxis: {
      maxSize: 7,
      minSize: 1
    },
    animation: {
      duration: 1500,
      easing: 'in',
      startup: true
    },
    fontSize: 10,
    legend: 'none',
    height: 230,
    chartArea: {
      bottom: 48,
      left: 200,
      right: 18,
      top: 18,
      width: '100%',
      height: '100%'
    },
    bubble: { stroke: '#ffca18', opacity: 1 },
    colors: ['#ffca18', '#ffca18'],
    tooltip: {
      trigger: 'none'
    },
    hAxis: {
      ticks: [
        { v: 2015, f: '2015' },
        { v: 2016, f: '2016' },
        { v: 2017, f: '2017' },
        { v: 2018, f: '2018' },
        { v: 2019, f: '2019' },
        { v: 2020, f: '2020' }
      ],
      gridlines: { color: '#dedede' },
      minorGridlines: { color: '#f7f7f7', count: 3 },
      textStyle: { color: '#5f5f5f' }
    },
    vAxis: {
      ticks: [
        { v: 1, f: 'JUNE' },
        { v: 2, f: 'MAY' },
        { v: 3, f: 'APRIL' },
        { v: 4, f: 'MARCH' },
        { v: 5, f: 'FEBRUARY' },
        { v: 6, f: 'JANUARY' },
        { v: 7, f: '' }
      ],
      gridlines: { color: '#dedede' },
      textStyle: { color: '#5f5f5f' },
      viewWindowMode: 'explicit',
      viewWindow: {
        min: 1,
        max: 7
      }
    }
  };

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

这里唯一的问题是动画,
图表将移动 'ready'
上的标签 然后我们将它们移回 'animationfinish'
所以它们似乎在跳跃。
您可能会重新考虑使用动画...