chart.js how add euro symbol on each node - chart.js

i'm using chart.js 3.0
i want to add the euro sybol on each y-axis value.
with this code:
const chart = new Chart(ctx, {
type: 'line',
data: data,
options: {
scales: {
y: {
ticks: {
// Include a dollar sign in the ticks
callback: function(value, index, ticks) {
return '$' + value;
}
}
}
}
}
});
i add the dollar symbol on each y-axis value, I want to show the euro symbol (€), but if i use this code:
callback: function(value, index, ticks) {
return '€' + value;
}
i get a bad result, i get the symbol ? instead of the € symbol
how i can fix it?

Instead of using the Euro symbol, try to use its Unicode as follows.
options: {
scales: {
y: {
ticks: {
callback: v => v + '\u20AC'
}
}
}

Related

Chart.js xaxis formatter changes the value shown in the chart

I'm creating a simple visualization that shows the evolution of the Temperature in the past 24h. It is shown in the picture.
In the x axis I'm showing the hours and I'm trying to format them so that 10 -> 10:00, and so on.
However, when I include the ticks.callback in the options, the chat shows as follows: it always starts at 0:00 while the correct chat, at this particular time starts at 12.
ticks: {
callback: function(value, index, ticks) {
return `${value}:00`;
}
}
As you can see I've been able to format the y axis, but there is something different with the x axis.
This is the whole configuration of the chart, in case the error is there:
const labels = this.extractLabels(this.props.data);
const dataPoints = this.extractData(this.props.data);
const data = {
labels: labels,
datasets: [{
label: 'Avg. Temperature',
data: dataPoints,
fill: false,
borderColor: 'rgb(75, 192, 192)',
tension: 0.1
}]
};
const options = {
scales: {
y: {
beginAtZero: true,
grace: '5%',
title: {
display: true,
text: 'Temperature',
font: {
size: 16
}
},
ticks: {
callback: function(value, index, ticks) {
return value + ' ºC';
}
}
},
x: {
title: {
display: true,
text: 'Date',
font: {
size: 16
}
},
ticks: {
callback: function(value, index, ticks) {
return `${value}:00`;
}
}
}
}
};
const config = {
type: 'line',
data: data,
options: options,
};
this.temperatureChart = new Chart(this.chartRef.current, config);
As per the tip in the docs:
The category axis, which is the default x-axis for line and bar charts, uses the index as internal data format. For accessing the label, use this.getLabelForValue(value). API: getLabelForValue
so to get the right display value your callback needs to be this:
ticks: {
callback: function(value, index, ticks) {
return `${this.getLabelForValue(value)}:00`;
}
}
You can edit the labels, but in my opinion a better solution would be to implement a Time cartesian axis. This would allow you to add more data without making changes to the labels. You would need to include a time adapter to make it work.
config:
const config = {
type: 'line',
data: data,
options: {
scales: {
xAxis: {
type: 'time',
ticks: {
source: 'labels', // get ticks from given labels
},
time: {
minUnit: 'minute', // smallest time format
displayFormats: {
minute: "HH:mm",
hour: "dd/MM HH:mm",
day: "dd/MM",
week: "dd/MM",
month: "MMMM yyyy",
quarter: 'MMMM yyyy',
year: "yyyy",
}
}
},
},
}
};
Here is a fiddle to show you how this would look: JSFiddle

How can i change tick val to title in ChartJS

Hello tell please how is possible show text title instead int values, look at pic,
ChartJS ver.3
You can override the tick callback, so you check the value of the tick and instead of returning that value you return the string of text you want to return
options: {
scales: {
yAxes: [{
ticks: {
callback: function(value, index, values) {
return valueToString(value);
}
}
}]
}
}
Source: https://www.chartjs.org/docs/latest/axes/labelling.html#creating-custom-tick-formats

Pie Chart Legend - Chart.js

I need help to put the number of the pie chart in the legend
Chart Image
If i hover the chart with mouse i can see the number relative to each item
i want to display it in the legend either
the important code so far:
var tempData = {
labels: Status,
datasets: [
{
label: "Status",
data: Qtd,
backgroundColor: randColor
},
]
};
var ctx = $("#pieStatus").get(0).getContext("2d");
var chartInstance = new Chart(ctx, {
type: 'pie',
data: tempData,
options: {
title: {
display: true,
fontsize: 14,
text: 'Total de Pedidos por Situação'
},
legend: {
display: true,
position: 'bottom',
},
responsive: false
}
});
"Qtd","randColor" are "var" already with values
You need to edit the generateLabels property in your options :
options: {
legend: {
labels: {
generateLabels: function(chart) {
// Here
}
}
}
}
Since it is quite a mess to create on your own a great template. I suggest using the same function as in the source code and then edit what is needed.
Here are a small jsFiddle, where you can see how it works (edited lines - from 38 - are commented), and its result :
Maybe this is a hacky solution, but for me seems simpler.
The filter parameter
ChartJS legend options have a filter parameter. This is a function that is called for each legend item, and that returns true/false whether you want to show this item in the legend or not.
filter has 2 arguments:
legendItem : The legend item to show/omit. Its properties are described here
data : The data object passed to the chart.
The hack
Since JS passes objects by reference, and filter is called for each legend item, then you can mutate the legendItem object to show the text that you want.
legend : {
labels: {
filter: (legendItem, data) => {
// First, retrieve the data corresponding to that label
const label = legendItem.text
const labelIndex = _.findIndex(data.labels, (labelName) => labelName === label) // I'm using lodash here
const qtd = data.datasets[0].data[labelIndex]
// Second, mutate the legendItem to include the new text
legendItem.text = `${legendItem.text} : ${qtd}`
// Third, the filter method expects a bool, so return true to show the modified legendItem in the legend
return true
}
}
}
Following on from tektiv's answer, I've modified it for ES6 which my linter requires;
options: {
legend: {
labels: {
generateLabels: (chart) => {
const { data } = chart;
if (data.labels.length && data.datasets.length) {
return data.labels.map((label, i) => {
const meta = chart.getDatasetMeta(0);
const ds = data.datasets[0];
const arc = meta.data[i];
const custom = (arc && arc.custom) || {};
const { getValueAtIndexOrDefault } = Chart.helpers;
const arcOpts = chart.options.elements.arc;
const fill = custom.backgroundColor ? custom.backgroundColor : getValueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor);
const stroke = custom.borderColor ? custom.borderColor : getValueAtIndexOrDefault(ds.borderColor, i, arcOpts.borderColor);
const bw = custom.borderWidth ? custom.borderWidth : getValueAtIndexOrDefault(ds.borderWidth, i, arcOpts.borderWidth);
const value = chart.config.data.datasets[arc._datasetIndex].data[arc._index];
return {
text: `${label}: ${value}`,
fillStyle: fill,
strokeStyle: stroke,
lineWidth: bw,
hidden: Number.isNaN(ds.data[i]) || meta.data[i].hidden,
index: i,
};
});
}
return [];
},
},
},
},
I wanted to let the user select from 100+ data sets, but rather than adding/removing them from my Chart I decided to set the showLine: false on any dataset that I want hidden. Unfortunately the default legend would show all 100+. So in my solution I generate the legend manually, filtering out any dataset that has showLine: false.
Your settings will have this:
legend: {
labels: {
generateLabels: (a) => {
return a.data.labels
}
}
And you'll generate your own labels with a helper function:
function updateAllLabels() {
const myNewLabels = [];
myChart.data.datasets.forEach((element) => {
if (element.showLine) {
myNewLabels.push(generateLabel(element));
}
});
myChart.data.labels = myNewLabels;
}
And you'll generate the label with another function:
function generateLabel(data) {
return {
fillStyle: data.borderColor,
lineWidth: 1,
strokeStyle: data.borderColor,
text: data.countyName, // I attach countryName to my datasets for convenience
}
}
Now just don't forget to call the function whenever updating your chart:
updateAllLabels();
myChart.update();
Happy graphing!

how to update chartjs2 option (scale.tick.max)

I have a Bar Chart with this Option
scales: {
yAxes: [{
ticks: {
display:false,
beginAtZero:true,
max: 1150
}
}]
}
now i change the values of my only dataset
barChartData.datasets[0].data = newData;
and update the chart
window.myBar.update();
How can i also update the max scale of the yAxes??
I have to use a max scale so i cant use suggestedMax.
found the Solution myself.
to change any options of the chart:
myBar.config.options
in my case
myBar.config.options.scales.yAxes[0].ticks.max = newValue
after this you have to call
window.myBar.update();
This is my solution for Line Chart.
You can use 'beforeFit' callback function that you can find here in the docs http://www.chartjs.org/docs/latest/axes/
In scale.chart.config.data.datasets you have the chart dataset
You must set the scale.options.ticks.max
Example:
scales: {
yAxes: [{
beforeFit: function (scale) {
// See what you can set in scale parameter
console.log(scale)
// Find max value in your dataset
let maxValue = 0
if (scale.chart.config && scale.chart.config.data && scale.chart.config.data.datasets) {
scale.chart.config.data.datasets.forEach(dataset => {
if (dataset && dataset.data) {
dataset.data.forEach(value => {
if (value > maxValue) {
maxValue = value
}
})
}
})
}
// After, set max option !!!
scale.options.ticks.max = maxValue
}
}
I hope I've been helpful.
The link https://www.chartjs.org/docs/latest/developers/updates.html has pretty up to date information.
the keey is to recognise what the chart object is. :)
I struggled for half a day reading various pages until i found the right way
use the baseChartDirective to access the chart directly by doing this -> this.chart
To update scales do this:
var barChartOptions = {
legend: { display: true },
scales: { yAxes: [{ id: 'yaxis', type: 'linear', position: 'left', ticks: { min: 0, max: maxScale } }]} };
this.chart.chart.options = barChartOptions;
then update the chart:
this.chart.chart.update();
you can pretty much update everything. Just need to realise what the chart object means in this page: https://www.chartjs.org/docs/latest/developers/updates.html
:)

Chart.js V2: Add prefix or suffix to tooltip label

In Chart.js V1.0, I would add tooltipTemplate: "<%if (label){%><%=label %>: <%}%><%= '€' + value %>" to add a euro symbol as prefix to the tooltip label. However, this no longer works in V2. Does anybody know the new way to do accomplish this? I can't seem to find it.
Many thanks!
In the V2.0 the tooltipTemplate option is deprecated. Instead you can use callbacks to modify the displayed tooltips. There is a sample for the usage of callbacks here and you can find the possible callbacks in the documentation under Chart.defaults.global.tooltips
In your case I would do the following:
window.myLine = new Chart(chart, {
type: 'line',
data: lineChartData,
options: {
tooltips: {
enabled: true,
mode: 'single',
callbacks: {
label: function(tooltipItems, data) {
return tooltipItems.yLabel + ' €';
}
}
},
}
});
Don't forget to set the HTML meta tag:
<meta charset="UTF-8">
In addition to iecs' answer, if you want to return the exact default text and add some more (like a € sign in your case), use following syntax :
var ctx = $(chartCanvas);
window.chartObject = new Chart(ctx, {
type: 'bar',
data: chartData,
options: {
tooltips: {
callbacks: {
label: function(tooltipItems, data) {
return data.datasets[tooltipItems.datasetIndex].label +': ' + tooltipItems.yLabel + ' €';
}
}
}
}
});
See if it helps:
var config = {
options: {
tooltips: {
callbacks: {
title: function (tooltipItem, data) { return data.labels[tooltipItem[0].index]; },
label: function (tooltipItem, data) {
var amount = data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
var total = eval(data.datasets[tooltipItem.datasetIndex].data.join("+"));
return amount + ' / ' + total + ' ( ' + parseFloat(amount * 100 / total).toFixed(2) + '% )';
},
//footer: function(tooltipItem, data) { return 'Total: 100 planos.'; }
}
},
}
};
This set "label + value + €"
options: {
legend: {
display: false
},
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
return data.labels[tooltipItem.index] + ': ' + data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index] + '€';
}
}
}
}
If you have a stacked bar chart (and I assume a stacked line chart) and you want to format all the data points included in a single bar with a currency symbol, you can do something like this:
tooltips: {
mode: 'label',
callbacks: {
label: function (tooltipItems, data) {
return '$' + tooltipItems.yLabel;
}
}
},
Note the value of mode.
If you want to have finer control of the tool tip, for example include the labels as they appear the chart's legend, you can do something like this:
tooltips: {
mode: 'single', // this is the Chart.js default, no need to set
callbacks: {
label: function (tooltipItems, data) {
var i, label = [], l = data.datasets.length;
for (i = 0; i < l; i += 1) {
label[i] = data.datasets[i].label + ' : ' + '$' + data.datasets[i].data[tooltipItems.index];
}
return label;
}
}
},
Just updating #Luc Lérot's answer.
I had the same problem and his code helped me out but not fixed it, I had to modify it to work for me.
Using Chart.js version 2.6.0
var ctx = $(chartCanvas);
window.chartObject = new Chart(ctx, {
type: 'bar',
data: chartData,
options: {
tooltips: {
callbacks: {
label: function (tooltipItems, data) {
return data.datasets[tooltipItems.datasetIndex].label + ': ' + data.datasets[tooltipItems.datasetIndex].data[tooltipItems.index] + ' €';
}
}
}
}
});
To generalize code, let's use unitPrefix and unitSuffix for the datasets, for example:
datasets: [
{
label: 'Loss Rate',
data: [],
unitSuffix: "%",
},
{
label: 'Price',
data: [],
unitPrefix: "$",
},
Then we could have this code:
options: {
tooltips: {
callbacks: {
label: function (tooltipItem, data) {
let dataset = data.datasets[tooltipItem.datasetIndex];
let blocks = [];
if (dataset.label) {
blocks.push(${dataset.label} + ':');
}
if (dataset.unitPrefix) {
blocks.push(dataset.unitPrefix);
}
blocks.push(dataset.data[tooltipItem.index])
if (dataset.unitSuffix) {
blocks.push(dataset.unitSuffix);
}
return blocks.join(' ');
},
},
},
},
As we continue our way along the release chain, the answer once again changes in Chart.js v3.X with the updated options API.
An example of adding temperature units is as follows:
const options = {
plugins: {
tooltip: {
callbacks: {
label: (item) =>
`${item.dataset.label}: ${item.formattedValue} °C`,
},
},
},
}
Chart.js version 3.9.1
const options: ChartOptions = {
plugins: {
tooltip: {
callbacks: {
label: ({ label, formattedValue }) => `${label}:${formattedValue}g`
}
}
}
}