Hide first label in legend in a Chart using chart.js - javascript

I have created a stacked bar chart and i have to hide first dataset's label and its box in legend which is "Total Line", Is there anyway to hide first or any dataset's label. i have read the documentation there is a filter in options but it didn't work.
Hiding This label
Here is the html and js for chart
var ctx = document.getElementById("girth-measure-chart");
var totalLine = [115, 118, 88, 93, 103, 118, 125]
var total = [112, 115, 85, 90, 100, 115, 122]
var arms = [46, 55, 41, 41, 47, 54, 57]
var neck = [17, 20, 15, 15, 17, 20, 21]
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ["Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep"],
datasets: [{
type: 'line',
label: 'Total Line',
data: totalLine,
fill: false,
borderColor: ["#ff7899"],
legend: false,
pointBackgroundColor: "#ff151f",
pointRadius: 8,
pointHoverRadius: 8,
pointHoverBackgroundColor: "#990e14",
pointHoverBorderColor: "#6754d3"
}, {
type: 'bar',
label: 'Neck',
data: neck,
backgroundColor: "#e99449",
hoverBackgroundColor: "#d36d14"
}, {
type: 'bar',
label: 'Arms',
data: arms,
backgroundColor: "#49bae9",
hoverBackgroundColor: "#0789bf"
}, {
type: 'bar',
label: 'Total',
data: total,
backgroundColor: "#6754d3",
hoverBackgroundColor: "#260cbd"
}
]
},
options: {
legend: {
display: true,
labels: {
display: true,
boxWidth: 12,
}
},
responsive: true,
scales: {
xAxes: [{
stacked: true,
gridLines: {
display: false
},
barThickness: 25,
ticks: {
display: true,
fontFamily: "Montserrat",
fontColor: "#2c405a",
fontSize: 12
}
}],
yAxes: [{
gridLines: {
display: false
},
ticks: {
display: false,
stepSize: 10,
min: 0,
max: 150,
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.bundle.js"></script>
<div class="chart-container">
<div class="girth-measure-chart-inner" style="width: 100%;">
<canvas id="girth-measure-chart" height=""></canvas>
</div>
</div>

Use the filter method under options.
options: {
legend: {
labels: {
filter: function(legendItem, chartData) {
// return true or false based on legendItem's datasetIndex (legendItem.datasetIndex)
}
}
}
}
In your case return false for the first index and true for the rest.
var ctx = document.getElementById("girth-measure-chart");
var totalLine = [115, 118, 88, 93, 103, 118, 125]
var total = [112, 115, 85, 90, 100, 115, 122]
var arms = [46, 55, 41, 41, 47, 54, 57]
var neck = [17, 20, 15, 15, 17, 20, 21]
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ["Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep"],
datasets: [{
type: 'line',
label: 'Total Line',
data: totalLine,
fill: false,
borderColor: ["#ff7899"],
legend: false,
pointBackgroundColor: "#ff151f",
pointRadius: 8,
pointHoverRadius: 8,
pointHoverBackgroundColor: "#990e14",
pointHoverBorderColor: "#6754d3"
}, {
type: 'bar',
label: 'Neck',
data: neck,
backgroundColor: "#e99449",
hoverBackgroundColor: "#d36d14"
}, {
type: 'bar',
label: 'Arms',
data: arms,
backgroundColor: "#49bae9",
hoverBackgroundColor: "#0789bf"
}, {
type: 'bar',
label: 'Total',
data: total,
backgroundColor: "#6754d3",
hoverBackgroundColor: "#260cbd"
}
]
},
options: {
legend: {
labels: {
filter: function(legendItem, chartData) {
if (legendItem.datasetIndex === 0) {
return false;
}
return true;
}
}
},
responsive: true,
scales: {
xAxes: [{
stacked: true,
gridLines: {
display: false
},
barThickness: 25,
ticks: {
display: true,
fontFamily: "Montserrat",
fontColor: "#2c405a",
fontSize: 12
}
}],
yAxes: [{
gridLines: {
display: false
},
ticks: {
display: false,
stepSize: 10,
min: 0,
max: 150,
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.bundle.js"></script>
<div class="chart-container">
<div class="girth-measure-chart-inner" style="width: 100%;">
<canvas id="girth-measure-chart" height=""></canvas>
</div>
</div>

Related

Chartjs bar chart got clipped

I have a bar chart and I wanted to stacking the yellow bar over the purple and pink bar. Somehow the xAxes of the yellow bar start/end at the left/right corner so it got clipped on each sides. I want it to be at center like at value = 3 on the image below:
here's my code :
var ctx = document.getElementById('myChart');
var mixedChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ['1', '2', '3', '4', '5'],
datasets: [
{
label: 'Total Trip',
yAxisID: 'Total-Trip',
data: [1000, 1350, 1230, 940, 640],
type: 'line',
backgroundColor: ['transparent']
},
{
label: 'Orang',
xAxisID: 'x-B',
yAxisID: 'Orang-y',
data: [50, 46, 44, 46, 49],
backgroundColor: 'rgba(255, 206, 86)',
barThickness: 30,
clip: {
left: 50,
right: 50
}
},
{
label: 'Travel Costs',
xAxisID: 'x-A',
yAxisID: 'Orang-y',
data: [100, 96, 84, 76, 69],
backgroundColor: 'rgba(255, 99, 132)',
},
{
label: 'Travel Costs USD',
xAxisID: 'x-A',
yAxisID: 'Orang-y',
data: [150, 106, 94, 96, 99],
backgroundColor: 'rgba(155, 19, 232)',
}
]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
labels: {
render: 'value'
}
},
scales: {
yAxes: [
{
id: 'Total-Trip',
display: false,
type: 'linear',
position: 'right',
ticks: {
min: 0,
}
},
{
id: 'Orang-y',
stacked: false,
ticks: {
beginAtZero: true
},
}
],
xAxes: [
{
id: 'x-A',
},
{
id: 'x-B',
stacked: true,
clip: {
left: 50,
right: 50
}
},
]
}
}
});
or you can see here, please click Show Files and then choose bar-side-to-side.html
https://replit.com/#panjigemilang/html?v=1
I think offset and display properties will help:
{
id: 'x-B',
offset:true,
display:false
},
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>
Transaksi CBT - Non CBT
</h1>
<div class="panel">
<canvas id="myChart" width="400" height="400"></canvas>
</div>
<style>
.panel {
height: 400px;
width: 400px;
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js" integrity="sha512-s+xg36jbIujB2S2VKfpGmlC3T5V2TF3lY48DX7u2r9XzGzgPsa6wTpOQA7J9iffvdeBN0q9tKzRxVxw1JviZPg==" crossorigin="anonymous" referrerpolicy="no-referrer">
</script>
<script src="https://cdn.jsdelivr.net/gh/emn178/chartjs-plugin-labels/src/chartjs-plugin-labels.js" crossorigin="anonymous" referrerpolicy="no-referrer">
</script>
<script type="text/javascript">
var ctx = document.getElementById('myChart');
var mixedChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ['1', '2', '3', '4', '5'],
datasets: [{
label: 'Total Trip',
yAxisID: 'Total-Trip',
data: [1000, 1350, 1230, 940, 640],
type: 'line',
backgroundColor: ['transparent']
},
{
label: 'Orang',
xAxisID: 'x-B',
yAxisID: 'Orang-y',
data: [50, 46, 44, 46, 49],
backgroundColor: 'rgba(255, 206, 86)',
barThickness: 30,
},
{
label: 'Travel Costs',
xAxisID: 'x-A',
yAxisID: 'Orang-y',
data: [100, 96, 84, 76, 69],
backgroundColor: 'rgba(255, 99, 132)',
},
{
label: 'Travel Costs USD',
xAxisID: 'x-A',
yAxisID: 'Orang-y',
data: [150, 106, 94, 96, 99],
backgroundColor: 'rgba(155, 19, 232)',
}
]
},
options: {
layout: {
margin: 20
},
responsive: true,
maintainAspectRatio: false,
plugins: {
labels: {
render: 'value'
}
},
scales: {
yAxes: [{
id: 'Total-Trip',
display: false,
type: 'linear',
position: 'right',
ticks: {
beginAtZero: true
}
},
{
id: 'Orang-y',
stacked: false,
ticks: {
beginAtZero: true
}
},
],
xAxes: [{
id: 'x-A',
},
{
id: 'x-B',
offset: true,
display: false
},
]
}
}
});
</script>
</body>
</html>

Fill between two lines Chartjs

I want to draw a chart with 4 lines, with filling between 2 specific lines named Max and Min. The library I'm using is Javascript Chartjs.
I have read the chart area doc (https://www.chartjs.org/docs/latest/charts/area.html) and this answer https://stackoverflow.com/a/45398867/10250051
However, the graph still fills the whole area under the Max line instead of stopping at the min line.
$(document).ready(function(){
var ctx = document.getElementById('mixed-api').getContext('2d');
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: [1,2,3,4,5,6,7],
datasets: [
{
label: 'Median',
data: [20, 20, 20, 20, 20, 20, 20],
fill: false,
borderColor: 'rgb(0, 0, 0)',
tension: 0.1,
//backgroundColor: 'rgba(255,193,8,0)'
},
{
label: 'Min',
data: [10, 10, 10, 10, 10, 10, 10],
fill: false,
borderColor: 'red',
tension: 0.1,
//backgroundColor: 'rgba(255,193,8,0)'
},
{
label: 'Max',
data: [30, 30, 30, 30, 30, 30, 30],
fill: '-1',
borderColor: 'red',
tension: 0.1,
backgroundColor: 'rgba(255,193,8,0.5)'
},
{
label: 'Random',
data: [5, 10, 15, 20, 25, 30, 35],
fill: false,
borderColor: 'rgb(75, 192, 192)',
tension: 0.1,
//backgroundColor: 'rgba(255,193,8,0)'
}
]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
},
scaleLabel: {
display: true,
labelString: 'Energy (kW)'
}
}],
xAxes: [{
scaleLabel: {
display: true,
labelString: 'Time'
}
}],
pointLabels: {
fontStyle: 'bold',
},
plugins: {
filler: {
propagate: false
}
},
}
}
});
});
Wrong graph
Your code is working fine, only thing I can think of is that you are using an outdated version of the lib, with the latest V2 (2.9.4) release and V3 release its working as intended, see examples:
V2.9.4
var ctx = document.getElementById('chartJSContainer').getContext('2d');
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: [1, 2, 3, 4, 5, 6, 7],
datasets: [
{
label: 'Median',
data: [20, 20, 20, 20, 20, 20, 20],
fill: false,
borderColor: 'rgb(0, 0, 0)',
tension: 0.1,
//backgroundColor: 'rgba(255,193,8,0)'
},
{
label: 'Min',
data: [10, 10, 10, 10, 10, 10, 10],
fill: false,
borderColor: 'red',
tension: 0.1,
//backgroundColor: 'rgba(255,193,8,0)'
},
{
label: 'Max',
data: [30, 30, 30, 30, 30, 30, 30],
fill: '-1',
borderColor: 'red',
tension: 0.1,
backgroundColor: 'rgba(255,193,8,0.5)'
},
{
label: 'Random',
data: [5, 10, 15, 20, 25, 30, 35],
fill: false,
borderColor: 'rgb(75, 192, 192)',
tension: 0.1,
//backgroundColor: 'rgba(255,193,8,0)'
}
]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
},
scaleLabel: {
display: true,
labelString: 'Energy (kW)'
}
}],
xAxes: [{
scaleLabel: {
display: true,
labelString: 'Time'
}
}],
pointLabels: {
fontStyle: 'bold',
},
plugins: {
filler: {
propagate: false
}
},
}
}
});
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.js" integrity="sha512-hZf9Qhp3rlDJBvAKvmiG+goaaKRZA6LKUO35oK6EsM0/kjPK32Yw7URqrq3Q+Nvbbt8Usss+IekL7CRn83dYmw==" crossorigin="anonymous"></script>
</body>
V3:
var ctx = document.getElementById('chartJSContainer').getContext('2d');
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: [1, 2, 3, 4, 5, 6, 7],
datasets: [
{
label: 'Median',
data: [20, 20, 20, 20, 20, 20, 20],
fill: false,
borderColor: 'rgb(0, 0, 0)',
tension: 0.1,
//backgroundColor: 'rgba(255,193,8,0)'
},
{
label: 'Min',
data: [10, 10, 10, 10, 10, 10, 10],
fill: false,
borderColor: 'red',
tension: 0.1,
//backgroundColor: 'rgba(255,193,8,0)'
},
{
label: 'Max',
data: [30, 30, 30, 30, 30, 30, 30],
fill: '-1',
borderColor: 'red',
tension: 0.1,
backgroundColor: 'rgba(255,193,8,0.5)'
},
{
label: 'Random',
data: [5, 10, 15, 20, 25, 30, 35],
fill: false,
borderColor: 'rgb(75, 192, 192)',
tension: 0.1,
//backgroundColor: 'rgba(255,193,8,0)'
}
]
},
options: {
scales: {
y: {
ticks: {
beginAtZero: true
},
scaleLabel: {
display: true,
labelString: 'Energy (kW)'
}
},
x: {
scaleLabel: {
display: true,
labelString: 'Time'
}
},
},
pointLabels: {
fontStyle: 'bold',
},
plugins: {
filler: {
propagate: false
}
},
}
});
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.1.0/chart.js" integrity="sha512-LlFvdZpYhQdASf4aZfSpmyHD6+waYVfJRwfJrBgki7/Uh+TXMLFYcKMRim65+o3lFsfk20vrK9sJDute7BUAUw==" crossorigin="anonymous"></script>
</body>

