如何使用 Google 图表在条形图顶部插入点?
How to insert points on top of bar charts using Google Charts?
鉴于插图
我能够使用以下代码创建图表(没有点):
<html>
<head>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load('current', {'packages':['bar']});
google.charts.setOnLoadCallback(drawStuff);
var chart;
function drawStuff() {
var data = new google.visualization.arrayToDataTable([
['Y', 'Series 1','Series 2'],
["Element A", 44,11],
["Element B", 31,11],
["Element C", 12,11],
]);
var options = {
bars: 'horizontal', // Required for Material Bar Charts.
axes: {
x: {
0: { side: 'bottom', label: 'X'} // Top x-axis.
}
}
};
var div = document.getElementById('top_x_div');
var link = document.getElementById('url');
chart = new google.charts.Bar(div);
chart.draw(data, options);
//console.log(chart.getImageURI());
};
</script>
</head>
<body>
<div id="top_x_div" style="width: 900px; height: 500px;"></div>
</body>
</html>
如何使用 Google 图表在条形图顶部插入点?
我想到了几种方法来完成...
- 使用组合图表
- 在图表的
'ready'
事件 上手动添加点
然而,使用 material 图表无法实现这两个选项。
google.charts.Bar
首先,material图表不支持组合图表。
并且,material 图表没有手动添加点所需的 methods。
更不用说,还有几个material图表不支持的选项
参见 --> Tracking Issue for Material Chart Feature Parity #2143
所以我们必须使用经典图表...
google.visualization.BarChart
我们可以使用一个选项为 经典 图表提供 相似 的外观和感觉 material 图表...
theme: 'material'
现在解决方案...
尝试使用组合图表时,
这些点与 y 轴对齐,位于两个条形之间。
没有一个选项可以让这些点 在 条上对齐。
所以我们必须在图表的 'ready'
事件中手动添加点...
我们需要的图表很少methods...
getChartLayoutInterface()
- Returns an object containing information about the onscreen placement of the chart and its elements.
getBoundingBox(id)
- Returns an object containing the left, top, width, and height of chart element id.
getXLocation(position, optional_axis_index)
- Returns the screen x-coordinate of position relative to the chart's container.
图表的 'ready'
事件触发后,我们可以使用 --> getChartLayoutInterface()
获取布局界面
上面提到的另外两个方法是布局接口的方法
我们使用 getBoundingBox(id)
获取柱的坐标,点将放置在该柱上。
这将为我们提供 Y 坐标和点的高度。
柱的id由数据行和系列列决定。
bar#C#R // where C is the series column index, and R is the row index
我们正在提供 X 坐标,
getXLocation
将提供图表上的位置,需要将点放在我们预定的 x 轴上。
// x coordinates of points to add
var points = [
[36, 8],
[28, 8],
[10, 8],
];
// loop data rows and columns
for (var r = 0; r < data.getNumberOfRows(); r++) {
for (var c = 1; c < data.getNumberOfColumns(); c++) {
// calculate position of the point
var barBounds = chartLayout.getBoundingBox('bar#' + (c - 1) + '#' + r);
var xCoord = chartLayout.getXLocation(points[r][c - 1]);
var height = barBounds.height / 4;
var top = barBounds.top + (height * 2);
// create and add the point to the chart
var point = document.createElementNS(svgNS, 'circle');
point.setAttribute('cx', xCoord);
point.setAttribute('cy', top);
point.setAttribute('r', height);
point.setAttribute('stroke', '#ffffff');
point.setAttribute('stroke-width', height);
point.setAttribute('fill', 'transparent');
svg.appendChild(point);
}
}
请参阅以下工作片段...
var chart;
google.charts.load('current', {
packages: ['corechart']
}).then(function drawStuff() {
var data = new google.visualization.arrayToDataTable([
['Y', 'Series 1', 'Series 2'],
['Element A', 44, 11],
['Element B', 31, 11],
['Element C', 12, 11],
]);
// x coordinates of points to add
var points = [
[36, 8],
[28, 8],
[10, 8],
];
var options = {
chartArea: {
left: 128,
top: 24,
right: 128,
bottom: 72,
height: '100%',
width: '100%'
},
hAxis: {
title: 'X'
},
height: '100%',
theme: 'material',
vAxis: {
title: data.getColumnLabel(0)
},
width: '100%'
};
var div = document.getElementById('top_x_div');
//var link = document.getElementById('url');
chart = new google.visualization.BarChart(div);
google.visualization.events.addListener(chart, 'ready', function () {
// get chart layour interface and svg
var chartLayout = chart.getChartLayoutInterface();
var svg = div.getElementsByTagName('svg')[0];
var svgNS = svg.namespaceURI;
// loop data rows and columns
for (var r = 0; r < data.getNumberOfRows(); r++) {
for (var c = 1; c < data.getNumberOfColumns(); c++) {
// calculate position of the point
var barBounds = chartLayout.getBoundingBox('bar#' + (c - 1) + '#' + r);
var xCoord = chartLayout.getXLocation(points[r][c - 1]);
var height = barBounds.height / 4;
var top = barBounds.top + (height * 2);
// create and add the point to the chart
var point = document.createElementNS(svgNS, 'circle');
point.setAttribute('cx', xCoord);
point.setAttribute('cy', top);
point.setAttribute('r', height);
point.setAttribute('stroke', '#ffffff');
point.setAttribute('stroke-width', height);
point.setAttribute('fill', 'transparent');
svg.appendChild(point);
}
}
});
chart.draw(data, options);
window.addEventListener('resize', function () {
chart.draw(data, options);
});
});
#top_x_div {
height: 400px;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="top_x_div"></div>
鉴于插图
我能够使用以下代码创建图表(没有点):
<html>
<head>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load('current', {'packages':['bar']});
google.charts.setOnLoadCallback(drawStuff);
var chart;
function drawStuff() {
var data = new google.visualization.arrayToDataTable([
['Y', 'Series 1','Series 2'],
["Element A", 44,11],
["Element B", 31,11],
["Element C", 12,11],
]);
var options = {
bars: 'horizontal', // Required for Material Bar Charts.
axes: {
x: {
0: { side: 'bottom', label: 'X'} // Top x-axis.
}
}
};
var div = document.getElementById('top_x_div');
var link = document.getElementById('url');
chart = new google.charts.Bar(div);
chart.draw(data, options);
//console.log(chart.getImageURI());
};
</script>
</head>
<body>
<div id="top_x_div" style="width: 900px; height: 500px;"></div>
</body>
</html>
如何使用 Google 图表在条形图顶部插入点?
我想到了几种方法来完成...
- 使用组合图表
- 在图表的
'ready'
事件 上手动添加点
然而,使用 material 图表无法实现这两个选项。
google.charts.Bar
首先,material图表不支持组合图表。
并且,material 图表没有手动添加点所需的 methods。
更不用说,还有几个material图表不支持的选项
参见 --> Tracking Issue for Material Chart Feature Parity #2143
所以我们必须使用经典图表...
google.visualization.BarChart
我们可以使用一个选项为 经典 图表提供 相似 的外观和感觉 material 图表...
theme: 'material'
现在解决方案...
尝试使用组合图表时,
这些点与 y 轴对齐,位于两个条形之间。
没有一个选项可以让这些点 在 条上对齐。
所以我们必须在图表的 'ready'
事件中手动添加点...
我们需要的图表很少methods...
getChartLayoutInterface()
- Returns an object containing information about the onscreen placement of the chart and its elements.
getBoundingBox(id)
- Returns an object containing the left, top, width, and height of chart element id.
getXLocation(position, optional_axis_index)
- Returns the screen x-coordinate of position relative to the chart's container.
图表的 'ready'
事件触发后,我们可以使用 --> getChartLayoutInterface()
上面提到的另外两个方法是布局接口的方法
我们使用 getBoundingBox(id)
获取柱的坐标,点将放置在该柱上。
这将为我们提供 Y 坐标和点的高度。
柱的id由数据行和系列列决定。
bar#C#R // where C is the series column index, and R is the row index
我们正在提供 X 坐标,
getXLocation
将提供图表上的位置,需要将点放在我们预定的 x 轴上。
// x coordinates of points to add
var points = [
[36, 8],
[28, 8],
[10, 8],
];
// loop data rows and columns
for (var r = 0; r < data.getNumberOfRows(); r++) {
for (var c = 1; c < data.getNumberOfColumns(); c++) {
// calculate position of the point
var barBounds = chartLayout.getBoundingBox('bar#' + (c - 1) + '#' + r);
var xCoord = chartLayout.getXLocation(points[r][c - 1]);
var height = barBounds.height / 4;
var top = barBounds.top + (height * 2);
// create and add the point to the chart
var point = document.createElementNS(svgNS, 'circle');
point.setAttribute('cx', xCoord);
point.setAttribute('cy', top);
point.setAttribute('r', height);
point.setAttribute('stroke', '#ffffff');
point.setAttribute('stroke-width', height);
point.setAttribute('fill', 'transparent');
svg.appendChild(point);
}
}
请参阅以下工作片段...
var chart;
google.charts.load('current', {
packages: ['corechart']
}).then(function drawStuff() {
var data = new google.visualization.arrayToDataTable([
['Y', 'Series 1', 'Series 2'],
['Element A', 44, 11],
['Element B', 31, 11],
['Element C', 12, 11],
]);
// x coordinates of points to add
var points = [
[36, 8],
[28, 8],
[10, 8],
];
var options = {
chartArea: {
left: 128,
top: 24,
right: 128,
bottom: 72,
height: '100%',
width: '100%'
},
hAxis: {
title: 'X'
},
height: '100%',
theme: 'material',
vAxis: {
title: data.getColumnLabel(0)
},
width: '100%'
};
var div = document.getElementById('top_x_div');
//var link = document.getElementById('url');
chart = new google.visualization.BarChart(div);
google.visualization.events.addListener(chart, 'ready', function () {
// get chart layour interface and svg
var chartLayout = chart.getChartLayoutInterface();
var svg = div.getElementsByTagName('svg')[0];
var svgNS = svg.namespaceURI;
// loop data rows and columns
for (var r = 0; r < data.getNumberOfRows(); r++) {
for (var c = 1; c < data.getNumberOfColumns(); c++) {
// calculate position of the point
var barBounds = chartLayout.getBoundingBox('bar#' + (c - 1) + '#' + r);
var xCoord = chartLayout.getXLocation(points[r][c - 1]);
var height = barBounds.height / 4;
var top = barBounds.top + (height * 2);
// create and add the point to the chart
var point = document.createElementNS(svgNS, 'circle');
point.setAttribute('cx', xCoord);
point.setAttribute('cy', top);
point.setAttribute('r', height);
point.setAttribute('stroke', '#ffffff');
point.setAttribute('stroke-width', height);
point.setAttribute('fill', 'transparent');
svg.appendChild(point);
}
}
});
chart.draw(data, options);
window.addEventListener('resize', function () {
chart.draw(data, options);
});
});
#top_x_div {
height: 400px;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="top_x_div"></div>