我正在尝试向 Google 烛台图表添加一些注释。我注意到有人已经问过同样的问题 (Adding annotations to Google Candlestick chart)。用户 Aperçu 回复了扩展图表和添加注释的详细解决方案,因为图表没有内置任何此类功能。但是,当我尝试此解决方案时,出现错误“TypeError: document.querySelectorAll(...) [0] 未定义”
这是我的代码:
chartPoints = [
['Budget', 0, 0, 9999, 9999, 'foo1'],
['Sales', 0, 0, 123, 123, 'foo2'],
['Backlog', 123, 123, 456, 456, 'foo3'],
['Hard Forecast', 456, 456, 789, 789, 'foo4'],
['Sales to Budget', 789, 789, 1000, 1000, 'foo5']
];
var data = google.visualization.arrayToDataTable(chartPoints, true);
data.setColumnProperty(5, 'role', 'annotation');
var options = {
legend: 'none',
bar: { groupWidth: '40%', width: '100%' },
candlestick: {
fallingColor: { strokeWidth: 0, fill: '#a52714' },
risingColor: { strokeWidth: 0, fill: '#0f9d58' }
}
};
var chart = new google.visualization.CandlestickChart(document.getElementById('chart_div'));
chart.draw(data, options);
// attempt to use Aperçu's solution
const bars = document.querySelectorAll('#chart_div svg > g:nth-child(5) > g')[0].lastChild.children // this triggers a TypeError
for (var i = 0 ; i < bars.length ; i++) {
const bar = bars[i]
const { top, left, width } = bar.getBoundingClientRect()
const hint = document.createElement('div')
hint.style.top = top + 'px'
hint.style.left = left + width + 5 + 'px'
hint.classList.add('hint')
hint.innerText = rawData.filter(t => t[1])[i][0]
document.getElementById('chart_div').append(hint)
}
我希望图表在条形旁边显示最后一条数据(即“foo1”、“foo2”等)
最佳答案
每个蜡烛图或柱形图都由一个 <rect>
元素表示
我们可以使用上升和下降颜色将条形图与图表中的其他 <rect>
元素分开
将有与数据表中的行数相同的条形
一旦找到第一个柱,我们就可以使用零的 rowIndex
从数据中提取值
我们需要找到上升/下降的值,才能知道在哪里放置注释
然后使用图表方法找到注释的位置
getChartLayoutInterface()
- Returns an object containing information about the onscreen placement of the chart and its elements.
getYLocation(position, optional_axis_index)
- Returns the screen y-coordinate of position relative to the chart's container.
请参阅以下工作片段
添加了两个注解
一为涨跌之别
另一个为具有注释作用的列中的值
google.charts.load('current', {
callback: drawChart,
packages: ['corechart']
});
function drawChart() {
var chartPoints = [
['Budget', 0, 0, 9999, 9999, 'foo1'],
['Sales', 0, 0, 123, 123, 'foo2'],
['Backlog', 123, 123, 456, 456, 'foo3'],
['Hard Forecast', 456, 456, 789, 789, 'foo4'],
['Sales to Budget', 789, 789, 1000, 1000, 'foo5']
];
var data = google.visualization.arrayToDataTable(chartPoints, true);
data.setColumnProperty(5, 'role', 'annotation');
var options = {
legend: 'none',
bar: { groupWidth: '40%', width: '100%' },
candlestick: {
fallingColor: { strokeWidth: 0, fill: '#a52714' },
risingColor: { strokeWidth: 0, fill: '#0f9d58' }
}
};
var container = document.getElementById('chart_div');
var chart = new google.visualization.CandlestickChart(container);
google.visualization.events.addListener(chart, 'ready', function () {
var annotation;
var bars;
var chartLayout;
var formatNumber;
var positionY;
var positionX;
var rowBalance;
var rowBottom;
var rowIndex;
var rowTop;
var rowValue;
var rowWidth;
chartLayout = chart.getChartLayoutInterface();
rowIndex = 0;
formatNumber = new google.visualization.NumberFormat({
pattern: '#,##0'
});
bars = container.getElementsByTagName('rect');
for (var i = 0; i < bars.length; i++) {
switch (bars[i].getAttribute('fill')) {
case '#a52714':
case '#0f9d58':
rowWidth = parseFloat(bars[i].getAttribute('width'));
if (rowWidth > 2) {
rowBottom = data.getValue(rowIndex, 1);
rowTop = data.getValue(rowIndex, 3);
rowValue = rowTop - rowBottom;
rowBalance = Math.max(rowBottom, rowTop);
positionY = chartLayout.getYLocation(rowBalance) - 6;
positionX = parseFloat(bars[i].getAttribute('x'));
// row value
annotation = container.getElementsByTagName('svg')[0].appendChild(container.getElementsByTagName('text')[0].cloneNode(true));
annotation.textContent = formatNumber.formatValue(rowValue);
annotation.setAttribute('x', (positionX + (rowWidth / 2)));
annotation.setAttribute('y', positionY);
annotation.setAttribute('font-weight', 'bold');
// annotation column
annotation = container.getElementsByTagName('svg')[0].appendChild(container.getElementsByTagName('text')[0].cloneNode(true));
annotation.textContent = data.getValue(rowIndex, 5);
annotation.setAttribute('x', (positionX + (rowWidth / 2)));
annotation.setAttribute('y', positionY - 18);
annotation.setAttribute('font-weight', 'bold');
rowIndex++;
}
break;
}
}
});
chart.draw(data, options);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
关于javascript - 向 Google 烛台图表添加注释(发布的解决方案触发 TypeError),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46064803/