Google 可视化对具有目标线的多个列堆栈进行聚类



我的目标是聚类两个或多个具有相应目标线的列堆栈。

获取此图表的最佳方法是什么?

我最初的想法是使用ComboChart。 我只能完成具有多行的单个堆栈条。

我能够尝试"条形"类型图表(在代码片段下方(并使用两个轴完成两个簇状条形堆栈,但无法获得线条。 我还认为这可能在未来仅限于两个堆栈。

任何想法?? 一如既往地感谢!

google.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Year', 'Sales', 'Expenses', 'Goal Line 1', 'Profit', 'Bonus', 'Goal Line 2'],
['2014', 1000, 400, 400, 200, 50, 500],
['2015', 1170, 460, 400, 250, 2000, 500],
['2016', 660, 1120, 400, 300, 10, 500],
['2017', 1030, 540, 400, 350, 15, 500]
]);
var options = {
bars: 'vertical',
isStacked: true,
series: {
0: { targetAxisIndex: 1 },
1: { targetAxisIndex: 1 },
2: { targetAxisIndex: 1 }, //this should be a line 
3: { targetAxisIndex: 2 },
4: { targetAxisIndex: 2 },
5: { targetAxisIndex: 2 } //this should be a line 
},
vAxes: {
},
height: 400,
xcolors: ['#1b9e77', '#d95f02', '#7570b3']
};
var chart = new google.charts.Bar(document.getElementById('chart_div'));
chart.draw(data, google.charts.Bar.convertOptions(options));
}
<script type="text/javascript" src="https://www.google.com/jsapi?autoload={'modules':[{'name':'visualization','version':'1.1','packages':['bar']}]}"></script>
<div id="chart_div"></div>
<br/>

============更新==============所以我
现在尝试了一个带有两个轴的柱形图。 我可以看到我现在有两个堆栈,但它们一个在另一个前面。您可以看到红色/橙色堆栈从蓝色/紫色堆栈后面伸出。

是否可以将堆栈1 向左偏移,将堆栈 2 向右偏移? 然后我认为直观地认为图表可以适用于我的应用程序。

