ChartJS Stacked Bar Chart: Showing value in opposite directions [closed] - chart.js

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I want to generate a stacked bar chart like this. How can I achieve this? Any solution will be highly appreciated.

After some research and study, finally I got a way out regarding my problem I have posted here.
public static drawDashboard2Chart(data: Dashboard2Data[], canvas: ElementRef) {
const planProfit = data.map(dataUnit => dataUnit.p_profit);
const planExpenses = data.map(dataUnit => dataUnit.p_expenses);
const planSalary = data.map(dataUnit => dataUnit.p_salary);
const factProfit = data.map(dataUnit => dataUnit.f_profit);
const factExpenses = data.map(dataUnit => dataUnit.f_expenses);
const factSalary = data.map(dataUnit => dataUnit.f_salary);
const ctx = canvas.nativeElement.getContext('2d');
const dataArray = [
{
label: 'REVENUES PLAN',
backgroundColor: '#d14035',
hoverBackgroundColor: '#d14035',
stack: '0',
data: planProfit,
datalabels: {
color: '#d14035',
}
},
{
label: 'SALARY PLAN',
backgroundColor: '#72598e',
hoverBackgroundColor: '#72598e',
stack: '1',
data: planSalary,
datalabels: {
color: '#72598e',
}
},
{
label: 'EXPENSES PLAN',
backgroundColor: '#a9bb30',
hoverBackgroundColor: '#a9bb30',
stack: '1',
data: planExpenses,
datalabels: {
color: '#a9bb30',
}
},
{
label: 'ACTUAL REVENUES',
backgroundColor: '#05a6a6',
hoverBackgroundColor: '#05a6a6',
stack: '2',
data: factProfit,
datalabels: {
color: '#05a6a6',
}
},
{
label: 'ACTUAL SALARY',
backgroundColor: '#c2718c',
hoverBackgroundColor: '#c2718c',
stack: '3',
data: factSalary,
datalabels: {
color: '#c2718c',
}
},
{
label: 'ACTUAL EXPENSES',
backgroundColor: '#eb8a3c',
hoverBackgroundColor: '#eb8a3c',
stack: '3',
data: factExpenses,
datalabels: {
color: '#eb8a3c',
}
}
]
const options = {
responsive: true,
maintainAspectRatio: false,
hover: {
animationDuration: 0
},
plugins: {
datalabels: {
display: true,
align: 'center',
anchor: 'center',
font: {
size: '18',
weight: '700'
},
rotation: 270,
formatter: function (value, context) {
return value !== 0 ? value : null;
}
}
},
legend: {
onClick: (e) => e.stopPropagation(),
display: true,
position: 'top',
labels: {
fontFamily: '\'Montserrat\', sans-serif',
fontSize: 14,
fontColor: '#000'
}
},
tooltips: {
callbacks: {
label: function (tooltipItem, data) {
return tooltipItem.yLabel.toFixed().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1 ');
}
}
},
scales: {
xAxes: [{
stacked: true,
ticks: {
fontSize: 15,
fontStyle: 'normal',
padding: 100
}
},
{
type: 'category',
offset: true,
position: 'top',
ticks: {
fontColor: "#000",
fontSize: 18,
fontStyle: 'bold',
callback: function (value, index, values) {
return "";
}
}
}
],
yAxes: [{
stacked: true,
ticks: {
fontSize: 15,
fontStyle: 'normal'
},
}],
},
animation: {
duration: 1,
onComplete: function () {
var chartInstance = this.chart,
ctx = chartInstance.ctx;
var fontSize = 15;
var fontStyle = 'normal';
ctx.font = Chart.helpers.fontString(fontSize, fontStyle, Chart.defaults.global.defaultFontFamily);
ctx.textAlign = 'center';
ctx.textBaseline = 'center';
this.data.datasets.forEach(function (dataset, i) {
var meta = chartInstance.controller.getDatasetMeta(i);
meta.data.forEach(function (bar, index) {
if (dataset.data[index] > 0) {
if(dataset.stack == '0')
{
var data = dataset.data[index].toFixed().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1 ');
ctx.save();
ctx.translate(bar._model.x, bar._model.y + bar.height());
ctx.rotate(0.5 * Math.PI);
ctx.fillText(data, 35, 0);
ctx.restore();
}
else if(dataset.stack == '1' && dataset.label == 'EXPENSES PLAN')
{
var data = dataset.data[index].toFixed().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1 ');
ctx.save();
ctx.translate(bar._model.x, bar._model.y);
ctx.rotate(-0.5 * Math.PI);
ctx.fillText(data, 35, 0);
ctx.restore();
}
else if(dataset.stack == '1' && dataset.label == 'SALARY PLAN')
{
var data = dataset.data[index].toFixed().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1 ');
ctx.save();
ctx.translate(bar._model.x, bar._model.y + bar.height());
ctx.rotate(0.5 * Math.PI);
ctx.fillText(data, 35, 0);
ctx.restore();
}
else if(dataset.stack == '2')
{
var data = dataset.data[index].toFixed().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1 ');
ctx.save();
ctx.translate(bar._model.x, bar._model.y + bar.height());
ctx.rotate(0.5 * Math.PI);
ctx.fillText(data, 35, 0);
ctx.restore();
}
else if(dataset.stack == '3' && dataset.label == 'ACTUAL EXPENSES')
{
var data = dataset.data[index].toFixed().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1 ');
ctx.save();
ctx.translate(bar._model.x, bar._model.y);
ctx.rotate(-0.5 * Math.PI);
ctx.fillText(data, 35, 0);
ctx.restore();
}
else if(dataset.stack == '3' && dataset.label == 'ACTUAL SALARY')
{
var data = dataset.data[index].toFixed().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1 ');
ctx.save();
ctx.translate(bar._model.x, bar._model.y + bar.height());
ctx.rotate(0.5 * Math.PI);
ctx.fillText(data, 35, 0);
ctx.restore();
}
}
});
});
}
}
}
new Chart(ctx, {
type: "bar",
data: {
labels: MONTHS,
datasets: dataArray
},
options: options
});
}

