You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Google Classic Charts双轴堆叠柱形图堆叠重叠问题及相邻堆叠实现可行性问询

在Google Classic Charts中实现双轴相邻堆叠柱形图(附自定义Tooltip)

我完全理解你的痛点:Google Material Charts能轻松实现双轴下的相邻堆叠柱形,但它不支持自定义Tooltip;而Classic Charts虽然支持Tooltip定制,却把同一轴的堆叠系列渲染在之前的堆叠之上,和Material的效果差异明显。

别担心,我们可以通过给Classic Charts的系列分配堆叠分组来解决这个问题,完美复刻Material的效果,同时保留自定义Tooltip的特性。

核心解决方案:用stack属性划分堆叠组

Classic Charts默认会把所有系列堆叠在一起,不管它们归属哪个轴。我们只需要给不同轴的系列设置不同的stack标识,同一轴的系列设置相同的stack标识,就能让同一轴的系列堆叠,不同轴的系列相邻排列。

修改后的Classic配置

var classicOptions = {
  width: 900,
  isStacked: true, // 开启全局堆叠模式
  series: {
    0: { 
      targetAxisIndex: 0, 
      stack: 'distance-group' // 左轴的Distance系列单独成组
    },
    1: { 
      targetAxisIndex: 1, 
      stack: 'brightness-group' // 右轴的Brightness系列加入brightness组
    },
    2: { 
      targetAxisIndex: 1, 
      stack: 'brightness-group' // 右轴的Contrast系列也加入brightness组,实现堆叠
    }
  },
  title: 'Nearby galaxies - distance on the left, brightness on the right',
  vAxes: {
    0: { title: 'parsecs' },
    1: { title: 'apparent magnitude' }
  },
  tooltip: { isHtml: true } // 开启HTML自定义Tooltip,满足你的核心需求
};

原理拆解

  • stack属性是关键:同一stack值的系列会在同一个类别下堆叠,不同stack值的系列会并排显示
  • 左轴的Distance系列单独占一个堆叠组,右轴的Brightness和Contrast系列共享一个堆叠组,这样每个Galaxy类别下就会呈现两个相邻的堆叠柱,和Material Charts的效果完全一致
  • 同时保留了Classic Charts独有的tooltip.isHtml特性,你可以自由定制Tooltip的HTML内容

完整可运行代码

HTML+JavaScript完整示例

<html>
  <head>
    <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
    <script type="text/javascript">
      google.charts.load('current', { 'packages': ['corechart', 'bar'] });
      google.charts.setOnLoadCallback(drawStuff);
      function drawStuff() {
        var button = document.getElementById('change-chart');
        var chartDiv = document.getElementById('chart_div');

        // 带自定义HTML Tooltip的数据
        var data = google.visualization.arrayToDataTable([
          ['Galaxy', 'Distance', 'Brightness', 'Contrast', { type: 'string', role: 'tooltip', 'p': { 'html': true } }],
          ['Canis Major Dwarf', 8000, 23.3, 2.8, '<div style="padding:10px;"><b>Canis Major Dwarf</b><br>类型:不规则星系<br>距离:8000 秒差距</div>'],
          ['Sagittarius Dwarf', 24000, 3.5, 6.6, '<div style="padding:10px;"><b>Sagittarius Dwarf</b><br>半径:5000 光年<br>亮度:3.5</div>'],
          ['Ursa Major II Dwarf', 30000, 14.3, 10.67, '<div style="padding:10px;"><b>Ursa Major II Dwarf</b><br>半光半径<br>对比度:10.67</div>'],
          ['Lg. Magellanic Cloud', 50000, 0.9, 3.6, null],
          ['Bootes I', 60000, 13.1, 10.23, null]
        ]);

        var materialOptions = {
          width: 900,
          isStacked: true,
          chart: {
            title: 'Nearby galaxies',
            subtitle: 'distance on the left, brightness on the right'
          },
          series: {
            0: { axis: 'distance' },
            1: { axis: 'brightness' },
            2: { axis: 'brightness' }
          },
          axes: {
            y: {
              distance: { label: 'parsecs' },
              brightness: { side: 'right', label: 'apparent magnitude' }
            }
          }
        };

        // 修改后的Classic配置
        var classicOptions = {
          width: 900,
          isStacked: true,
          series: {
            0: { targetAxisIndex: 0, stack: 'distance-group' },
            1: { targetAxisIndex: 1, stack: 'brightness-group' },
            2: { targetAxisIndex: 1, stack: 'brightness-group' }
          },
          title: 'Nearby galaxies - distance on the left, brightness on the right',
          vAxes: {
            0: { title: 'parsecs' },
            1: { title: 'apparent magnitude' }
          },
          tooltip: { isHtml: true }
        };

        function drawMaterialChart() {
          var materialChart = new google.charts.Bar(chartDiv);
          materialChart.draw(data, google.charts.Bar.convertOptions(materialOptions));
          button.innerText = 'Change to Classic';
          button.onclick = drawClassicChart;
        }

        function drawClassicChart() {
          var classicChart = new google.visualization.ColumnChart(chartDiv);
          classicChart.draw(data, classicOptions);
          button.innerText = 'Change to Material';
          button.onclick = drawMaterialChart;
        }

        drawMaterialChart();
      };
    </script>
  </head>
  <body>
    <button id="change-chart">Change to Classic</button>
    <br><br>
    <div id="chart_div" style="width: 800px; height: 500px;"></div>
  </body>
</html>

这个方案完美兼顾了你的两个需求:既实现了和Material Charts一致的双轴相邻堆叠效果,又保留了Classic Charts的自定义Tooltip功能。

内容的提问来源于stack exchange,提问作者Rahul Raj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 20:32:47