charts - 谷歌图表,柱形图 - 如何在 x 轴标签上居中列?
问题描述
在两组的分组柱形图中,当另一列的高度为 0 时,我想将该列居中。
例如,
2013 年至 2016 年的条形应以年份标签为中心。这是因为组中的第二个值是 0,所以 bar 的高度是 0,所以没有 bar 显示:
data = [
["2012", 900, 950],
["2013", 1000, 0],
["2014", 1170, 0],
["2015", 1250, 0],
["2016", 1530, 0]
];
我怎样才能用谷歌图表做到这一点?
解决方案
请参阅以下工作片段...
条形图位于其对应空白处的中心。
但是,一旦用户将鼠标悬停在一个栏上,它就会中断。
条由<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>
推荐阅读
- kubernetes - 使用 Bitnami WordPress helm chart,如何通过 FTP 连接 Filezilla?
- css - 是否可以取消所有 css 文件在 Wordpress 前端加载但保持后端加载 css 正常?
- spring-cloud-stream - SCDF 流设计和定制处理器
- ansible - 无法根据条件运行任务文件以避免ansible中的块循环
- github-actions - GitHub 操作 $GITHUB_WORKSPACE envar 为什么列出空目录?
- gcc - 当默认标准是 201402L (c++14) 时 g++ 与 g++ -std=c++14 有什么不同吗?
- reactjs - 使用 Jest 反应用户测试在 BeforeEach 方法完成之前执行测试
- python - flake8 仅在 VS Code 中检查部分文件
- python - 为什么完全相同的函数在 ipython/jupyter 中表现不同?
- c# - 我正在做一个阶乘 c# 程序,但在第二次尝试后,它开始计算错误