How to show different tooltips on charts (in columns)?

How to display different tooltips on chart columns? It is necessary to output data from:
data: [220, 315, 380, 470, 520] and data: [135, 190, 180, 160, 240]
Now duplicated.
Here is my code (using chart.js):
My fiddle
https://jsfiddle.net/ebgaouv8/
Thanks in advance for any help!
You have to change your tooltip mode from label to point and dont hard code the datasetIndex. To solve deprecation issue, remove the barpercentage from the scale option and specify it in every dataset or you can configure it globally before you make the chart like this: Chart.defaults.global.datasets.bar.barPercentage = 0.5;.
var barChart = {
labels: ["2016", "2017", "2018", "2019", "2020"],
datasets: [{
label: '',
backgroundColor: "rgba(34,42,171, 0.7)",
borderColor: 'rgba(34,42,171, 1)',
borderWidth: 1,
barPercentage: 0.5,
data: [220, 315, 380, 470, 520]
},
{
label: '',
backgroundColor: "#ceb947",
barPercentage: 0.5,
data: [135, 190, 180, 160, 240]
},
]
};
var ctx4 = document.getElementById("chartJSContainer").getContext("2d");
window.newBar = new Chart(ctx4, {
type: 'bar',
data: barChart,
options: {
title: {
display: false,
fontStyle: 'bold',
text: "Figure"
},
legend: {
display: false,
position: "bottom",
padding: 20,
labels: {}
},
tooltips: {
mode: 'point',
bodySpacing: 10,
cornerRadius: 0,
titleFontSize: 16,
bodyFontSize: 14,
titleMarginBottom: 15,
callbacks: {
label: function(tooltipItem, data) {
var value = data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
value = value.toString();
value = value.split((/(?=(?:..)?$)/));
value = value.join(',');
return 'Total: ' + value + ' %';
}
}
},
scales: {
xAxes: [{
gridLines: false,
ticks: {
fontColor: 'rgb(37,39,103)',
fontSize: '14',
autoSkip: false,
maxRotation: 45,
minRotation: 45,
padding: 15
}
}],
yAxes: [{
ticks: {
fontColor: 'rgb(37,39,103)',
fontSize: '14',
beginAtZero: true,
stepSize: 100,
userCallback: function(value, index, values) {
value = value.toString();
value = value.split(/(?=(?:..)?$)/);
value = value.join(',');
return value + ' %';
}
}
}]
},
responsive: true,
}
});
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js"></script>
</body>

