Related
I have a chart containing data for each day of the year and I'm wanting to show the x-axis simply as months.
I've set up the following callback function which (crudely) grabs the month from the set of labels, checks to see whether it already exists and if not, returns it as an axis label
let rollingLabel;
...
function(label, index, labels) {
let _label = label.replace(/[0-9]/g, '');
if (rollingLabel != _label) {
rollingLabel = _label;
return rollingLabel;
}
}
However, it's only returning two of the expected four labels.
What's confusing me more is that if I add console.log(rollingLabel) within the conditional I can see that the variable is updating how I'd expect but it's not returning the value, or it is and the chart isn't picking it up for whatever reason. Even more confusing is that if I uncomment line 48 // return _label the chart updates with all the labels so I don't believe it's an issue with max/min settings for the chart.
If anyone has any ideas I'd be most grateful. I've been staring at it for hours now!
The expected output for the below snippet should have the following x-axis labels:
Aug | Sep | Oct | Nov
const canvas = document.getElementById('chart');
const ctx = canvas.getContext('2d');
let data = [
1,6,3,11,5,1,2,6,2,10,5,8,1,1,2,4,5,2,3,1
];
let labels = [
"Aug 1","Aug 2","Aug 3","Aug 4","Aug 5","Sep 1","Sep 2","Sep 3","Sep 4","Sep 5","Oct 1","Oct 2","Oct 3","Oct 4","Oct 5","Nov 1","Nov 2", "Nov 3","Nov 4","Nov 5"
];
let rollingLabel;
chart = new Chart(ctx, {
type: "line",
data: {
datasets: [
{
backgroundColor: '#12263A',
data: data,
pointRadius: 0
}
],
labels: labels,
},
options: {
legend: {
display: false
},
responsive: false,
scales: {
xAxes: [
{
gridLines: {
display: false
},
ticks: {
display: true,
autoSkip: true,
callback: function(label, index, labels) {
let _label = label.replace(/[0-9]/g, '');
if (rollingLabel != _label) {
rollingLabel = _label;
return rollingLabel;
}
// return _label;
}
}
}
]
},
tooltips: {
mode: "index",
intersect: false
},
hover: {
mode: "index",
intersect: false
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="chart"></canvas>
You need to define ticks.autoSkip: false on the x-axis to make it work as expected:
autoSkip: If true, automatically calculates how many labels can be shown and hides labels accordingly. Labels will be rotated up to maxRotation before skipping any. Turn autoSkip off to show all labels no matter what.
Please take a look at your amended code below:
let data = [
1,6,3,11,5,1,2,6,2,10,5,8,1,1,2,4,5,2,3,1
];
let labels = [
"Aug 1","Aug 2","Aug 3","Aug 4","Aug 5","Sep 1","Sep 2","Sep 3","Sep 4","Sep 5","Oct 1","Oct 2","Oct 3","Oct 4","Oct 5","Nov 1","Nov 2", "Nov 3","Nov 4","Nov 5"
];
let rollingLabel;
chart = new Chart('chart', {
type: "line",
data: {
datasets: [
{
backgroundColor: '#12263A',
data: data,
pointRadius: 0
}
],
labels: labels,
},
options: {
legend: {
display: false
},
responsive: false,
scales: {
xAxes: [
{
gridLines: {
display: false
},
ticks: {
display: true,
autoSkip: false,
callback: function(label, index, labels) {
let _label = label.replace(/[0-9]/g, '');
if (rollingLabel != _label) {
rollingLabel = _label;
return rollingLabel;
}
}
}
}
]
},
tooltips: {
mode: "index",
intersect: false
},
hover: {
mode: "index",
intersect: false
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="chart"></canvas>
I found a easy solution via the chart.js documentation.
const config = {
type: 'line',
data: data,
options: {
responsive: true,
plugins: {
title: {
display: true,
text: 'Chart with Tick Configuration'
}
},
scales: {
x: {
ticks: {
// For a category axis, the val is the index so the lookup via getLabelForValue is needed
callback: function(val, index) {
// Hide the label of every 2nd dataset
return index % 2 === 0 ? this.getLabelForValue(val) : '';
},
color: 'red',
}
}
}
},
};
The callback function decides what labels will be shown. Current setup shows every 2nd label, if you want to show every 3rd for example you would change:
return index % 2 === 0 ? this.getLabelForValue(val) : '';
to:
return index % 3 === 0 ? this.getLabelForValue(val) : '';
The Chart.js plugin is super, excellent, beautiful and easily customizable.
But even all this did not help me solve a few problems.
I have to create pixel perfect chart according to design shown on picture 1
I hope for your help!!
How to make those lines that without signatures be longer than those with signatures
I did the indentation from the scales to the graphs using the tickMarkLength parameter, but maybe it’s possible somehow under another, because you can see the overlap of one scale on another.
How to make the grid lines of the left and right scales coincide?
I set beforeUpdate .stepSize, but in spite of the fact that I specify that there should be 8 intervals, sometimes 8, then 9.
There is a link to my current code:
function data_generation(values_obj) {
let max_val=-900;
let min_val=0;
Object.keys(values_obj).forEach(function(key) {
chart_object={};
chart_object.label= values_obj[key].name;
chart_object.data= Object.values(values_obj[key].data);
chart_object.backgroundColor= values_obj[key].color;
if(key == 'TempOutdoor') {
chart_object.yAxisID = 'right-y-axis';
chart_object.backgroundColor= "transparent";
chart_object.pointRadius= 4;
chart_object.lineTension= 0;
chart_object.pointBackgroundColor="#FFF";
chart_object.pointBorderColor= "#60AD5E";
chart_object.borderColor= "#60AD5E";
chart_object.pointBorderWidth= 2;
chart_object.type= 'line';
} else {
chart_object.yAxisID = 'left-y-axis';
chart_object.lineTension= 0;
}
config.data.datasets.push(chart_object);
//find common min and max values
//min
if(min_val>parseFloat(values_obj[key].min)) {
min_val = parseFloat(values_obj[key].min);
}
//max
if(max_val < parseFloat(values_obj[key].max)) {
max_val = parseFloat(values_obj[key].max);
}
});
}
var config = {
drawTicks:false,
type: 'bar',
data: {
datasets: [ ],
labels: ''
},
options: {
animation: {
duration: 0
},
'legend':false,
responsive:true,
maintainAspectRatio: false,
scales: {
xAxes: [{
stacked: true,
barThickness: ($(window).width()<991.99)?14:24,
ticks: {
fontSize: ($(window).width()<991.99)?10:14,
},
gridLines : {
display : false
}
}],
yAxes: [
{
beforeUpdate: function(scale) {
//1 find max and min through all leftlabels
var left_side_list = config.data.datasets.filter(obj => {return obj.yAxisID == "left-y-axis"});
var left_side_list_data = [].concat(...Object.keys(left_side_list).map(e => left_side_list[e].data));
let max_val = Math.max.apply(Math,left_side_list_data);
let min_val = Math.min.apply(Math,left_side_list_data);
// 8 intervals - 9 lines
let left_iterval = (max_val - min_val) / 8;
//set stepsize
scale.chart.options.scales.yAxes[0].ticks.stepSize = left_iterval;
return;
},
id: 'left-y-axis',
type: 'linear',
position: 'left',
ticks: {
beginAtZero: false,
fontSize: ($(window).width()<991.99)?10:14,
callback: function(value, index, values) {
if(index % 2 == 0 || index==0) {
return ' ';
} else {
return " "+value.toFixed(0)+" ";
}
}
},
gridLines: {
drawBorder: false,
tickMarkLength: ($(window).width()<991.99)?34:84,
}
},
{
beforeUpdate: function(scale) {
//var nMaxRev = Math.max.apply(Math,scale.chart.config.data.datasets[1].data);
//get right object data
var temp_list = config.data.datasets.filter(obj => {return obj.yAxisID == "right-y-axis"});
//var temp_list = scale.chart.config.data.datasets.filter(obj => {return obj.yAxisID == "right-y-axis"});
//console.log(temp_list);
if(temp_list[0].data !== undefined || temp_list[0].data != []) {
var nMaxRev = Math.max.apply(Math, temp_list[0].data);
var nMinRev = Math.min.apply(Math, temp_list[0].data);
var nLeftTickCount = 8;
if(nMinRev<0) {
nLeftTickCount = 7;
}
var nTickInterval = (nMaxRev - nMinRev) / nLeftTickCount;
scale.chart.options.scales.yAxes[1].ticks.stepSize = nTickInterval;
}
return;
},
id: 'right-y-axis',
type: 'linear',
position: 'right',
ticks: {
beginAtZero: false,
fontSize: ($(window).width()<991.99)?10:14,
callback: function(value, index, values) {
if(index % 2 == 0 || index==0) {
return '';
} else {
return " "+value.toFixed(0);
}
}
},
gridLines: {
drawBorder: false,
tickMarkLength: ($(window).width()<991.99)?34:84,
}
}
]
}
}
};
window.onload = function() {
var data_string='{"success":true,"axis":["Пн","Вт","Ср","Чт","Пт","Сб","Вс"],"data":{"TempOutdoor":{"period_start":"2021-05-10 00:00:00","period_end":"2021-05-16 23:59:59","data":{"Пн":-4.9787234042553195,"Вт":-2.9166666666666665,"Ср":-3.3125,"Чт":2.5208333333333335,"Пт":6.84375,"Сб":0,"Вс":0},"min":"-4.98","max":"6.84","avg":"-0.26","sum":"-1.84","name":"Температура на улице","color":"#60AD5E","value_type":"instant"},"MotoHW":{"period_start":"2021-05-10 00:00:00","period_end":"2021-05-16 23:59:59","data":{"Пн":11,"Вт":15,"Ср":13,"Чт":12,"Пт":9,"Сб":0,"Вс":0},"min":"0.00","max":"15.00","avg":"8.57","sum":"60.00","name":"Мотогодини: Гаряча вода","color":"#29819D","value_type":"counter"}},"closestPeriods":{"previous":{"2021-05-03 00:00:00":"03.05 - 09.05"},"current":{"2021-05-10 00:00:00":"10.05 - 16.05"},"next":null}}';
var data = JSON.parse(data_string);
config.data.labels = data.axis;
var values_obj = data.data;
data_generation(values_obj);
//console.log(JSON.stringify(config));
var ctx = document.getElementById('StatisticsChartCanvas').getContext('2d');
window.StatisticsChart = new Chart(ctx,config);
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="chart-wrapper" style="width:548px; height:265px;">
<canvas id="StatisticsChartCanvas"></canvas>
</div>
After a huge amount of ideas, attempts and errors, I found a solution for the full customization of the scale.
For this I
Disabled the display of gridlines and ticks using property
display:false,
Wrote a plugin that draw gridlines and ticks in accordance with the design.
That's what happened
var AikGridLinePlugin = {
beforeDraw: function(chartInstance) {
var yScaleLeft = chartInstance.scales["left-y-axis"];
var yScaleRight = chartInstance.scales["right-y-axis"];
var canvas = chartInstance.chart;
var ctx = canvas.ctx;
//left axis
var left_side_list = chartInstance.data.datasets.filter(obj => {return obj.yAxisID == "left-y-axis"});
var left_side_list_data = [].concat(...Object.keys(left_side_list).map(e => left_side_list[e].data));
let left_side_list_max = Math.max.apply(Math,left_side_list_data);
let left_side_list_min = Math.min.apply(Math,left_side_list_data);
let left_iterval = (left_side_list_max - left_side_list_min) / 8;
// right axis
var right_side_list = chartInstance.data.datasets.filter(obj => {return obj.yAxisID == "right-y-axis"});
var right_side_list_data = [].concat(...Object.keys(right_side_list).map(e => right_side_list[e].data));
let right_side_list_max = Math.max.apply(Math,right_side_list_data);
let right_side_list_min = Math.min.apply(Math,right_side_list_data);
let right_iterval = (right_side_list_max - right_side_list_min) / 8;
var current_value_left = left_side_list_min,
current_value_right = right_side_list_min,
current_value_right_text=0;
for(var i=1;i<10;i++) {
ctx.lineWidth = 1;
ctx.font = "13px Roboto";
ctx.fillStyle = "#666666";
ctx.beginPath();
if(i%2==0) {
ctx.moveTo(47, yScaleLeft.getPixelForValue(current_value_left));
ctx.lineTo((canvas.width-47), yScaleLeft.getPixelForValue(current_value_left));
ctx.fillText((current_value_left>1)?current_value_left.toFixed(0):current_value_left.toFixed(1), 5, yScaleLeft.getPixelForValue(current_value_left)+5);
current_value_right_text=(current_value_right>1 || current_value_right<-1)?current_value_right.toFixed(0):current_value_right.toFixed(1);
ctx.fillText(current_value_right_text, (canvas.width-5-ctx.measureText(current_value_right_text).width), yScaleLeft.getPixelForValue(current_value_left)+5);
} else {
ctx.moveTo(15, yScaleLeft.getPixelForValue(current_value_left));
ctx.lineTo((canvas.width-15), yScaleLeft.getPixelForValue(current_value_left));
}
ctx.strokeStyle = "#91979F";
ctx.stroke();
current_value_left = current_value_left+left_iterval;
current_value_right = current_value_right+right_iterval;
}
return;
}
};
Chart.pluginService.register(AikGridLinePlugin);
function data_generation(values_obj) {
let max_val=-900;
let min_val=0;
Object.keys(values_obj).forEach(function(key) {
chart_object={};
chart_object.label= values_obj[key].name;
chart_object.data= Object.values(values_obj[key].data);
chart_object.backgroundColor= values_obj[key].color;
if(key == 'TempOutdoor') {
chart_object.yAxisID = 'right-y-axis';
chart_object.backgroundColor= "transparent";
chart_object.pointRadius= 4;
chart_object.lineTension= 0;
chart_object.pointBackgroundColor="#FFF";
chart_object.pointBorderColor= "#60AD5E";
chart_object.borderColor= "#60AD5E";
chart_object.pointBorderWidth= 2;
chart_object.type= 'line';
} else {
chart_object.yAxisID = 'left-y-axis';
chart_object.lineTension= 0;
}
config.data.datasets.push(chart_object);
//find common min and max values
//min
if(min_val>parseFloat(values_obj[key].min)) {
min_val = parseFloat(values_obj[key].min);
}
//max
if(max_val < parseFloat(values_obj[key].max)) {
max_val = parseFloat(values_obj[key].max);
}
});
}
var config = {
drawTicks:false,
type: 'bar',
data: {
datasets: [ ],
labels: ''
},
options: {
animation: {
duration: 0
},
'legend':false,
responsive:true,
maintainAspectRatio: false,
scales: {
xAxes: [{
id: 'x-axis',
stacked: true,
barThickness: ($(window).width()<991.99)?14:24,
ticks: {
fontSize: ($(window).width()<991.99)?10:14,
},
gridLines : {
display : false
}
}],
yAxes: [
{
id: 'left-y-axis',
type: 'linear',
position: 'left',
ticks: {
display:false,
},
gridLines: {
display : false,
drawBorder: false,
tickMarkLength: ($(window).width()<991.99)?34:84,
}
},
{
id: 'right-y-axis',
type: 'linear',
position: 'right',
ticks: {
display : false,
beginAtZero: false,
fontSize: ($(window).width()<991.99)?10:14,
},
gridLines: {
display : false,
drawBorder: false,
tickMarkLength: ($(window).width()<991.99)?34:84,
}
}
]
}
}
};
window.onload = function() {
var data_string='{"success":true,"axis":["Пн","Вт","Ср","Чт","Пт","Сб","Вс"],"data":{"TempOutdoor":{"period_start":"2021-05-10 00:00:00","period_end":"2021-05-16 23:59:59","data":{"Пн":-4.9787234042553195,"Вт":-2.9166666666666665,"Ср":-3.3125,"Чт":2.5208333333333335,"Пт":6.84375,"Сб":0,"Вс":0},"min":"-4.98","max":"6.84","avg":"-0.26","sum":"-1.84","name":"Температура на улице","color":"#60AD5E","value_type":"instant"},"MotoHW":{"period_start":"2021-05-10 00:00:00","period_end":"2021-05-16 23:59:59","data":{"Пн":11,"Вт":15,"Ср":13,"Чт":12,"Пт":9,"Сб":0,"Вс":0},"min":"0.00","max":"15.00","avg":"8.57","sum":"60.00","name":"Мотогодини: Гаряча вода","color":"#29819D","value_type":"counter"}},"closestPeriods":{"previous":{"2021-05-03 00:00:00":"03.05 - 09.05"},"current":{"2021-05-10 00:00:00":"10.05 - 16.05"},"next":null}}';
var data = JSON.parse(data_string);
config.data.labels = data.axis;
var values_obj = data.data;
data_generation(values_obj);
//console.log(JSON.stringify(config));
var ctx = document.getElementById('StatisticsChartCanvas').getContext('2d');
window.StatisticsChart = new Chart(ctx,config);
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="chart-wrapper" style="width:548px; height:265px;">
<canvas id="StatisticsChartCanvas"></canvas>
</div>
I am trying to hide data labels generated by the data labels plugin for small screens.
I thought that I could use the onResize property of chartjs and set display to false when the width got small. This is much like the hide labels solution found here.
Unfortunately, I've not been able to get this to work. I have the following CodePen that doesn't work.
var moneyFormat = wNumb({
decimals: 0,
thousand: ',',
prefix: '$',
negativeBefore: '-'
});
var percentFormat = wNumb({
decimals: 0,
suffix: '%',
negativeBefore: '-'
});
/*
* Unregister chartjs-plugins-datalabels - not really necessary for this use case
*/
Chart.plugins.unregister(ChartDataLabels);
var doughnutdata = {
labels: ['Housing',
'Food',
'Transportation',
'Clothing',
'Healthcare',
'Childcare',
'Misc'],
datasets: [
{
backgroundColor: [
'#9B2A00',
'#5B5C90',
'#6B8294',
'#1A6300',
'#BE0000',
'#B8A853',
'#64A856'
],
borderColor: [
'#FFFFFF',
'#FFFFFF',
'#FFFFFF',
'#FFFFFF',
'#FFFFFF',
'#FFFFFF',
'#FFFFFF'
],
data: [88480, 57680, 40050, 18430, 23860, 25840, 17490]
}
]
};
var chartOptions = {
responsive: true,
maintainAspectRatio: true,
legend: {
labels: {
boxWidth: 20
}
},
tooltips: {
callbacks: {
label: function (tooltipItem, data) {
var index = tooltipItem.index;
return data.labels[index] + ': ' + moneyFormat.to(data.datasets[0].data[index]) + '';
}
}
},
plugins: {
datalabels: {
anchor: 'end',
backgroundColor: function (context) {
return context.dataset.backgroundColor;
},
borderColor: 'white',
borderRadius: 25,
borderWidth: 1,
color: 'white',
font: {
size: 10
},
formatter: function (value, pieID) {
var sum = 0;
var dataArr = pieID.chart.data.datasets[0].data;
dataArr.map(function (data) {
sum += data;
});
var percentage = percentFormat.to((value * 100 / sum));
return percentage;
}
}
}
};
var doughnutID = document.getElementById('doughnutchart').getContext('2d');
var pieChart = new Chart(doughnutID, {
plugins: [ChartDataLabels],
type: 'doughnut',
data: doughnutdata,
options: chartOptions,
onResize: function(chart, size) {
var showLabels = (size.width < 500) ? false : true;
chart.options = {
plugins: {
datalabels: {
display: showLabels
}
}
};
}
});
Any ideas concerning what I'm doing wrong (and fixes) would be greatly appreciated.
Responsiveness can be implemented using scriptable options and in your case, you would use a function for the display option that returns false if the chart is smaller than a specific size. (Example):
options: {
plugins: {
datalabels: {
display: function(context) {
return context.chart.width > 500;
}
}
}
}
As usual, as soon as I post a question I come up with an answer. One solution using inline plugin definitions is given at the following CodePen. If you put a browser into developer mode and shrink the window to less than 540 px, the data labels will vanish.
The code is shown below:
"use strict";
/* global Chart */
/* global wNumb */
/* global ChartDataLabels */
/*
* Unregister chartjs-plugins-datalabels - not really necessary for this use case
*/
Chart.plugins.unregister(ChartDataLabels);
var moneyFormat = wNumb({
decimals: 0,
thousand: ",",
prefix: "$",
negativeBefore: "-"
});
var percentFormat = wNumb({
decimals: 0,
suffix: "%",
negativeBefore: "-"
});
var doughnutdata = {
labels: [
"Housing",
"Food",
"Transportation",
"Clothing",
"Healthcare",
"Childcare",
"Misc"
],
datasets: [
{
backgroundColor: [
"#9B2A00",
"#5B5C90",
"#6B8294",
"#1A6300",
"#BE0000",
"#B8A853",
"#64A856"
],
borderColor: [
"#FFFFFF",
"#FFFFFF",
"#FFFFFF",
"#FFFFFF",
"#FFFFFF",
"#FFFFFF",
"#FFFFFF"
],
data: [88480, 57680, 40050, 18430, 23860, 25840, 17490]
}
]
};
var chartOptions = {
responsive: true,
maintainAspectRatio: true,
legend: {
labels: {
boxWidth: 20
}
},
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
var index = tooltipItem.index;
return (
data.labels[index] +
": " +
moneyFormat.to(data.datasets[0].data[index]) +
""
);
}
}
},
plugins: {
datalabels: {
anchor: "end",
backgroundColor: function(context) {
return context.dataset.backgroundColor;
},
borderColor: "white",
borderRadius: 25,
borderWidth: 1,
color: "white",
font: {
size: 10
},
formatter: function(value, pieID) {
var sum = 0;
var dataArr = pieID.chart.data.datasets[0].data;
dataArr.map(function(data) {
sum += data;
});
var percentage = percentFormat.to(value * 100 / sum);
return percentage;
}
}
}
};
var doughnutID = document.getElementById("doughnutchart").getContext("2d");
var pieChart = new Chart(doughnutID, {
plugins: [
ChartDataLabels,
{
beforeLayout: function(chart) {
var showLabels = (chart.width) > 500 ? true : false;
chart.options.plugins.datalabels.display = showLabels;
}
},
{
onresize: function(chart) {
var showLabels = (chart.width) > 500 ? true : false;
chart.options.plugins.datalabels.display = showLabels;
}
}
],
type: "doughnut",
data: doughnutdata,
options: chartOptions
});
I hope that this is useful.
Reading up a lot on how to format the tooltip in ChartJS v2.x utilizing the tooltip callback. I've had success thus far, but find that I'm unable to define two separate formats for the two data sets I have.
As a bit more context, I have a line chart overlayed on top of a bar chart:
My bar data is numerical (in the millions, and needs to be rounded and truncated).
Example: 22345343 needs to be shown as 22M in the tooltip
My line data is a currency
Example: 146.36534 needs to shown as $146.37 in the tooptip
Here's my short WIP code thus far. This formats the tooltip to round and include the $ sign. How can I expand this so that I can separately format my bar data correctly in the tooltip?
tooltips: {
mode: 'index',
intersect: false,
callbacks: {
label: function(tooltipItem, data) {
return "$" + Number(tooltipItem.yLabel).toFixed(2).replace(/./g, function(c, i, a) {
return i > 0 && c !== "." && (a.length - i) % 3 === 0 ? "," + c : c;
});
}
}
}
You could achieve that using the following tooltips callback function ...
callbacks: {
label: function (t, d) {
if (t.datasetIndex === 0) {
return '$' + t.yLabel.toFixed(2)
} else if (t.datasetIndex === 1) {
return Math.round(+t.yLabel.toString().replace(/(\d{2})(.*)/, '$1.$2')) + 'M';
}
}
}
ᴅᴇᴍᴏ
var ctx = document.getElementById("canvas").getContext("2d");
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ["January", "February", "March", "April", "May"],
datasets: [{
type: 'line',
label: "Sales",
data: [144.36534, 146.42534, 145.23534, 147.19534, 145],
fill: false,
borderColor: '#EC932F',
backgroundColor: '#EC932F',
tension: 0,
yAxisID: 'y-axis-2'
}, {
type: 'bar',
label: "Visitor",
data: [22345343, 23345343, 24345343, 25345343, 230245343],
backgroundColor: '#71B37C',
yAxisID: 'y-axis-1'
}]
},
options: {
responsive: false,
tooltips: {
mode: 'index',
intersect: false,
callbacks: {
label: function (t, d) {
if (t.datasetIndex === 0) {
return '$' + t.yLabel.toFixed(2);
} else if (t.datasetIndex === 1) {
if (t.yLabel.toString().length === 9) {
return Math.round(+t.yLabel.toString().replace(/(\d{3})(.*)/, '$1.$2')) + 'M';
} else return Math.round(+t.yLabel.toString().replace(/(\d{2})(.*)/, '$1.$2')) + 'M';
}
}
}
},
scales: {
yAxes: [{
id: "y-axis-1",
position: "left"
}, {
id: "y-axis-2",
position: "right"
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js"></script>
<canvas id="canvas" width="400" height="190"></canvas>
Try using below code!
let DoughnutForSavingCount = {
labels: [
intl.formatMessage({ id: 'Guarantee' }),
intl.formatMessage({ id: 'ILAS' }),
intl.formatMessage({ id: 'No Idea' })
],
datasets: [
/* Outer doughnut data starts*/
{
label: 'Graph1',
data: [
_.get(getClientSavingILASPolicyData[0], 'countwithGuaranttee') >
0 &&
_.get(getClientSavingILASPolicyData[0], 'totalWithGuarantee') ===
0
? 0.1
: _.get(getClientSavingILASPolicyData[0], 'totalWithGuarantee'),
_.get(getClientSavingILASPolicyData[0], 'countwithILAS', 0) > 0 &&
_.get(getClientSavingILASPolicyData[0], 'totalWithILAS') === 0
? 0.1
: _.get(getClientSavingILASPolicyData[0], 'totalWithILAS'),
_.get(getClientSavingILASPolicyData[0], 'countNoIdea', 0) > 0 &&
_.get(getClientSavingILASPolicyData[0], 'totalWithNoIdea') === 0
? 0.1
: _.get(getClientSavingILASPolicyData[0], 'totalWithNoIdea')
],
backgroundColor: ['#8c1aff', '#BF80FF', '#E9e9e9'],
hoverBackgroundColor: ['#8c1aff', '#BF80FF', '#E9e9e9']
},
/* Outer doughnut data ends*/
/* Inner doughnut data starts*/
{
label: 'Graph2',
data: [
_.get(getClientSavingILASPolicyData[0], 'countwithGuaranttee'),
_.get(getClientSavingILASPolicyData[0], 'countwithILAS'),
_.get(getClientSavingILASPolicyData[0], 'countNoIdea')
],
backgroundColor: ['#8c1aff', '#BF80FF', '#E9e9e9'],
hoverBackgroundColor: ['#8c1aff', '#BF80FF', '#E9e9e9']
}
/* Inner doughnut data ends*/
],
borderWidth: [1]
};
let DoughnutForSavingCountConfig = {
cutoutPercentage: 70,
legend: {
display: true,
position: 'bottom',
labels: {
fontColor: '#34A0DC',
fontSize: 10,
fontFamily: 'Helvetica',
boxWidth: 10,
usePointStyle: true
}
},
responsive: true,
plugins: {
datalabels: {
display: false
}
},
tooltips: {
enabled: true,
//*****add for reference********** */
callbacks: {
label: function(tooltipItems, data) {
if (tooltipItems.datasetIndex) {
var label = data.labels[tooltipItems.index] || '';
var currentValue =
data.datasets[tooltipItems.datasetIndex].data[
tooltipItems.index
];
if (label) {
label += ': ';
}
label += currentValue == '0.1' ? '0' : currentValue;
return label;
} else {
var label = data.labels[tooltipItems.index] || '';
var currentValue =
data.datasets[tooltipItems.datasetIndex].data[
tooltipItems.index
];
if (label) {
label += ': ';
}
label += intl.formatMessage({ id: 'HKD' }) + ' ';
label +=
currentValue == '0.1'
? '0'
: currentValue
.toString()
.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
return label;
}
}
}
}
};
Thanks, GRUNT!
But since my datasets could me mixed it's better to use the yAxisID to check for the correct dataset.
tooltips: {
callbacks: {
label: function (tooltipItem, details) {
if (details.datasets[tooltipItem.datasetIndex].yAxisID == "$") {
let dataset = details.datasets[tooltipItem.datasetIndex];
let currentValue = dataset.data[tooltipItem.index];
return dataset.label + ": " + currentValue.toFixed(2) + " $";
} else {
let dataset = details.datasets[tooltipItem.datasetIndex];
let currentValue = dataset.data[tooltipItem.index];
return dataset.label + ": " + currentValue +" pieces";
}
}
}
}
How can I remove this square from tooltip?
I would prefer if I could manage to just have it one line like this: February - 2
var data = {
labels: ['January', 'February', 'March'],
datasets: [
{
data: [1,2,3]
}
]
};
var myLineChart = new Chart(document.getElementById('chart'), {
type: 'line',
data: data,
options: {
legend: {
display: false
}
}
});
Add this in your options object
tooltips: {
displayColors: false
}
Update for version 3 or greater (from #hanumanDev below):
Remove 's' from tooltips
tooltip: {
displayColors: false
}
here you go:
jsfiddle: http://jsfiddle.net/1v9fy5mz/
code:
html
<canvas id="canvas"></canvas>
js:
var ctx = document.getElementById("canvas").getContext("2d");
var data = {
labels: ['January', 'February', 'March'],
datasets: [{
data: [1, 2, 3]
}]
};
var myLineChart = new Chart(ctx, {
type: 'line',
data: data,
options: {
showAllTooltips: true,
tooltips: {
custom: function(tooltip) {
if (!tooltip) return;
// disable displaying the color box;
tooltip.displayColors = false;
},
callbacks: {
// use label callback to return the desired label
label: function(tooltipItem, data) {
return tooltipItem.xLabel + " :" + tooltipItem.yLabel;
},
// remove title
title: function(tooltipItem, data) {
return;
}
}
}
}
});
tooltips: {
displayColors: false,
callbacks: {
// use label callback to return the desired label
label: function(tooltipItem, data) {
return tooltipItem.xLabel + " :" + tooltipItem.yLabel;
},
// remove title
title: function(tooltipItem, data) {
return;
}
}
}
In version 3.8.0 of the chart.js plugin the tooltip config needs to go in the plugins config object, like this:
options: {
plugins: {
tooltip: {
displayColors: false
}
}
}