In your Chart.js bar chart, experiencing unwanted spacing between the labels Q1 and Q2 when the corresponding data values are 0
. Even though the bars with 0
values are not visually displayed, Chart.js still reserves space for them, creating unnecessary gaps. You have already attempted to use null
, undefined
, and NaN
to remove these spaces, but the issue persists. The goal is to ensure that Q1
and Q2
appear side by side without any empty space caused by 0
values, so the chart maintains a clean and compact appearance.
var app = angular.module("chartApp", ["chart.js"]);
app.controller("ChartController", function ($scope) {
$scope.chartJsProps = {
data: [
[100, null], [110, null], [200, null], [210, null], [210, null], [220, 0],
[0, 300], [null, 290], [null, 320], [null, 340], [null, 350], [null, 370]
],
type: "bar",
colors: [
"#803690", "#00ADF9", "#46BFBD", "#fb3b3b", "#FDB45C",
"#949FB1", "#4D5360", "#4cbfbc", "#98bbcc", "#ff8d30",
"#824670", "#dcdcdc"
],
labels: ["Q1", "Q2"],
labelsCol: "quarter",
series: [],
options: {
responsive: true,
maintainAspectRatio: true,
title: {
display: true,
text: "Chart",
position: "top"
},
legend: {
display: false,
position: "bottom",
labels: {
fontColor: "rgb(66, 66, 66)",
fontSize: 12,
padding: 10,
boxWidth: 40
}
},
layout: {
padding: 20
},
tooltips: {
enabled: true,
mode: "nearest",
intersect: true
},
elements: {
point: {
radius: 3,
hoverRadius: 4,
hitRadius: 2
}
},
scales: {
xAxes: [{
type: "category",
stacked: true,
categoryPercentage: 0.8,
barPercentage: 0.9,
gridLines: { display: false },
ticks: { fontSize: 11 }
}],
yAxes: [{
stacked: true,
gridLines: { display: false },
ticks: { fontSize: 11, fontColor: "#803690", beginAtZero: false }
}]
}
},
datasetOverride: [
{
label: "jan_actual(sum)",
type: "bar",
backgroundColor: "#803690",
yAxisID: "y-axis-0",
stack: "grp_A"
},
{
label: "jan_target(sum)",
type: "bar",
backgroundColor: "#00ADF9",
yAxisID: "y-axis-0",
stack: "grp_T"
},
{
label: "feb_actual(sum)",
type: "bar",
backgroundColor: "#46BFBD",
yAxisID: "y-axis-0",
stack: "grp_A"
},
{
label: "feb_target(sum)",
type: "bar",
backgroundColor: "#fb3b3b",
yAxisID: "y-axis-0",
stack: "grp_T"
},
{
label: "mar_actual(sum)",
type: "bar",
backgroundColor: "#FDB45C",
yAxisID: "y-axis-0",
stack: "grp_A"
},
{
label: "mar_target(sum)",
type: "bar",
backgroundColor: "#949FB1",
yAxisID: "y-axis-0",
stack: "grp_T"
},
{
label: "apr_actual(sum)",
type: "bar",
backgroundColor: "#4D5360",
yAxisID: "y-axis-0",
stack: "grp_Q2_A"
},
{
label: "apr_target(sum)",
type: "bar",
backgroundColor: "#4cbfbc",
yAxisID: "y-axis-0",
stack: "grp_Q2_T"
},
{
label: "may_actual(sum)",
type: "bar",
backgroundColor: "#98bbcc",
yAxisID: "y-axis-0",
stack: "grp_Q2_A"
},
{
label: "may_target(sum)",
type: "bar",
backgroundColor: "#ff8d30",
yAxisID: "y-axis-0",
stack: "grp_Q2_T"
},
{
label: "jun_actual(sum)",
type: "bar",
backgroundColor: "#824670",
yAxisID: "y-axis-0",
stack: "grp_Q2_A"
},
{
label: "jun_target(sum)",
type: "bar",
backgroundColor: "#dcdcdc",
yAxisID: "y-axis-0",
stack: "grp_Q2_T"
}
],
labelsColType: "category"
};
$scope.chartJsProps.data = $scope.chartJsProps.data.filter(dataSet =>
dataSet.some(value => value !== 0)
);
$scope.chartJsProps.options.scales.yAxes[0].ticks = {
suggestedMin: 1, // Ensure the minimum is not zero
callback: function (value) {
return value !== 0 ? value : null; // Hide zero values
}
};
$scope.chartJsProps.datasetOverride.forEach(dataset => {
dataset.spanGaps = true;
});
});
<!DOCTYPE html>
<html lang="en" ng-app="chartApp">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AngularJS Chart</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.9/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-chart.js/1.1.1/angular-chart.min.js"></script>
</head>
<body ng-controller="ChartController">
<canvas
id="base" class="chart-base"
chart-click="onChartJsClick"
chart-data="chartJsProps.data"
chart-labels="chartJsProps.labels"
chart-colors="chartJsProps.colors"
chart-pause="'running'"
chart-dataset-override="chartJsProps.datasetOverride"
chart-options="chartJsProps.options"
chart-series="chartJsProps.series"
chart-type="chartJsProps.type">
</canvas>
<script src="app.js">
</script>
</body>
</html>
enter code here
In each category/label, there should be only 2 series.
Modify the stack
value in the datasetOverride
so that it will only be either 'A' (actual) or 'T' (target).
datasetOverride: [
{
label: 'jan_actual(sum)',
type: 'bar',
backgroundColor: '#803690',
yAxisID: 'y-axis-0',
stack: 'A',
},
{
label: 'jan_target(sum)',
type: 'bar',
backgroundColor: '#00ADF9',
yAxisID: 'y-axis-0',
stack: 'T',
},
{
label: 'feb_actual(sum)',
type: 'bar',
backgroundColor: '#46BFBD',
yAxisID: 'y-axis-0',
stack: 'A',
},
{
label: 'feb_target(sum)',
type: 'bar',
backgroundColor: '#fb3b3b',
yAxisID: 'y-axis-0',
stack: 'T',
},
{
label: 'mar_actual(sum)',
type: 'bar',
backgroundColor: '#FDB45C',
yAxisID: 'y-axis-0',
stack: 'A',
},
{
label: 'mar_target(sum)',
type: 'bar',
backgroundColor: '#949FB1',
yAxisID: 'y-axis-0',
stack: 'T',
},
{
label: 'apr_actual(sum)',
type: 'bar',
backgroundColor: '#46BFBD',
yAxisID: 'y-axis-0',
stack: 'A',
},
{
label: 'apr_target(sum)',
type: 'bar',
backgroundColor: '#4cbfbc',
yAxisID: 'y-axis-0',
stack: 'T',
},
{
label: 'may_actual(sum)',
type: 'bar',
backgroundColor: '#98bbcc',
yAxisID: 'y-axis-0',
stack: 'A',
},
{
label: 'may_target(sum)',
type: 'bar',
backgroundColor: '#ff8d30',
yAxisID: 'y-axis-0',
stack: 'T',
},
{
label: 'jun_actual(sum)',
type: 'bar',
backgroundColor: '#824670',
yAxisID: 'y-axis-0',
stack: 'A',
},
{
label: 'jun_target(sum)',
type: 'bar',
backgroundColor: '#dcdcdc',
yAxisID: 'y-axis-0',
stack: 'T',
},
]