Hide empty bars in Grouped Stacked Bar Chart - chart.js

I am using chart.js version 2.5.0 and need to know if there any way to hide the empty bars from each group in a grouped stacked bar chart? Some data values in chart datasets can be null.
Here is what I want:
Combo Chart Type (Grouped and Stacked)
var options = {
responsive: true,
maintainAspectRatio: false,
tooltips: {
mode: 'label',
callbacks: {
label: function(tooltipItem, data) {
var dataset = data.datasets[tooltipItem.datasetIndex];
if (tooltipItem.index == 0 && tooltipItem.datasetIndex !== 0)
return null;
return dataset.label + ': ' + numeral(dataset.data[tooltipItem.index]).format('($ 0.0 a)');
}
}
},
scales: {
xAxes: [{
display: true,
gridLines: {
display: true
},
labels: {
show: true
}
}],
yAxes: [{
type: "linear",
display: true,
position: "left",
id: "y-axis-1",
gridLines: {
display: false
},
labels: {
show: false
}
}, {
type: "linear",
display: true,
gridLines: {
display: true
},
labels: {
show: true
},
ticks: {
beginAtZero: false,
userCallback: function(value) {
return numeral(value).format('($ 0.0 a)');
}
}
}, {
type: "linear",
display: false,
gridLines: {
display: false
},
labels: {
show: true
}
}, {
type: "linear",
display: false,
gridLines: {
display: false
},
labels: {
show: true
}
}, {
type: "linear",
display: false,
gridLines: {
display: false
},
labels: {
show: true
}
}, {
type: "linear",
display: false,
id: "y-axis-5",
gridLines: {
display: false
},
labels: {
show: true
}
}]
},
legend: {
labels: {
fontSize: 11,
usePointStyle: true,
padding: 15,
filter: (legendItem, chartData) => {
if (legendItem.datasetIndex > 0) return true;
}
}
}
}
var data = {
labels: ["Opening Balance", "Qtr-1", "Qtr-2", "Qtr-3", "Qtr-4"],
datasets: [{
type: 'bar',
label: "Opening Balance",
data: [1120000],
fill: true,
backgroundColor: 'rgba(243, 194, 0, .3)',
borderWidth: 1,
borderColor: '#F3C200',
hoverBackgroundColor: '#F3C200',
hoverBorderColor: '#7d6505',
stack: 'OB'
}, {
type: 'bar',
label: "Income",
data: [, 210000, 258900, 475669, 402569],
fill: true,
backgroundColor: 'rgba(42, 180, 192, .3)',
borderWidth: 1,
borderColor: '#166269',
hoverBackgroundColor: '#2ab4c0',
hoverBorderColor: '#2ab4c0',
stack: 'Income'
}, {
type: 'bar',
label: "Income Expected",
data: [, 215000, 320000, 412236, 385569],
fill: true,
backgroundColor: 'rgba(76, 135, 185, .4)',
borderWidth: 1,
borderColor: '#2a587f',
hoverBackgroundColor: '#4c87b9',
hoverBorderColor: '#2a587f',
stack: 'Income'
}, {
type: 'bar',
label: "Expenditures",
data: [, 204560, 256987, 236981, 365587],
fill: true,
backgroundColor: 'rgba(243, 82, 58, .3)',
borderWidth: 1,
borderColor: '#f3523a',
hoverBackgroundColor: '#f56954',
hoverBorderColor: '#f3523a',
stack: 'Expenditures'
}, {
type: 'bar',
label: "Expenditures Expected",
data: [, 269877, 325698, 435887, 423369],
fill: true,
backgroundColor: 'rgba(228, 58, 69, .4)',
borderWidth: 1,
borderColor: '#b32a33',
hoverBackgroundColor: '#e43a45',
hoverBorderColor: '#b32a33',
stack: 'Expenditures'
}, {
label: "Balance",
type: 'bar',
data: [, 54400, 19013, 14569, 24998],
fill: true,
borderColor: '#1ebfae',
backgroundColor: 'rgba(30, 191, 174, .3)',
borderWidth: 1,
hoverBackgroundColor: '#1ebfae',
hoverBorderColor: '#099486',
stack: 'Balance'
}]
};
new Chart(document.getElementById("fundStatus").getContext('2d'), {
type: 'bar',
data: data,
options: options
});
The fiddle: https://jsfiddle.net/q_sabawoon/atLxLg7x/
Please help.
This problem can be solved by defining two separate x-axes as follows:
xAxes: [{
id: 'opening',
display: false
},
{
id: 'quarter',
offset: true,
gridLines: {
offsetGridLines: true
}
}]
Then link the datasets with option xAxisID to their corresponding x-axis:
datasets: [{
label: "Opening Balance",
...
xAxisID: "opening"
}, {
label: "Income",
...
xAxisID: "quarter" // the same for all other datasets
}
...
Please take a look at your amended code and see how it works.
var options = {
responsive: true,
maintainAspectRatio: false,
tooltips: {
mode: 'label',
callbacks: {
label: function(tooltipItem, data) {
var dataset = data.datasets[tooltipItem.datasetIndex];
if (tooltipItem.index == 0 && tooltipItem.datasetIndex !== 0)
return null;
return dataset.label + ': ' + numeral(dataset.data[tooltipItem.index]).format('($ 0.0 a)');
}
}
},
scales: {
xAxes: [{
id: 'opening',
display: false
},
{
id: 'quarter',
offset: true,
gridLines: {
offsetGridLines: true
}
}
],
yAxes: [{
ticks: {
beginAtZero: false,
userCallback: function(value) {
return numeral(value).format('($ 0.0 a)');
}
}
}]
},
legend: {
labels: {
fontSize: 11,
usePointStyle: true,
padding: 15,
filter: (legendItem, chartData) => {
if (legendItem.datasetIndex > 0) return true;
}
}
}
}
var data = {
labels: ["Opening Balance", "Qtr-1", "Qtr-2", "Qtr-3", "Qtr-4"],
datasets: [{
label: "Opening Balance",
data: [1120000],
backgroundColor: 'rgba(243, 194, 0, .3)',
borderWidth: 1,
borderColor: '#F3C200',
hoverBackgroundColor: '#F3C200',
hoverBorderColor: '#7d6505',
stack: 'OB',
categoryPercentage: 0.6,
xAxisID: "opening"
}, {
label: "Income",
data: [,210000, 258900, 475669, 402569],
backgroundColor: 'rgba(42, 180, 192, .3)',
borderWidth: 1,
borderColor: '#166269',
hoverBackgroundColor: '#2ab4c0',
hoverBorderColor: '#2ab4c0',
stack: 'Income',
categoryPercentage: 1,
xAxisID: "quarter"
}, {
label: "Income Expected",
data: [,215000, 320000, 412236, 385569],
backgroundColor: 'rgba(76, 135, 185, .4)',
borderWidth: 1,
borderColor: '#2a587f',
hoverBackgroundColor: '#4c87b9',
hoverBorderColor: '#2a587f',
stack: 'Income',
categoryPercentage: 1,
xAxisID: "quarter"
}, {
label: "Expenditures",
data: [,204560, 256987, 236981, 365587],
backgroundColor: 'rgba(243, 82, 58, .3)',
borderWidth: 1,
borderColor: '#f3523a',
hoverBackgroundColor: '#f56954',
hoverBorderColor: '#f3523a',
stack: 'Expenditures',
categoryPercentage: 1,
xAxisID: "quarter"
}, {
label: "Expenditures Expected",
data: [,269877, 325698, 435887, 423369],
backgroundColor: 'rgba(228, 58, 69, .4)',
borderWidth: 1,
borderColor: '#b32a33',
hoverBackgroundColor: '#e43a45',
hoverBorderColor: '#b32a33',
stack: 'Expenditures',
categoryPercentage: 1,
xAxisID: "quarter"
}, {
label: "Balance",
data: [,54400, 19013, 14569, 24998],
borderColor: '#1ebfae',
backgroundColor: 'rgba(30, 191, 174, .3)',
borderWidth: 1,
hoverBackgroundColor: '#1ebfae',
hoverBorderColor: '#099486',
stack: 'Balance',
categoryPercentage: 1,
xAxisID: "quarter"
}]
};
const chart = new Chart("fundStatus", {
type: 'bar',
data: data,
options: options
});
#fundStatus {
min-height: 400px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/numeral.js/2.0.6/numeral.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.js"></script>
<canvas id="fundStatus"></canvas>

Chartjs 2 - Stacked bar and unstacked line on same chart with same y axis

I've started using the latest beta of v2 of chart.js since I need to draw a chart that contains both a stacked bar chart and an unstacked line chart on the same chart. Here's an example of what I need:
In this chart the lines are not stacked and are all showing their natural values but the bar chart is stacked and shows the combined total of the values (including some negative values).
I've managed to get the two charts drawn together but so far I've only succeeded in either having both charts stacked or I've had to use two separate y-axis which ends up with 2 scales. There's an example of the separate y-axis in this fiddle:
yAxes: [{
stacked: false,
ticks: {
beginAtZero: true
}
}, {
id: "bar-y-axis",
stacked: true,
ticks: {
beginAtZero: true
},
type: 'linear'
}]
If I remove the first y-axis then I ended up with a single scale with the only problem being that the line chart is now stacked as well.
Is there any way to draw a chart like I need using chart.js?
You can get this functionality with a combination of setting a different yAxisID (e.g. yAxisID: "bar-stacked") to each of your datasets, and then adding a second options.scales.yAxes object. So you would have this as a dataset:
{
label: 'Promoters',
backgroundColor: "#aad700",
yAxisID: "bar-stacked",
data: [
50, 44, 52, 62, 48, 58, 59, 50, 51, 52, 53, 54
]
}
and then you would add an additional yAxes (the first one will be the collection of your line datasets [no yAxisId in the example below], the second will be all of the bars you want stacked):
yAxes: [{
stacked: false,
ticks: {
beginAtZero: true,
min: 0,
max: 100
}
}, {
id: "bar-stacked",
stacked: true,
display: false, //optional if both yAxes use the same scale
ticks: {
beginAtZero: true,
min: 0,
max: 100
},
type: 'linear'
}]
Full example is as follows:
<!doctype html>
<html>
<head>
<title>Stacked Bar Chart</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.3/Chart.bundle.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<body>
<div style="width: 100%">
<canvas id="canvas"></canvas>
</div>
<script>
var barChartData = {
labels: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
datasets: [{
data: [
50, 30, 60, 70, 80, 90, 95, 70, 90, 20, 60, 95
],
type: 'line',
label: 'This Year',
fill: false,
backgroundColor: "#fff",
borderColor: "#70cbf4",
borderCapStyle: 'butt',
borderDash: [],
borderDashOffset: 0.0,
borderJoinStyle: 'miter',
lineTension: 0.3,
pointBackgroundColor: "#fff",
pointBorderColor: "#70cbf4",
pointBorderWidth: 1,
pointHoverRadius: 5,
pointHoverBackgroundColor: "#70cbf4",
pointHoverBorderColor: "#70cbf4",
pointHoverBorderWidth: 2,
pointRadius: 4,
pointHitRadius: 10
}, {
data: [
25, 40, 30, 70, 60, 50, 40, 70, 40, 80, 30, 90
],
type: 'line',
label: 'Last Year',
fill: false,
backgroundColor: "#fff",
borderColor: "#737373",
borderCapStyle: 'butt',
borderDash: [10, 10],
borderDashOffset: 0.0,
borderJoinStyle: 'miter',
lineTension: .3,
pointBackgroundColor: "#fff",
pointBorderColor: "#737373",
pointBorderWidth: 1,
pointHoverRadius: 5,
pointHoverBackgroundColor: "#737373",
pointHoverBorderColor: "#737373",
pointHoverBorderWidth: 2,
pointRadius: 4,
pointHitRadius: 10
}, {
label: 'Promoters',
backgroundColor: "#aad700",
yAxisID: "bar-y-axis",
data: [
50, 44, 52, 62, 48, 58, 59, 50, 51, 52, 53, 54
]
}, {
label: 'Passives',
backgroundColor: "#ffe100",
yAxisID: "bar-y-axis",
data: [
20, 21, 24, 25, 26, 17, 28, 19, 20, 11, 22, 33
]
}, {
label: 'Detractors',
backgroundColor: "#ef0000",
yAxisID: "bar-y-axis",
data: [
30, 35, 24, 13, 26, 25, 13, 31, 29, 37, 25, 13
]
}]
};
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myBar = new Chart(ctx, {
type: 'bar',
data: barChartData,
options: {
title: {
display: true,
text: "Chart.js Bar Chart - Stacked"
},
tooltips: {
mode: 'label'
},
responsive: true,
scales: {
xAxes: [{
stacked: true,
}],
yAxes: [{
stacked: false,
ticks: {
beginAtZero: true,
min: 0,
max: 100
}
}, {
id: "bar-y-axis",
stacked: true,
display: false, //optional
ticks: {
beginAtZero: true,
min: 0,
max: 100
},
type: 'linear'
}]
}
}
});
};
</script>
</body>
</html>
Another answer here - you can set a 'stack' identifier for the data you want to be cumulative (i.e. just the bars), and turn off 'fill' on the line graphs to draw just as a line rather than mountain range
Chart.js remove stacking
You can set the stacked property on bar datasets, so lines don't stack.
Try something like this:
data: {
datasets: [{
label: 'Line 1',
data: [],
backgroundColor: '#3788d8cc',
borderColor: '#3788d8cc',
fill: false
}, {
label: 'Stacked bar 1',
data: [],
backgroundColor: '#e51c23',
borderColor: '#e51c23',
type: 'bar',
stack: 'bar-stacked'
}, {
label: 'Line 2',
data: [],
backgroundColor: '#ff9800',
borderColor: '#ff9800',
fill: false
},
{
label: 'Stacked bar 2',
data: [],
type: 'bar',
backgroundColor: '#3f51b5',
borderColor: '#3f51b5',
stack: 'bar-stacked'
}],
labels: [],
},
options: {
maintainAspectRatio: false,
legend: {
display: true
},
scales: {
xAxes: [{
display: true
}],
yAxes: [{
display: true
}]
}
}

Categories

Resources