Related

Tooltip on each data point in Chartjs

Here is my code for putting different tooltip on each data point. I want to put different month on each point, but all the months get printed together. How do I separate them out?
function trendsChart(labels1, datasets1, chartId) {
var ctx =
document.getElementById(chartId).getContext('2d');
var MONTHS = ["January", "February", "March", "April", "May", "June"];
console.log(datasets1)
var data = {
labels: labels1,
datasets: datasets1,
};
// Tooltip
const titleTooltip = (tooltipItems) => {
let sum = 77;
MONTHS.forEach(function(tooltipItem) {
sum = tooltipItem;
})
return sum;
}
var randomScalingFactor = function() {
return (Math.random() > 0.5 ? 1.0 : 1.0) * Math.round(Math.random() * 100);
};
var line1 = [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()];
myChart = new Chart(ctx, {
type: 'line',
data: data,
options: {
maintainAspectRatio: false,
responsive: true,
scales: {
x: {
barPercentage: 1.6,
gridLines: {
drawBorder: false,
color: 'rgba(225,78,202,0.1)',
zeroLineColor: "transparent",
},
ticks: {
padding: 0,
fontColor: "#9a9a9a"
},
title: {
display: true,
text: 'Week Of'
}
},
y: {
barPercentage: 1.6,
gridLines: {
drawBorder: false,
color: 'rgba(225,78,202,0.1)',
zeroLineColor: "transparent",
},
ticks: {
padding: 0,
fontColor: "#9a9a9a"
},
stacked: false,
title: {
display: true,
text: 'Count'
}
}
},
plugins: {
tooltip: {
//yAlign: 'bottom',
callbacks: {
title: titleTooltip,
}
}
}
}
});
return myChart;
}
Inside titleTooltip in the pasted code, you replace sum with the last entry from MONTHS. The tooltip from the image however suggests that in the real code, you create an array with 77 and all entries from MONTHS, then you probably return 'Sum: ' + sum, which results in the string you can see in the tooltip.
In order to see all the months on a separate line, you could change your code as follows and return sum as an array:
const titleTooltip = ctx => {
let sum = ['Sum: 77'];
MONTHS.forEach(month => {
sum.push(month);
});
return sum;
}
The resulting tooltip still doesn't make much sense but you'll see all months on a different line. Therefore, you to extend the function titleTooltip in order to obtain the desired result.
Please take a loo at your amended code and see how it works.
function trendsChart(labels1, datasets1, chartId) {
var MONTHS = ["January", "February", "March", "April", "May", "June"];
var data = {
labels: labels1,
datasets: datasets1,
};
// Tooltip
const titleTooltip = ctx => {
let sum = ['Sum: 77'];
MONTHS.forEach(month => {
sum.push(month);
});
return sum;
}
var randomScalingFactor = function() {
return (Math.random() > 0.5 ? 1.0 : 1.0) * Math.round(Math.random() * 100);
};
var line1 = [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()];
myChart = new Chart(chartId, {
type: 'line',
data: data,
options: {
maintainAspectRatio: false,
responsive: true,
scales: {
x: {
barPercentage: 1.6,
gridLines: {
drawBorder: false,
color: 'rgba(225,78,202,0.1)',
zeroLineColor: "transparent",
},
ticks: {
padding: 0,
fontColor: "#9a9a9a"
},
title: {
display: true,
text: 'Week Of'
}
},
y: {
barPercentage: 1.6,
gridLines: {
drawBorder: false,
color: 'rgba(225,78,202,0.1)',
zeroLineColor: "transparent",
},
ticks: {
padding: 0,
fontColor: "#9a9a9a"
},
stacked: false,
title: {
display: true,
text: 'Count'
}
}
},
plugins: {
tooltip: {
//yAlign: 'bottom',
callbacks: {
title: titleTooltip,
label: ctx => ctx.label + ': ' + ctx.parsed.y
}
}
}
}
});
return myChart;
}
trendsChart(['created', 'tested', 'reviewed', 'approved'], [{ data: [1, 5, 3, 2]}], 'myChart');
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.8.0/chart.js"></script>
<canvas id="myChart"></canvas>

