I'm trying to make a vertical stack bar plot with Chart.js. It works pretty well but for some labels (i.e., for one vertical part of the graph) I don't necessarily have strictly positive values for all the dataset points. I don't see the rectangle for those which is good, but if I hover at the wrong place, I see a 0 which bothers me.
Here is a MRE because my description was probably not very understandable:
var chart = new Chart(ctx, {
type: 'bar',
data: {
labels: ['1', '2'],
datasets: [{
label: 'a',
data: [1, 8],
backgroundColor: '#22aa99'
}, {
label: 'b',
data: [1, 2],
backgroundColor: '#109618'
}, {
label: 'c',
data: [0, 1],
backgroundColor: '#dc3912'
}, {
label: 'd',
data: [4, null],
backgroundColor: '#3366cc'
},
{
label: 'e',
data: [4, null],
backgroundColor: '#9661ca'
}]
},
options: {
responsive: false,
legend: {
position: 'right'
},
scales: {
xAxes: [{
stacked: true
}],
yAxes: [{
stacked: true
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>
<canvas id="ctx" width="700"></canvas>
I would like this not to be possible (hovering on d
on the right part even though d
is 0 (as well as e
)):
Using data: [4, null]
does not work either, since I have that now instead:
You can filter out tooltip items docs for latest chart.js, docs for v2.6.0.
For version 4 charts, a filter for positive values would look like:
options: {
// .... other options
plugins:{
tooltip:{
filter: ({parsed: {y}}) => y > 0
},
// ... other plugin options
}
}
Snippet demo:
new Chart("ctx", {
type: 'bar',
data: {
labels: ['1', '2'],
datasets: [{
label: 'a',
data: [0, 8],
backgroundColor: '#22aa99'
}, {
label: 'b',
data: [1.56, 2],
backgroundColor: '#109618'
}, {
label: 'c',
data: [0, 1],
backgroundColor: '#dc3912'
}, {
label: 'd',
data: [4, null],
backgroundColor: '#3366cc'
},
{
label: 'e',
data: [4, null],
backgroundColor: '#9661ca'
}]
},
options: {
responsive: false,
scales: {
x: {
stacked: true,
display: false
},
y: {
stacked: true,
display: false
}
},
plugins:{
tooltip:{
mode: 'nearest',
filter: ({parsed: {y}}) => y > 0
},
legend: {
position: 'right'
},
}
}
});
<canvas width="600" id="ctx"></canvas>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
while for 2.6.0 charts, the filter might be:
options: {
// .... other options
tooltips:{
filter: ({index, datasetIndex}, {datasets}) => datasets[datasetIndex].data[index] > 0
}
}
Snippet demo:
new Chart("ctx", {
type: 'bar',
data: {
labels: ['1', '2'],
datasets: [{
label: 'a',
data: [0, 8],
backgroundColor: '#22aa99'
}, {
label: 'b',
data: [1.56, 2],
backgroundColor: '#109618'
}, {
label: 'c',
data: [0, 1],
backgroundColor: '#dc3912'
}, {
label: 'd',
data: [4, null],
backgroundColor: '#3366cc'
},
{
label: 'e',
data: [4, null],
backgroundColor: '#9661ca'
}]
},
options: {
responsive: false,
legend: {
position: 'right'
},
tooltips:{
mode: 'nearest',
filter: ({index, datasetIndex}, {datasets}) => datasets[datasetIndex].data[index] > 0
},
scales: {
xAxes: [{
stacked: true,
display: false
}],
yAxes: [{
stacked: true,
display: false
}]
}
}
});
<canvas width="600" id="ctx"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>
As a side note, the issue with null
s was addressed in the very next version of the one you used, 2.7.0, and if you used version 2.7.2 or later, it was very likely you didn't ever observe the issue with zeros, since from that version bar positions were no longer rounded to integer pixel values, so a zero-height bar positioned
at an integer y
coordinate was a rare occurrence; and if its position was not integer, it would never match the mouse coordinates which are still integer. Still, the possibility exists and
the safe solution is to filter them out.