Stacked bar chart results in misaligned bars - javascript

I'm attempting to create a bar chart that stacks the bars for three respective data series. I'm using Chart.js with angular charts. I have the stacked property set accordingly with: stacked: true, yet the bars do not align with one another vertically.
Basically, my question is: how do I make the data from each series line up so that the bars are of uniform width but with staggered colors vertically?
Here's some of my chart configuration code:
$scope.barLabels = ['-120 to -80', '-80 to -70', '-70 to -60', '-60 to -50', '-50 to -10'];
$scope.barData = [
[3, 9, 2, 11, 5],
[6, 9, 2, 11, 5],
[2, 1, 2, 4, 5]
];
$scope.barOptions = {
legend: {
display: false
},
scales: {
yAxes: [
{
stacked: true,
display: true,
position: 'left',
ticks: {
beginAtZero: true,
min: 0
}
}
]
}
};

You should also set stacked: true for the x-axis. Your scales should, therefore, look like this:
...
scales: {
xAxes: [{
stacked: true
}],
yAxes: [{
stacked: true,
display: true,
position: 'left',
ticks: {
beginAtZero: true,
min: 0
}
}]
}
...
Have a look at Bar Chart Options and at the first code sample of the section. In this code sample, stacked: true is set for both axes, x-axis and y-axis. This will get you a stacked bar chart as you want it.

Related

Create bar chart with chart.js where space per bar is the same, overall chart size adjusted