Chart.js - Tooltips overlapped by bar values

In bar charts, label above bars overlaps tooltip. Please see screenshots below.
Bar chart - original
Bar chart - tooltip problem
Please see my code below.
<!doctype html>
<html>
<head>
<title>Single Bar Chart</title>
<script src="Chart.min.js"></script>
<style>
canvas {
border:1px solid #367ee9;
}
#container{
width: 950px;
}
</style>
</head>
<body>
<div id="container">
<canvas id="canvas"></canvas>
</div>
<script>
var barChartData = {
labels: ["Jul 19", "Aug 19", "Sep 19", "Oct 19", "Nov 19", "Dec 19", "Jan 20", "Feb 20", "Mar 20", "Apr 20", "May 20", "Jun 20"],
datasets: [{
//label: 'Jan 20',
backgroundColor: '#367ee9',
borderColor: '#367ee9',
borderWidth: 1,
data: [33111, 27510, 27377, 14947, 4312, 7279, 70988, 2903, 29575, 65, 9861, 3416],
data_action: ["bar1_action", "bar2_action", "bar3_action", "bar4_action", "bar5_action", "bar6_action", "bar7_action", "bar8_action", "bar9_action", "bar10_action", "bar11_action", "bar12_action"],
data_alt: ["Click here to see results of bar1_alt", "bar2_alt", "bar3_alt", "bar4_alt", "bar5_alt", "bar6_alt", "bar7_alt", "bar8_alt", "bar9_alt", "bar10_alt", "bar11_alt", "bar12_alt"],
}]
};
window.onload = function() {
var ctx = document.getElementById('canvas').getContext('2d');
window.myBar = new Chart(ctx, {
type: 'bar',
data: barChartData,
options: {
responsive: true,
onHover: (event, chartElement) => {
event.target.style.cursor = chartElement[0] ? 'pointer' : 'default';
},
hover: {
animationDuration: 0,
},
animation: {
duration: 1000,
onComplete: function () {
var chartInstance = this.chart,
ctx = chartInstance.ctx;
ctx.font = Chart.helpers.fontString(Chart.defaults.global.defaultFontSize, Chart.defaults.global.defaultFontStyle, Chart.defaults.global.defaultFontFamily);
ctx.textAlign = 'center';
ctx.textBaseline = 'bottom';
//ctx.canvas.style.zIndex = 5;
this.data.datasets.forEach(function (dataset, i) {
var meta = chartInstance.controller.getDatasetMeta(i);
meta.data.forEach(function (bar, index) {
var val = dataset.data[index];
var data = "$" + val.toLocaleString();
if(val > -1){
ctx.fillText(data, bar._model.x, bar._model.y - 5);
}
else{
ctx.fillText(data, bar._model.x, bar._model.y + 14);
}
});
});
}
},
onClick:function(evt) {
var firstPoint = this.getElementAtEvent(evt)[0];
if (firstPoint) {
var value = this.data.datasets[firstPoint._datasetIndex].data_action[firstPoint._index];
alert(value);
}
},
legend: {
display: false,
position: 'top',
onHover:function(){
event.target.style.cursor = 'pointer';
},
},
title: {
display: true,
text: 'Total Benefits Exceeded ($231,345) (Claim Date)',
fontColor: '#000',
fontSize: '15',
},
tooltips: {
yAlign:'top',
displayColors: false, // hide color box
yPadding: 10,
xPadding: 10,
backgroundColor: '#fff',
borderColor: '#000',
borderWidth: 1,
bodyFontFamily: 'tahoma,Verdana,Arial, Helvetica, sans-serif',
bodyFontSize: 13,
bodyFontColor:'#000',
callbacks: {
title: function(tooltipItem, data) {
return; // hide title
},
label: function(tooltipItem, data) {
barCount = tooltipItem.index;
barIndex = tooltipItem.datasetIndex;
var label = data.datasets[barIndex].data_alt[barCount];
return label;
},
}
},
scales: {
yAxes: [{
display: false,
scaleLabel: {
display: true,
labelString: 'Denied Charges ($)',
fontColor: '#000',
fontSize: '15',
fontStyle: 'bold',
},
ticks: {
callback: function(value, index, values) {
return '$' + value.toLocaleString();
}
},
}]
}
}
});
};
</script>
</body>
</html>
Is there any way to avoid this?
I tried to find details about setting z-index in above code. But, I haven't got much help.
Other than this, the graphs work great.
Thanks,
Sandeep
At the begin of the animation.onComplete callback function, you should add the following lines:
ctx.save();
ctx.globalCompositeOperation='destination-over';
And at the end of animation.onComplete, you need to invoke ctx.restore().
For further details about ctx.globalCompositeOperation='destination-over', have a look at this answer.
Please take a look at your amended code and see how it works.
var barChartData = {
labels: ["Jul 19", "Aug 19", "Sep 19", "Oct 19", "Nov 19", "Dec 19", "Jan 20", "Feb 20", "Mar 20", "Apr 20", "May 20", "Jun 20"],
datasets: [{
//label: 'Jan 20',
backgroundColor: '#367ee9',
borderColor: '#367ee9',
borderWidth: 1,
data: [33111, 27510, 27377, 14947, 4312, 7279, 70988, 2903, 29575, 65, 9861, 3416],
data_action: ["bar1_action", "bar2_action", "bar3_action", "bar4_action", "bar5_action", "bar6_action", "bar7_action", "bar8_action", "bar9_action", "bar10_action", "bar11_action", "bar12_action"],
data_alt: ["Click here to see results of bar1_alt", "bar2_alt", "bar3_alt", "bar4_alt", "bar5_alt", "bar6_alt", "bar7_alt", "bar8_alt", "bar9_alt", "bar10_alt", "bar11_alt", "bar12_alt"],
}]
};
var ctx = document.getElementById('canvas').getContext('2d');
window.myBar = new Chart(ctx, {
type: 'bar',
data: barChartData,
options: {
responsive: true,
onHover: (event, chartElement) => {
event.target.style.cursor = chartElement[0] ? 'pointer' : 'default';
},
hover: {
animationDuration: 0,
},
animation: {
duration: 1000,
onComplete: function() {
var chartInstance = this.chart,
ctx = chartInstance.ctx;
ctx.save();
ctx.globalCompositeOperation='destination-over';
ctx.font = Chart.helpers.fontString(Chart.defaults.global.defaultFontSize, Chart.defaults.global.defaultFontStyle, Chart.defaults.global.defaultFontFamily);
ctx.textAlign = 'center';
ctx.textBaseline = 'bottom';
//ctx.canvas.style.zIndex = 5;
this.data.datasets.forEach(function(dataset, i) {
var meta = chartInstance.controller.getDatasetMeta(i);
meta.data.forEach(function(bar, index) {
var val = dataset.data[index];
var data = "$" + val.toLocaleString();
if (val > -1) {
ctx.fillText(data, bar._model.x, bar._model.y - 5);
} else {
ctx.fillText(data, bar._model.x, bar._model.y + 14);
}
});
});
ctx.restore();
}
},
onClick: function(evt) {
var firstPoint = this.getElementAtEvent(evt)[0];
if (firstPoint) {
var value = this.data.datasets[firstPoint._datasetIndex].data_action[firstPoint._index];
alert(value);
}
},
legend: {
display: false,
position: 'top',
onHover: function() {
event.target.style.cursor = 'pointer';
},
},
title: {
display: true,
text: 'Total Benefits Exceeded ($231,345) (Claim Date)',
fontColor: '#000',
fontSize: '15',
},
tooltips: {
yAlign: 'top',
displayColors: false, // hide color box
yPadding: 10,
xPadding: 10,
backgroundColor: '#fff',
borderColor: '#000',
borderWidth: 1,
bodyFontFamily: 'tahoma,Verdana,Arial, Helvetica, sans-serif',
bodyFontSize: 13,
bodyFontColor: '#000',
callbacks: {
title: function(tooltipItem, data) {
return; // hide title
},
label: function(tooltipItem, data) {
barCount = tooltipItem.index;
barIndex = tooltipItem.datasetIndex;
var label = data.datasets[barIndex].data_alt[barCount];
return label;
},
}
},
scales: {
yAxes: [{
display: false,
scaleLabel: {
display: true,
labelString: 'Denied Charges ($)',
fontColor: '#000',
fontSize: '15',
fontStyle: 'bold',
},
ticks: {
callback: function(value, index, values) {
return '$' + value.toLocaleString();
}
},
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<div id="container">
<canvas id="canvas"></canvas>
</div>

Always show last tooltip on all datasets, leave the rest to display on hover? ChartJS

I'm a little stuck on how I would achieve this since it's a little unorthodox in relation to what the plugin does.
I'm attempting for each dataset to keep the last tooltip open at all times and leave the rest to be displayed on hover.
Currently, I'm using this to keep them all displayed:
Chart.plugins.register({
beforeRender: function (chart) {
if (chart.config.options.showAllTooltips) {
chart.pluginTooltips = [];
chart.config.data.datasets.forEach(function (dataset, i) {
console.log(chart);
chart.getDatasetMeta(i).data.forEach(function (sector, j) {
console.log(sector);
chart.pluginTooltips.push(new Chart.Tooltip({
_chart: chart.chart,
_chartInstance: chart,
_data: chart.data,
_options: chart.options.tooltips,
_active: [sector]
}, chart));
});
});
chart.options.tooltips.enabled = false;
}
},
afterDraw: function (chart, easing) {
if (chart.config.options.showAllTooltips) {
if (!chart.allTooltipsOnce) {
if (easing !== 1) {
return;
}
chart.allTooltipsOnce = true;
}
chart.options.tooltips.enabled = true;
Chart.helpers.each(chart.pluginTooltips, function (tooltip) {
tooltip.initialize();
tooltip.update();
tooltip.pivot();
tooltip.transition(easing).draw();
});
chart.options.tooltips.enabled = false;
}
}
});
Is there a way to only do this for the last tooltip in each dataset?
I've come across a way to hide tooltips:
filter: function (tooltipItem, data) {
var label = data.labels[tooltipItem.index];
if (label === labels[labels.length - 1]) {
console.log(tooltipItem);
} else {
return true;
}
}
But this just doesn't display them whatsoever since it's returning false.
Ultimately it will look like this, with the other tooltips displaying on hover of the corresponding node:
Any help greatly appreciated.
I would try to use chartjs-plugin-datalabels for such task.
You can try it out directly on their pages - scriptable interactions
setup
Setting some random data:
var DATA_COUNT = 8;
var labels = [];
Utils.srand(100);
for (var i = 0; i < DATA_COUNT; ++i) {
labels.push('' + i);
}
var DATA_COUNT = 8;
var labels = [];
Utils.srand(100);
for (var i = 0; i < DATA_COUNT; ++i) {
labels.push('' + i);
}
config
Here I did some changes
{
type: 'line',
data: {
labels: labels,
datasets: [{
label: 'France',
backgroundColor: Utils.color(0),
borderColor: Utils.color(0),
data: Utils.numbers({
count: DATA_COUNT,
min: 10,
max: 100
}),
datalabels: {
align: function(context) {
return context.active ? 'start' : 'center';
}
}
}, {
label: 'Canada',
backgroundColor: Utils.color(1),
borderColor: Utils.color(1),
data: Utils.numbers({
count: DATA_COUNT,
min: 0,
max: 100
})
}, {
label: 'USA',
backgroundColor: Utils.color(2),
borderColor: Utils.color(2),
data: Utils.numbers({
count: DATA_COUNT,
min: 0,
max: 100
}),
datalabels: {
align: function(context) {
return context.active ? 'end' : 'center';
}
}
}]
},
options: {
plugins: {
datalabels: {
backgroundColor: function(context) {
return context.active ? context.dataset.backgroundColor : 'white';
},
borderColor: function(context) {
return context.dataset.backgroundColor;
},
borderRadius: function(context) {
return context.active ? 0 : 1;
},
borderWidth: 1,
color: function(context) {
return context.active ? 'white' : context.dataset.backgroundColor;
},
font: {
weight: 'bold'
},
formatter: function(value, context) {
value = Math.round(value * 100) / 100;
if (context.dataIndex === context.dataset.data.length - 1) {
return context.dataset.label + '\n' + value + '%';
} else {
return context.active
? context.dataset.label + '\n' + value + '%'
: ''
}
},
offset: 8,
padding: 0,
textAlign: 'center'
}
},
// Core options
aspectRatio: 5 / 3,
layout: {
padding: {
bottom: 16,
right: 40,
left: 8,
top: 40
}
},
hover: {
mode: 'index',
intersect: false
},
elements: {
line: {
fill: false
}
},
scales: {
yAxes: [{
stacked: true
}]
}
}
}
The main part here is:
formatter: function(value, context) {
value = Math.round(value * 100) / 100;
if (context.dataIndex === context.dataset.data.length - 1) {
return context.dataset.label + '\n' + value + '%';
} else {
return context.active
? context.dataset.label + '\n' + value + '%'
: ''
}
},
The formatter: where I show the label permanently only for context.dataIndex === context.dataset.data.length - 1.
In other cases if it is inactive I show only empty box in other case (hover) I show the information.
How does it look?
No hover
Hover with mouse
So this is the entire hmtl file with all relevant code. As I said, I am no programmer. This effort is from loads of trial and error, including several bits of code from stackoverflow questions.
<script>
$(document).ready(function () {
showtempGraph();
});
function showtempGraph()
{
{
$.post("temperaturedata.php",
function (data)
{
console.log(data);
var temptime = [];
var temp = [];
for (var i in data) {
temptime.push(data[i].timestamp);
temp.push(data[i].temperature);
}
var tempmin = Math.min(...temp);
var tempmax = Math.max(...temp);
var charttempdata = {
labels: temptime,
datasets: [
{
label: 'Temperatur',
pointRadius: 3,
backgroundColor: 'rgba(26, 137, 245, 0.2)',
borderColor: 'rgba(26, 137, 245, 1)',
hoverBackgroundColor: 'rgba(255, 255, 255, 1)',
hoverBorderColor: 'rgba(255, 255, 255, 1)',
pointBackgroundColor: 'rgba(12, 68, 122, 1)',
pointHoverBorderColor: "rgba(255, 255, 255, 0.8)",
data: temp
}
]
};
var graphtempTarget = $("#tempgraphCanvas");
var linetempGraph = new Chart(graphtempTarget, {
type: 'line',
data: charttempdata,
options: {
maintainAspectRatio: false,
tooltips: {
enabled: true,
custom: function(tooltip) {
if (!tooltip) return;
tooltip.displayColors = false;
},
callbacks: {
title: function(tooltipItems, tempdata) {
return 'Klokken: ' + tooltipItems[0].xLabel;
},
label: function(tooltipItem, tempdata) {
return 'Temperatur: ' + Number(tooltipItem.yLabel).toFixed(2) + '°C';
}
}
},
legend: {
display: false,
},
responsive: true,
scales: {
xAxes: [{
type: 'time',
time: {
displayFormats: {
hour: 'HH:mm'
},
tooltipFormat: 'HH:mm',
},
unit : 'day',
gridLines: {
color: '#999999',
lineWidth: 1
},
ticks: {
fontColor: "#fff",
}
}],
yAxes: [
{
type: 'linear',
position: 'left',
gridLines: {
color: '#999999',
lineWidth: 1
},
ticks: {
fontColor: "#fff",
}
}, {
type: 'linear',
position: "right",
afterUpdate: function(scaleInstance) {
console.dir(scaleInstance);
},
gridLines: {
color: '#999999)',
lineWidth: 0.5
},
ticks: {
stepSize: tempmax - tempmin,
min: tempmin,
max: tempmax,
mirror: true,
padding: -10,
fontColor: "#fff",
fontSize: 18,
callback: function(value) {
return value + '°C';
}
},
scaleLabel: {
display: true,
labelString: '°C',
fontColor: "#fff",
fontSize: 14
}
}]
},
}
});
});
}
}
</script>

Chart.js line graph-removing labels on the line

I am using chart.js with C# and Ajax calls. I am trying to develop my first line graph. I have circles, on the line, for each data point. However, each data point is showing the value inside the circle. How do I remove this value, so it is just a blue dot?
I am using the DataLabels library. I tried many options yesterday but could not remove the numbers from the points on the line.
This is the full function for my line graph:-
function LoadChart5() {
var processType = "";
var sdt = $("[id*=startDate]").val();
var edt = $("[id*=endDate]").val();
var sd = moment(sdt, "DD-MM-YYYY").format("YYYY-MM-DD");
var ed = moment(edt, "DD-MM-YYYY").format("YYYY-MM-DD");
$('[id*=processType] :selected').each(function (i, selected) {
if (i == 0) {
processType = $(selected).val();
}
else {
processType = processType + "\\',\\'" + $(selected).val();
}
});
$.ajax({
type: "POST",
url: "ewDashboard.aspx/GetChart5",
data: "{sd: '" + sd + "', ed: '" + ed + "', processType: '" + processType + "'}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (r) {
var labels = r.d[0];
var series1 = r.d[1];
var data = {
labels: labels,
datasets: [{
label: 'Process Count',
data: series1,
fill: false,
borderColor: "blue",
color: "red",
backgroundColor: "blue",
radius: 10,
}
]
};
$("#dvChart5").html("");
var canvas = document.createElement('canvas');
$("#dvChart5")[0].appendChild(canvas);
var ctx2 = canvas.getContext('2d');
var piechart = new Chart(ctx2, {
type: 'line',
data: data,
options: {
title: {
display: false
},
scales: {
xAxes: [{
ticks: {
minRotation: 75,
maxRotation: 90,
fontFamily: "'Open Sans', sans-serif",
fontSize: 14,
fontStyle: "bold",
fontColor: "#545454",
autoSkip: false
}
}],
},
tooltips: {
},
legend: {
display: true,
position: 'bottom'
}
}
});
},
failure: function (response) {
alert('There was an error.');
}
});
}
thanks
Put this in option
plugins: {
datalabels: {
display: false,
},
}
This works:
options: {
legend: {
display: false
},
}

How to render Chart.js 2.x tooltips on top of everything

I'm using Chart.js 2.6.0 and I have been working on an example to render custom graphics. You can see a live demo at: https://jsfiddle.net/arminzia/bm4ezdur/.
Basically I'm rendering circles on top of each bar to denote the value. here's the code:
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'bar',
responsive: true,
maintainAspectRatio: false,
data: {
labels: ["2 Jan", "9 Jan", "16 Jan", "23 Jan", "30 Jan", "6 Feb", "13 Feb"],
datasets: [{
data: [16, 87, 56, 35, 88, 60, 12],
backgroundColor: "#4082c4"
}]
},
options: {
"hover": {
"animationDuration": 0
},
"animation": {
"duration": 1,
"onComplete": function () {
var chartInstance = this.chart,
ctx = chartInstance.ctx;
ctx.font = Chart.helpers.fontString(Chart.defaults.global.defaultFontSize, Chart.defaults.global.defaultFontStyle, Chart.defaults.global.defaultFontFamily);
ctx.textAlign = 'center';
ctx.textBaseline = 'bottom';
this.data.datasets.forEach(function (dataset, i) {
var meta = chartInstance.controller.getDatasetMeta(i);
meta.data.forEach(function (bar, index) {
var data = dataset.data[index] + '$';
var centerX = bar._model.x;
var centerY = bar._model.y - 10;
var radius = 22;
ctx.beginPath();
ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
ctx.fillStyle = 'white';
ctx.fill();
ctx.lineWidth = 1;
ctx.strokeStyle = '#4082c4';
ctx.stroke();
ctx.fillStyle = '#4082c4';
ctx.font = "bold 14px Calibri";
ctx.fillText(data, bar._model.x, bar._model.y);
});
});
}
},
legend: {
"display": false
},
tooltips: {
"enabled": true
},
scales: {
yAxes: [{
display: true,
gridLines: {
display : true
},
ticks: {
display: true,
beginAtZero:true,
max: 140
}
}],
xAxes: [{
barThickness: 40,
gridLines: {
display : false
},
ticks: {
beginAtZero:true
}
}]
}
}
});
Now the problem is, tooltips are being hidden under these circles. I've been struggling with this for too long and haven't found any solution or anything useful from the docs.
How can I force tooltips to be rendered on top of these circles? On top of everything actually, something like z-index: 1000.
Forgot to update this post. The answer is to use External (Custom) Tooltips. That's basically rendering HTML elements to create tooltips. Read more on the docs here.