chart.js 3 stacked bar chart - tooltip showing for zero values - chart.js

I have a stacked bar chart, and when I hover the mouse near the bottom of bars the tooltip shows zero values like so:
... I only want the tooltip to show on non-zero bars like this:
The JSON for the chart looks like this:
... i.e. "6-10 hours" is a dataset, and the data has 0's in it where there are no values (so it aligns with the correct bar)
Other than the tooltips, the chart functions correctly.
Is there any way to remove 0 values from tooltips?

You can define a tooltip.filter callback function that returns false for zero values, true otherwise.
Please take a look at below runnable code snippet and see how it works.
new Chart('myChart', {
type: 'bar',
data: {
labels: ['A', 'B', 'C', 'D'],
datasets: [{
label: 'Dataset',
data: [0, 2, 0, 3],
}]
},
options: {
responsive: false,
plugins: {
tooltip: {
mode: 'dataset',
filter: tooltipItem => tooltipItem.dataset.data[tooltipItem.dataIndex] > 0
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.6.2/chart.min.js"></script>
<canvas id="myChart"></canvas>

Related

Howto show absolute number in Apexcharts pie chart

The pie chart I created with Apexcharts shows relative (percentage) numbers at the circle (like the "99.9%" in the screenshot below).
Instead of the relative number I'd like to show the absolute value like what's in the tooltip (see example: "6752").
I tried a formatter function with signature function(value, {seriesIndex,dataPointIndex,w}), but value is the relative value (e.g. 99.9), dataPointIndex is undefined, seriesIndex is always 1 and w contains the whole chart config without being specific to this slice of the pie.
How can I show absolute numbers?
You have the right strategy, but probably not the right formatter. The one you need is dataLabels.formatter:
let options = {
series: [10, 20, 15],
chart: {
width: 350,
type: 'pie'
},
labels: ['Label 1', 'Label 2', 'Label 3'],
dataLabels: {
formatter: (val, { seriesIndex, w }) => w.config.series[seriesIndex] // <--- HERE
}
};
let chart = new ApexCharts(document.querySelector('#chart'), options);
chart.render();
<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
<div id="chart"></div>

How to set color of Chart.js tick label based on tick value - negative values red

I would like to set the color of y-axis tick labels in Chart.js bar and line charts based on the numeric label value. Specifically, I'd like negative values to be rendered red. Additionally rather than displaying "-1", "-2", etc., I'd like to override to display "(1)", "(2)", etc.
I've seen examples for changing tick labels based on index / position, but not conditionally based on the label value. Thanks in advance for any guidance.
You can define the scriptable option scales.x.ticks.color as an array of colors that depend on the corresponding data value each. The following definition for example shows red tick labels for every bar of a value less than 10.
scales: {
x: {
ticks: {
color: data.map(v => v < 10 ? 'red' : undefined)
}
}
}
For further information, consult Tick Configuration from the Chart.js documentation.
Please take a look at below runnable code and see how it works.
const data = [4, 12, 5, 13, 15, 8];
new Chart('myChart', {
type: 'bar',
data: {
labels: ['A', 'B', 'C', 'D', 'E', 'F'],
datasets: [{
label: 'Dataset',
data: data,
}]
},
options: {
responsive: false,
scales: {
x: {
ticks: {
color: data.map(v => v < 10 ? 'red' : undefined)
}
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js"></script>
<canvas id="myChart" height="180"></canvas>

Is it possible to show each legends aligned with each bar in chart.js

I made a horizontal bar chart using Chart.js. In default setting all the legends are shown all together like this
there is no gap among them. I want to show each legend aligned with each bar like this
I tried so many solutions but none of them worked. Is it possible to show legends right and center aligned with each bar in chart.js?
I am using Chart.js (v.3.7)
The behavior you are looking for can possibly be achieved by using the padding option in the Legend Label Configuration and trying to find the correct value.
This could look something like this:
const chart = new Chart(ctx, {
type: 'bar',
data: data,
options: {
plugins: {
legend: {
display: true,
labels: {
padding: 15 // change according to testing
}
}
}
}
});
You would usually not use a legend for this but instead label the axis directly as described in the link below.
Have a look at the documentation: https://www.chartjs.org/docs/latest/axes/cartesian/#tick-configuration
It provides an example on how to use axis labels like that:
// config
const config = {
type: 'bar',
data,
options: {
indexAxis: 'y',
scales: {
y: {
ticks: {
crossAlign: 'far',
}
}
}
}
};
// setup
const labels = ["Label 1", "Label 2", "Label 3"]
const data = {
labels: labels,
datasets: [{
label: 'My dataset',
borderWidth: 1,
data: [65, 59, 80],
}]
};

chartjs-plugin-error-bars display error-bars without displaying label on a horizontalBar chart

i am trying to add error bars to a horizontal bar chart in chartjs using the chartjs-plugin-error-bars.
It seems that the error bar is tied to a label rather than the actual data, but i dont want do display the label. is there a way to either not declare a label an still have error bars, or just hide the label.
var barChartData = {
labels: ["shouldNotBeDisplayed"],
datasets: [{
data: [
56,
],
errorBars: {
shouldNotBeDisplayed: {plus: 1, minus: 1},
}
}]
};
you can try it out here and see the chart:
https://codepen.io/reckert/pen/rNWmdeK
Thank you in advance
You can filter out tick labels by defining a yAxes.ticks.callback function as follows.
options: {
...
scales: {
yAxes: [{
ticks: {
callback: () => undefined
}
}]
},
For further details, please consult chapter Creating Custom Tick Formats from the Chart.js documentation.

Put tooltip on the middle of two bars

I'm trying to position a custom Chart.js tooltip on the middle of two bars. I made a research on the chart.js docs and different posts but didn't found any different approach than position it using the following snippet (I'm using jquery and doing a toggle class to hide/show the tooltip, please focus on the values I'm using to position the tooltip):
function setupTooltipPosition(config) {
const { tooltipElement, tooltipModel } = config;
const leftOffset = this._chart.canvas.offsetLeft;
const topOffset = this._chart.canvas.offsetTop;
tooltipElement.removeClass(tooltipSelectors.hide);
tooltipElement.css('left', `${tooltipModel.caretX - leftOffset}px`);
tooltipElement.css('top', `${tooltipModel.carteY - topOffset}px`);
}
Using this approach on this particular case I got this result:
[
I also tried using the x and y values of the tooltipModel , however , it doesn't add more sense of how to put the tooltip in the middle. If you tried to add a custom offset to put it on the middle , it works for just this case, but when you add more data it doesn't work. I can have at most 2 datasets, however, the user can add at most 10 data values that means 10 groups of bars.
The question is: There is a way to put the tooltip in the middle of the group of bars (or a single bar in case the user has just 1 dataset) using the values that Chart.js provide for tooltips? Or in other case, do you know any custom approach to have this tooltip centered?
Thanks!!
You don't specify if 'middle' means on the x- and/or y-axis. But since you wrote:
...on the middle of two bars...
I assume you mean on the x-axis. In this case you need to set the options.tooltips.mode property to index. Below is a working example.
let myChart = new Chart(document.getElementById('myChart'), {
type: 'bar',
data: {
labels: ['x', 'y', 'z'],
datasets: [{
label: '1993',
data: [50, 30, 65],
backgroundColor: '#503291'
}, {
label: '1994',
data: [60, 15, 65],
backgroundColor: '#1bbecd'
}]
},
options: {
tooltips: {
mode: 'index'
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}],
xAxes: [{
barPercentage: 1
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.min.js"></script>
<canvas id="myChart"></canvas>
For future questions please provide a MCVE as that makes it much quicker and easier to help you.