google.charts.load('current', {
'packages': ['corechart']
});
google.charts.setOnLoadCallback(drawVisualization);
function drawVisualization() {
// Some raw data (not necessarily accurate)
var data = google.visualization.arrayToDataTable([
['Month', 'Ax1 line', 'Stack1 1', 'Stack1 2', 'Ax2 line', 'Stack2 1', 'Stack2 2'],
['2004/05', 10, 110, 210, 710, 810, 910],
['2005/06', 20, 120, 220, 720, 820, 920],
['2006/07', 30, 130, 230, 730, 830, 930],
['2007/08', 40, 140, 240, 740, 840, 940],
['2008/09', 50, 150, 250, 750, 850, 950]
]);
var options = {
title: 'Monthly Coffee Production by Country',
vAxis: {
title: 'Cups'
},
hAxis: {
title: 'Month'
},
seriesType: 'bars',
series: {
0: { type: 'line', targetAxisIndex: 1},
1: { type: 'bars', targetAxisIndex: 1},
	2: { type: 'bars', targetAxisIndex: 1},
3: { type: 'line', targetAxisIndex: 2},   
4: { type: 'bars', targetAxisIndex: 2},  
5: { type: 'bars', targetAxisIndex: 2}
},
isStacked: true
};
var chart = new google.visualization.ComboChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div" style="width: 900px; height: 500px;"></div>

这里的问题是,材料图表不支持组合图(添加线条(。
经典图表不支持多个堆栈。

但是,通过在列系列之间添加一个线系列,
并将一个系列移动到另一个 y 轴,堆栈将变得分开,
尽管彼此重叠。

在图表的'ready'事件中,我们可以将两个堆栈的大小减少一半,
然后将第二个堆栈向右移动。

这里最大的问题是交互性。
图表会将所有列重置回其在交互时的原始位置,例如悬停。
因此,我们必须使用MutationObserver来防止重置。

但是,还有一些小问题我没有解决。

将鼠标悬停在第一个堆栈上时,工具提示将显示在原始位置上方。
并且原始位置周围有一个亮点。

这是我到目前为止所拥有的...

google.charts.load('current', {
packages: ['corechart']
}).then(function () {
var data = google.visualization.arrayToDataTable([
['Month', 'Ax1 line', 'Stack1 1', 'Stack1 2', 'Ax2 line', 'Stack2 1', 'Stack2 2'],
['2004/05', 10, 110, 210, 710, 810, 910],
['2005/06', 20, 120, 220, 720, 820, 920],
['2006/07', 30, 130, 230, 730, 830, 930],
['2007/08', 40, 140, 240, 740, 840, 940],
['2008/09', 50, 150, 250, 750, 850, 950]
]);
var options = {
title: 'Monthly Coffee Production by Country',
vAxis: {
title: 'Cups'
},
hAxis: {
title: 'Month'
},
seriesType: 'bars',
series: {
0: { type: 'line', targetAxisIndex: 0},
1: { type: 'bars', targetAxisIndex: 0},
2: { type: 'bars', targetAxisIndex: 0},
3: { type: 'line', targetAxisIndex: 1},
4: { type: 'bars', targetAxisIndex: 1},
5: { type: 'bars', targetAxisIndex: 1}
},
isStacked: true,
legend: {
maxLines: 2,
position: 'top'
},
tooltip: {
target: 'both'
}
};
var chart = new google.visualization.ComboChart(document.getElementById('chart_div'));
var chartLayout;
var chartBounds;
var legendColors = [];
var saveCoords = {};
google.visualization.events.addListener(chart, 'ready', function () {
// init chart elements
chartLayout = chart.getChartLayoutInterface();
chartBounds = chartLayout.getChartAreaBoundingBox();
var bars = chart.getContainer().getElementsByTagName('rect');
// find legend markers
Array.prototype.forEach.call(bars, function (bar) {
var color = bar.getAttribute('fill');
var xCoord = parseFloat(bar.getAttribute('x'));
var yCoord = parseFloat(bar.getAttribute('y'));
if ((xCoord >= chartBounds.left) && (yCoord < chartBounds.top) && (color !== '#ffffff')) {
legendColors.push(color);
}
});
// find bars
Array.prototype.forEach.call(bars, function (bar, index) {
var xCoord = parseFloat(bar.getAttribute('x'));
var yCoord = parseFloat(bar.getAttribute('y'));
if ((xCoord > chartBounds.left) && (yCoord > chartBounds.top)) {
var color = bar.getAttribute('fill');
var width = parseFloat(bar.getAttribute('width')) / 2;
bar.setAttribute('width', width);
saveCoords[xCoord + yCoord] = {
width: width,
x: xCoord
};
if (legendColors.indexOf(color) > 1) {
bar.setAttribute('x', xCoord + width);
saveCoords[xCoord + yCoord].x = xCoord + width;
saveCoords[xCoord + width + yCoord] = saveCoords[xCoord + yCoord];
}
}
});
var observer = new MutationObserver(function () {
// reset bars
var bars = chart.getContainer().getElementsByTagName('rect');
Array.prototype.forEach.call(bars, function (bar, index) {
var xCoord = parseFloat(bar.getAttribute('x'));
var yCoord = parseFloat(bar.getAttribute('y'));
if ((xCoord > chartBounds.left) && (yCoord > chartBounds.top)) {
var color = bar.getAttribute('fill');
if (saveCoords.hasOwnProperty(xCoord + yCoord)) {
bar.setAttribute('width', saveCoords[xCoord + yCoord].width);
bar.setAttribute('x', saveCoords[xCoord + yCoord].x);
}
}
});
});
observer.observe(chart.getContainer(), {
childList: true,
subtree: true
});
});
chart.draw(data, options);
window.addEventListener('resize', function () {
chart.draw(data, options);
});
});
#chart_div {
height: 400px;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

注意:我还在这里发布了一个问题。目前,图例必须完全显示在一行上。若要运行此处的示例,必须运行代码段,然后单击">整页"。

最新更新