Here are my Javascript options and two screenshots showing examples of charts I've created. The width of the bars is set to 50 pixels. But the overall size of the chart is the same, even though one chart has two bars and the other five. This means the chart with five bars is squeezed tighter than the one with two, even though the actual bars are all 50 pixels. I'm looking for more consistency between these two charts, so that the one with only two bars would be a much "shorter" chart overall, with spacing to match the one with five bars. Is this possible with chart.js?
options: {
aspectRatio: 3,
legend: {
display: false
},
scales: {
xAxes: [{
barThickness: 50,
ticks: {
beginAtZero: true,
suggestedMax: maxAxisX
}
}],
yAxes: [{
maxBarThickness: 50,
ticks: {
beginAtZero: true
}
}]
}
}
The Plugin Core API offers a range of hooks that may be used for performing custom code. You can use the beforeRender hook to define the height of the canvas parent div depending on the number of bars contained in the chart. This function must also consider the space needed on top and below the chart, especially for drawing the xAxis ticks.
plugins: [{
beforeRender: chart => {
if (!chart.config.options.nonChartAreaHeight) {
var yAxis = chart.scales['y-axis-0'];
chart.config.options.nonChartAreaHeight = chart.chart.height - (yAxis.bottom - yAxis.top);
}
const barThickness = chart.config.data.datasets[0].barThickness;
const chartAreaHeight = (chart.config.data.labels.length * barThickness * 2);
document.getElementById("chartWrapper").style.height = (chartAreaHeight + chart.config.options.nonChartAreaHeight) + 'px';
}
}],
Please note that instead of defining the option aspectRatio, we need to define maintainAspectRatio: false.
Please have a look at the code sample below that produces two charts. This solution uses the latest stable version of Chart.js (2.9.3).
new Chart('myChart', {
type: 'horizontalBar',
plugins: [{
beforeRender : chart => {
if (!chart.config.options.nonChartAreaHeight) {
var yAxis = chart.scales['y-axis-0'];
chart.config.options.nonChartAreaHeight = chart.chart.height - (yAxis.bottom - yAxis.top);
}
const barThickness = chart.config.data.datasets[0].barThickness;
const chartAreaHeight = (chart.config.data.labels.length * barThickness * 2);
document.getElementById("chartWrapper").style.height = (chartAreaHeight + chart.config.options.nonChartAreaHeight) + 'px';
}
}],
data: {
labels: ['1', '2', '3', '4'],
datasets: [{
barThickness: 20,
data: [100, 90, 80, 70]
}]
},
options: {
maintainAspectRatio: false,
legend: {
display: false
},
scales: {
xAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
div {
width: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<div id="chartWrapper">
<canvas id="myChart"></canvas>
</div>

How can I set 3 color to the same chartjs bar?

my ideia is simple: I need a a chartjs and instead only one color I need to draw different colors to the same bar like:
I am not sure if you can apply three colors to the same "bar" (which is a relative term here). But I do know you have the ability to create stacked charts like in this example here:
https://www.chartjs.org/samples/latest/charts/bar/stacked.html
The key is to pass the stacked property as true when setting your chart options. Example:
...
options: {
title: {
display: true,
text: 'Chart.js Bar Chart - Stacked'
},
tooltips: {
mode: 'index',
intersect: false
},
responsive: true,
scales: {
xAxes: [{
// MAGIC HERE
stacked: true,
}],
yAxes: [{
// AND HERE
stacked: true
}]
}
}
I hope this can help you.

Chart.js one label per stacked bar

I'm using chart.js with datalabels plugin but I'm having issues with displaying one label per stacked bar.
I have tried to access to the dataset meta to distinguish to show the labels but struggling to achieve. Help me to do that.
Please see my example here: https://jsfiddle.net/fraserr/9ezggxx5/314/
var datasets = JSON.parse('[{"username":"test name","stack":"2","label":"test name - actual","dataset":{"2018-12-17":"3","2018-12-24":"1"},"data":["3","1"],"borderColor":"#db005f","backgroundColor":"#f190b0","borderWidth":1},{"username":"test name","stack":"2","label":"test name - target","dataset":{"2018-12-17":"10","2018-12-24":"10"},"data":["10","10"],"borderColor":"#511158","backgroundColor":"#aa89ab","borderWidth":1},{"username":"Santa Claus","stack":"1","label":"Santa Claus - actual","dataset":{"2018-12-17":"2","2018-12-24":0},"data":["2",0],"borderColor":"#db005f","backgroundColor":"#f190b0","borderWidth":1},{"username":"Santa Claus","stack":"1","label":"Santa Claus - target","dataset":{"2018-12-17":"2","2018-12-24":"2"},"data":["2","2"],"borderColor":"#511158","backgroundColor":"#aa89ab","borderWidth":1}]');
new Chart('chart', {
type: 'bar',
data: {
labels: ['2018-12-17', '2018-12-24'],
datasets: datasets
},
options: {
scales: {
xAxes: [{
stacked: true,
ticks: {
beginAtZero: true,
suggestedMax: 50
}
}],
yAxes: [{
stacked: true
}]
},
plugins: {
datalabels: {
formatter: (value, ctx) => {
return ctx.dataset.username;
},
align: 'end',
anchor: 'end',
}
}
}
});
My desired result is to have "test name" on at the top of the 1st bar, "Santa Claus" on the 2nd, "test name" on 3rd and "Santa Claus" on 4th. Ideally I would always show one label per bar (even when one is bar per stack is hidden).
Thanks in advance!

Last y-axis tick gridline not showing with chart title displayed

I'm making a stacked bar graph using Chart.js, with (total stacked) values ranging from 0 to 1 (displayed as 0-100%). I'd like to have a tick/gridline displayed every 0.20/20%, from 0 to and including 1/100%.
Right now, my chart will display the last gridline at 1/100% if I don't include a graph title, but will hide the gridline (but still have the tick label) if I display the title.
Any tips to get the gridline to show?
JS fiddle here: https://jsfiddle.net/amyzlc/n99xac76/, and relevant graph code below.
Link to image of graph with title and without top gridline here.
var stackedBar = new Chart(ctx, {
type: 'bar',
data: dataChart,
options: {
title: {
display: true, //top gridline displays if false, not if true
text: 'Month-wise Adherence'
},
legend: {
position: 'bottom'
},
scales: {
xAxes: [{
stacked: true,
gridLines: {display: false}
}],
yAxes: [{
stacked: true,
gridLines: {drawBorder: false, tickMarkLength: 3},
ticks: {
min: 0,
max: 1, //not showing with title
padding: 6,
stepSize: 0.2,
callback: function(value) {
return Math.round(value*100).toString() + "%";
}
}
}]
}
}
});
Thanks!

Chart.js remove the first vertical line

Is there a way to remove the initial vertical line from the chart without removing the values?
here is how my options look like:
scales: {
yAxes: [{
ticks: {
beginAtZero: true,
maxTicksLimit: 5,
suggestedMax: maxValue
}
}],
xAxes : [{
categoryPercentage: 1.0,
display : false, // set this to false to hide the labels under the bars
gridLines: {
display: false
}
}]
},
What you want to remove is probably the border of the chart. In Chart.js v2 I was able to remove this first vertical border by setting drawBorder to false for the grid line configuration:
options: {
scales: {
yAxes: [{
gridLines: {
drawBorder: false
}
}]
}
}
In Chart.js docs it is explained in https://www.chartjs.org/docs/latest/axes/styling.html#grid-line-configuration.
Try using the chart option, scaleLineColor, and setting the color to have 0 opacity:
new Chart(ctx).Bar(data, {
scaleLineColor: 'rgba(0, 0, 0, 0)',
});
http://jsfiddle.net/wb3kcunt/33/
If you are using chartjs v2, then the showBorder option in scales.gridLines should do the trick:
options: {
scales: {
gridLines: {
showBorder: false,
}
}
}
See docs: http://www.chartjs.org/docs/#scales

Categories