问题
How can i display different labels under each column and also have another label for the entire group?
As you can see in the picture below i want to use fontawesome icons for each column but another label for the main group. I found other answers how to use fa icons but don't know how to position them under each bar.
The trendlines which connect distinct columns are not so important but would be great if i can find out how to add them also.
Also the chart needs to be scrollable as it can hold lots of data and the labels need to be shown. I found some examples with scroll as well.
Any info is highly appreciated. Or are there any other open source chart frameworks in which i could implement this or something similar to fit my needs?
回答1:
using google charts...
on the chart's 'ready'
event,
you can use chart method --> getChartLayoutInterface()
var chartLayout = chart.getChartLayoutInterface();
the interface has a method --> getBoundingBox()
which will return the position of requested chart element
to get the position of a bar...
var barBounds = chartLayout.getBoundingBox('bar#0#0');
where the first #0
is the series, and the second is the row,'bar#0#0'
would get the first bar on the first row
we can also get the position of the axis label...
var labelBounds = chartLayout.getBoundingBox('hAxis#0#label#0');
we can use a combination of the bar and label bounds to position the icon
we want the left
position from the bar, and the top
position from the label
see following working snippet,
a column property is used to store the icon name,
the x-axis labels are used for the group
once the icon is in position, the axis label is moved down to make room
google.charts.load('current', {
packages: ['corechart']
}).then(function () {
var data = new google.visualization.DataTable({
cols: [
{label: 'x', type: 'string'},
{label: 'file', type: 'number', p: {icon: 'fa-file'}},
{label: 'database', type: 'number', p: {icon: 'fa-database'}},
{label: 'random', type: 'number', p: {icon: 'fa-random'}},
],
rows: [
{c:[{v: 'Label 1'}, {v: 11}, {v: 6}, {v: 15}]},
{c:[{v: 'Label 2'}, {v: 8}, {v: null}, {v: 12}]},
{c:[{v: 'Label 3'}, {v: 6}, {v: 8}, {v: 18}]},
{c:[{v: 'Label 4'}, {v: null}, {v: 1}, {v: 16}]},
]
});
var options = {
bar: {
groupWidth: '50%',
width: 20
},
colors: ['#ffc107', '#d32f2f', '#00bcd4'],
height: 600,
legend: 'none',
title: 'Capacities',
width: 1000,
};
var container = document.getElementById('chart_div');
var chart = new google.visualization.ColumnChart(container);
google.visualization.events.addListener(chart, 'ready', function () {
// initialize bounds variables
var axisLabels = container.getElementsByTagName('text');
var chartLayout = chart.getChartLayoutInterface();
var chartBounds = chartLayout.getChartAreaBoundingBox();
var containerBounds = container.getBoundingClientRect();
var labelIndex;
// add icons
for (var r = 0; r < data.getNumberOfRows(); r++) {
var barBounds;
var icon;
var iconBounds;
var labelBounds = chartLayout.getBoundingBox('hAxis#0#label#' + r);
for (var c = 1; c < data.getNumberOfColumns(); c++) {
barBounds = chartLayout.getBoundingBox('bar#' + (c - 1) + '#' + r);
if (barBounds !== null) {
icon = container.appendChild(document.createElement('i'));
icon.className = 'fa ' + data.getColumnProperty(c, 'icon');
icon.style.position = 'absolute';
iconBounds = icon.getBoundingClientRect();
icon.style.top = (containerBounds.top + labelBounds.top) + 'px';
icon.style.left = (barBounds.left + containerBounds.left + (barBounds.width / 2) - (iconBounds.width / 2)) + 'px';
}
}
// move axis label down
labelIndex = -1;
Array.prototype.forEach.call(axisLabels, function(label) {
if (label.getAttribute('text-anchor') === 'middle') {
labelIndex++;
if (labelIndex === r) {
label.setAttribute('y', (parseFloat(label.getAttribute('y')) + (iconBounds.height * 2)));
}
}
});
}
});
chart.draw(data, options);
});
i {
color: #00bcd4;
}
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.3.1/css/all.css" integrity="sha384-mzrmE5qonljUremFsqc01SB46JvROS7bZs3IO2EmfFsd15uHvIt+Y8vEf7N7fWAU" crossorigin="anonymous">
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
来源:https://stackoverflow.com/questions/52216253/chart-js-how-to-display-multiple-labels-on-multi-bar-stacked-chart