Chart.js : straight lines instead of curves - chart.js

I'm using Chart.JS to plot a dataset,
However I got a smooth effect !
Here is the curve I've got :
Here is my code :
function plotChart(data, labels) {
var lineChartData = {
"datasets": [{
"data": data,
"pointStrokeColor": "#fff",
"fillColor": "rgba(220,220,220,0.5)",
"pointColor": "rgba(220,220,220,1)",
"strokeColor": "rgba(220,220,220,1)"
}],
"labels": labels
};
var myLine = new Chart(document.getElementById("canvas").getContext("2d")).Line(lineChartData);
}
How can I have straight lines instead of curves ?
Thank you

Solution for Version 1 (old charts version)
According to documentation on chartjs.org
you can set the 'bezierCurve' in options and pass it in when you create the chart.
bezierCurve: false
eg:
var options = {
//Boolean - Whether the line is curved between points
bezierCurve : false
};
var myLine = new Chart(document.getElementById("canvas").getContext("2d")).Line(lineChartData, options);
Update for version 2
According to updated documentation for Line Configuration in global options
Name Type Default Description
tension Number 0.4 Default bezier curve tension. Set to 0 for no bezier curves.
eg:
var options = {
elements: {
line: {
tension: 0
}
}
};
And also directly in the Dataset Structure by setting lineTension to 0 (zero).
Property Type Usage
lineTension Number Bezier curve tension of the line. Set to 0 to draw straightlines.
This option is ignored if monotone cubic interpolation is used.
Note This was renamed from 'tension' but the old name still works.
An example data object using these attributes is shown below.
var lineChartData = {
labels: labels,
datasets: [
{
label: "My First dataset",
lineTension: 0,
data: data,
}
]
};

You can use lineTension option to set the desired curve. Set 0 for straight lines. You can give a number between 0-1
data: {
datasets: [{
lineTension: 0
}]
}

Just to complete version compatibility and to add something to this nice thread here:
Still the same with chart.js v3.x.x
(which is not backwards compatible with v2.x.x -- however, lineTension stays unchanged within
data: { datasets: [{ lineTension: ... )
LineTension for chart.js v3.x.x
Following, you can Run the snippet with 10 buttons to play with different lineTensions (0 to 1) right here:
// for now, let's assume sample data
let sample_data = {
"Labels" : [
"2021-08-02",
"2021-08-03",
"2021-08-04",
"2021-08-05",
"2021-08-06"
],
"Values": [
6,
4,
3,
8,
2
]
};
// Draw chart
const ctx = document.querySelector('canvas').getContext('2d');
const myLineChart = new Chart(ctx, {
type: 'line',
data: {
labels: sample_data.Labels,
datasets: [{
label: 'LineTension Sample',
data: sample_data.Values,
lineTension: 0,
borderColor: 'rgba(0,255,0,1)',
backgroundColor: 'rgba(0,255,0,0.3)',
fill: true
}]
}
});
function lineTension(event) {
// Redraw the chart with modified lineTension
// a bit of 'button-cosmetics' here
// enabling all buttons
document.querySelectorAll('button').forEach(element => element.disabled = false);
// disabling the pressed button
event.target.disabled = true;
// setting programmatically the 'lineTension' here
myLineChart.data.datasets[0].lineTension = parseFloat(event.target.dataset.linetension);
myLineChart.update();
};
button {
color: blue;
}
button:disabled {
color: black;
background-color: rgba(0,255,0,0.3);
}
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<!-- gets you the latest version of Chart.js, now at v3.5.0 -->
<button onclick="lineTension(event)" data-linetension="0" disabled>0</button>
<button onclick="lineTension(event)" data-linetension="0.1">0.1</button>
<button onclick="lineTension(event)" data-linetension="0.2">0.2</button>
<button onclick="lineTension(event)" data-linetension="0.3">0.3</button>
<button onclick="lineTension(event)" data-linetension="0.4">0.4</button>
<button onclick="lineTension(event)" data-linetension="0.5">0.5</button>
<button onclick="lineTension(event)" data-linetension="0.6">0.6</button>
<button onclick="lineTension(event)" data-linetension="0.7">0.7</button>
<button onclick="lineTension(event)" data-linetension="0.8">0.8</button>
<button onclick="lineTension(event)" data-linetension="0.9">0.9</button>
<button onclick="lineTension(event)" data-linetension="1">1</button>
<canvas width="320" height="240"></canvas>

I have used lineTension to set the smoothness of the curve.
From the docs: lineTension receives a number, Bezier curve tension of the line. Set to 0 to draw straight lines. This option is ignored if monotone cubic interpolation is used.
Just make sure to test with different values how smooth you want the line.
For example:
var data = {
labels: ["Jan", "Feb", "Mar"],
datasets: [{
label: "Label 1",
lineTension: 0.2
}, {
label: "Stock B",
lineTension: 0.2
}
]
};

I think it's been updated to lineTension. Check the docs.

Chart.js v3.9.1 - property tension.
Link to documentation

Related

chart.js animate data through time? [duplicate]

I created an basic bar chart using chartjs and it works fine. Now I want to update the values on a time based interval. My problem is that after I created the chart, I do not know how to update its values correctly...
My code:
var ctx = $("#myChart").get(0).getContext("2d");
var dts = [
{
fillColor: "rgba(220,220,220,0.5)",
strokeColor: "rgba(220,220,220,1)",
data: [0, 0, 0, 0, 0]
}
];
var data = {
labels: ["Core#1", "Core#2", "Core#3", "Core#4", "Total"],
datasets: dts
};
var chart = new Chart(ctx);
chart.Bar(data);
//test code
setInterval( function () {
data.datasets[0].data = [random(), random(), random(), random(), random()];
chart.Bar(data);
},2000);
in the test code, I am updating the values with datasets[0].data- is this the right way to do it? The problem with this is that everytime I call chart.Bar(), the values are reset to 0 then animated to the random value (like I am recreating the chart). This way, all animations are always from 0 to value which looks strange. I would expect that if I update a value from 50 to 10 the bar would go down to 10 from 50 and not setted to 0 then animated to 10.
I did not found anything in the docs about this... am I doing something wrong or this is impossible with this library?
Update: Looks like chartjs has been updated (see comment below). There are some examples up that look very nice:
Here's an example of updating a line chart using new data: http://jsbin.com/yitep/5/edit
Here's how we can update existing data on a line chart: http://jsbin.com/yitep/4/edit
Original Post
As of Nov 2013, there seem to be very few options for updating charts.
There is a good example here (duplicated below) of adding new points to a line chart. Still kind of jumpy but not too bad. However, I think the effect probably depends on the chart you are using.
It does look like this is somewhere in the development pipeline. I don't see any indication of a release date yet though: https://github.com/nnnick/Chart.js/issues/13 [Closed as of Jul 26, 2014]
JS
$(document).ready(function(){
var count = 10;
var data = {
labels : ["1","2","3","4","5", "6", "7", "8", "9", "10"],
datasets : [
{
fillColor : "rgba(220,220,220,0.5)",
strokeColor : "rgba(220,220,220,1)",
pointColor : "rgba(220,220,220,1)",
pointStrokeColor : "#fff",
data : [65,59,90,81,56,45,30,20,3,37]
},
{
fillColor : "rgba(151,187,205,0.5)",
strokeColor : "rgba(151,187,205,1)",
pointColor : "rgba(151,187,205,1)",
pointStrokeColor : "#fff",
data : [28,48,40,19,96,87,66,97,92,85]
}
]
}
// this is ugly, don't judge me
var updateData = function(oldData){
var labels = oldData["labels"];
var dataSetA = oldData["datasets"][0]["data"];
var dataSetB = oldData["datasets"][1]["data"];
labels.shift();
count++;
labels.push(count.toString());
var newDataA = dataSetA[9] + (20 - Math.floor(Math.random() * (41)));
var newDataB = dataSetB[9] + (20 - Math.floor(Math.random() * (41)));
dataSetA.push(newDataA);
dataSetB.push(newDataB);
dataSetA.shift();
dataSetB.shift(); };
var optionsAnimation = {
//Boolean - If we want to override with a hard coded scale
scaleOverride : true,
//** Required if scaleOverride is true **
//Number - The number of steps in a hard coded scale
scaleSteps : 10,
//Number - The value jump in the hard coded scale
scaleStepWidth : 10,
//Number - The scale starting value
scaleStartValue : 0
}
// Not sure why the scaleOverride isn't working...
var optionsNoAnimation = {
animation : false,
//Boolean - If we want to override with a hard coded scale
scaleOverride : true,
//** Required if scaleOverride is true **
//Number - The number of steps in a hard coded scale
scaleSteps : 20,
//Number - The value jump in the hard coded scale
scaleStepWidth : 10,
//Number - The scale starting value
scaleStartValue : 0
}
//Get the context of the canvas element we want to select
var ctx = document.getElementById("myChart").getContext("2d");
var optionsNoAnimation = {animation : false}
var myNewChart = new Chart(ctx);
myNewChart.Line(data, optionsAnimation);
setInterval(function(){
updateData(data);
myNewChart.Line(data, optionsNoAnimation)
;}, 2000
);
});
// ChartJS
var Chart=function(s){function v(a,c,b){a=A((a-c.graphMin)/(c.steps*c.stepValue),1,0);return b*c.steps*a}function x(a,c,b,e){function h(){g+=f;var k=a.animation?A(d(g),null,0):1;e.clearRect(0,0,q,u);a.scaleOverlay?(b(k),c()):(c(),b(k));if(1>=g)D(h);else if("function"==typeof a.onAnimationComplete)a.onAnimationComplete()}var f=a.animation?1/A(a.animationSteps,Number.MAX_VALUE,1):1,d=B[a.animationEasing],g=a.animation?0:1;"function"!==typeof c&&(c=function(){});D(h)}function C(a,c,b,e,h,f){var d;a=
Math.floor(Math.log(e-h)/Math.LN10);h=Math.floor(h/(1*Math.pow(10,a)))*Math.pow(10,a);e=Math.ceil(e/(1*Math.pow(10,a)))*Math.pow(10,a)-h;a=Math.pow(10,a);for(d=Math.round(e/a);d<b||d>c;)a=d<b?a/2:2*a,d=Math.round(e/a);c=[];z(f,c,d,h,a);return{steps:d,stepValue:a,graphMin:h,labels:c}}function z(a,c,b,e,h){if(a)for(var f=1;f<b+1;f++)c.push(E(a,{value:(e+h*f).toFixed(0!=h%1?h.toString().split(".")[1].length:0)}))}function A(a,c,b){return!isNaN(parseFloat(c))&&isFinite(c)&&a>c?c:!isNaN(parseFloat(b))&&
isFinite(b)&&a<b?b:a}function y(a,c){var b={},e;for(e in a)b[e]=a[e];for(e in c)b[e]=c[e];return b}function E(a,c){var b=!/\W/.test(a)?F[a]=F[a]||E(document.getElementById(a).innerHTML):new Function("obj","var p=[],print=function(){p.push.apply(p,arguments);};with(obj){p.push('"+a.replace(/[\r\t\n]/g," ").split("<%").join("\t").replace(/((^|%>)[^\t]*)'/g,"$1\r").replace(/\t=(.*?)%>/g,"',$1,'").split("\t").join("');").split("%>").join("p.push('").split("\r").join("\\'")+"');}return p.join('');");return c?
b(c):b}var r=this,B={linear:function(a){return a},easeInQuad:function(a){return a*a},easeOutQuad:function(a){return-1*a*(a-2)},easeInOutQuad:function(a){return 1>(a/=0.5)?0.5*a*a:-0.5*(--a*(a-2)-1)},easeInCubic:function(a){return a*a*a},easeOutCubic:function(a){return 1*((a=a/1-1)*a*a+1)},easeInOutCubic:function(a){return 1>(a/=0.5)?0.5*a*a*a:0.5*((a-=2)*a*a+2)},easeInQuart:function(a){return a*a*a*a},easeOutQuart:function(a){return-1*((a=a/1-1)*a*a*a-1)},easeInOutQuart:function(a){return 1>(a/=0.5)?
0.5*a*a*a*a:-0.5*((a-=2)*a*a*a-2)},easeInQuint:function(a){return 1*(a/=1)*a*a*a*a},easeOutQuint:function(a){return 1*((a=a/1-1)*a*a*a*a+1)},easeInOutQuint:function(a){return 1>(a/=0.5)?0.5*a*a*a*a*a:0.5*((a-=2)*a*a*a*a+2)},easeInSine:function(a){return-1*Math.cos(a/1*(Math.PI/2))+1},easeOutSine:function(a){return 1*Math.sin(a/1*(Math.PI/2))},easeInOutSine:function(a){return-0.5*(Math.cos(Math.PI*a/1)-1)},easeInExpo:function(a){return 0==a?1:1*Math.pow(2,10*(a/1-1))},easeOutExpo:function(a){return 1==
a?1:1*(-Math.pow(2,-10*a/1)+1)},easeInOutExpo:function(a){return 0==a?0:1==a?1:1>(a/=0.5)?0.5*Math.pow(2,10*(a-1)):0.5*(-Math.pow(2,-10*--a)+2)},easeInCirc:function(a){return 1<=a?a:-1*(Math.sqrt(1-(a/=1)*a)-1)},easeOutCirc:function(a){return 1*Math.sqrt(1-(a=a/1-1)*a)},easeInOutCirc:function(a){return 1>(a/=0.5)?-0.5*(Math.sqrt(1-a*a)-1):0.5*(Math.sqrt(1-(a-=2)*a)+1)},easeInElastic:function(a){var c=1.70158,b=0,e=1;if(0==a)return 0;if(1==(a/=1))return 1;b||(b=0.3);e<Math.abs(1)?(e=1,c=b/4):c=b/(2*
Math.PI)*Math.asin(1/e);return-(e*Math.pow(2,10*(a-=1))*Math.sin((1*a-c)*2*Math.PI/b))},easeOutElastic:function(a){var c=1.70158,b=0,e=1;if(0==a)return 0;if(1==(a/=1))return 1;b||(b=0.3);e<Math.abs(1)?(e=1,c=b/4):c=b/(2*Math.PI)*Math.asin(1/e);return e*Math.pow(2,-10*a)*Math.sin((1*a-c)*2*Math.PI/b)+1},easeInOutElastic:function(a){var c=1.70158,b=0,e=1;if(0==a)return 0;if(2==(a/=0.5))return 1;b||(b=1*0.3*1.5);e<Math.abs(1)?(e=1,c=b/4):c=b/(2*Math.PI)*Math.asin(1/e);return 1>a?-0.5*e*Math.pow(2,10*
(a-=1))*Math.sin((1*a-c)*2*Math.PI/b):0.5*e*Math.pow(2,-10*(a-=1))*Math.sin((1*a-c)*2*Math.PI/b)+1},easeInBack:function(a){return 1*(a/=1)*a*(2.70158*a-1.70158)},easeOutBack:function(a){return 1*((a=a/1-1)*a*(2.70158*a+1.70158)+1)},easeInOutBack:function(a){var c=1.70158;return 1>(a/=0.5)?0.5*a*a*(((c*=1.525)+1)*a-c):0.5*((a-=2)*a*(((c*=1.525)+1)*a+c)+2)},easeInBounce:function(a){return 1-B.easeOutBounce(1-a)},easeOutBounce:function(a){return(a/=1)<1/2.75?1*7.5625*a*a:a<2/2.75?1*(7.5625*(a-=1.5/2.75)*
a+0.75):a<2.5/2.75?1*(7.5625*(a-=2.25/2.75)*a+0.9375):1*(7.5625*(a-=2.625/2.75)*a+0.984375)},easeInOutBounce:function(a){return 0.5>a?0.5*B.easeInBounce(2*a):0.5*B.easeOutBounce(2*a-1)+0.5}},q=s.canvas.width,u=s.canvas.height;window.devicePixelRatio&&(s.canvas.style.width=q+"px",s.canvas.style.height=u+"px",s.canvas.height=u*window.devicePixelRatio,s.canvas.width=q*window.devicePixelRatio,s.scale(window.devicePixelRatio,window.devicePixelRatio));this.PolarArea=function(a,c){r.PolarArea.defaults={scaleOverlay:!0,
scaleOverride:!1,scaleSteps:null,scaleStepWidth:null,scaleStartValue:null,scaleShowLine:!0,scaleLineColor:"rgba(0,0,0,.1)",scaleLineWidth:1,scaleShowLabels:!0,scaleLabel:"<%=value%>",scaleFontFamily:"'Arial'",scaleFontSize:12,scaleFontStyle:"normal",scaleFontColor:"#666",scaleShowLabelBackdrop:!0,scaleBackdropColor:"rgba(255,255,255,0.75)",scaleBackdropPaddingY:2,scaleBackdropPaddingX:2,segmentShowStroke:!0,segmentStrokeColor:"#fff",segmentStrokeWidth:2,animation:!0,animationSteps:100,animationEasing:"easeOutBounce",
animateRotate:!0,animateScale:!1,onAnimationComplete:null};var b=c?y(r.PolarArea.defaults,c):r.PolarArea.defaults;return new G(a,b,s)};this.Radar=function(a,c){r.Radar.defaults={scaleOverlay:!1,scaleOverride:!1,scaleSteps:null,scaleStepWidth:null,scaleStartValue:null,scaleShowLine:!0,scaleLineColor:"rgba(0,0,0,.1)",scaleLineWidth:1,scaleShowLabels:!1,scaleLabel:"<%=value%>",scaleFontFamily:"'Arial'",scaleFontSize:12,scaleFontStyle:"normal",scaleFontColor:"#666",scaleShowLabelBackdrop:!0,scaleBackdropColor:"rgba(255,255,255,0.75)",
scaleBackdropPaddingY:2,scaleBackdropPaddingX:2,angleShowLineOut:!0,angleLineColor:"rgba(0,0,0,.1)",angleLineWidth:1,pointLabelFontFamily:"'Arial'",pointLabelFontStyle:"normal",pointLabelFontSize:12,pointLabelFontColor:"#666",pointDot:!0,pointDotRadius:3,pointDotStrokeWidth:1,datasetStroke:!0,datasetStrokeWidth:2,datasetFill:!0,animation:!0,animationSteps:60,animationEasing:"easeOutQuart",onAnimationComplete:null};var b=c?y(r.Radar.defaults,c):r.Radar.defaults;return new H(a,b,s)};this.Pie=function(a,
c){r.Pie.defaults={segmentShowStroke:!0,segmentStrokeColor:"#fff",segmentStrokeWidth:2,animation:!0,animationSteps:100,animationEasing:"easeOutBounce",animateRotate:!0,animateScale:!1,onAnimationComplete:null};var b=c?y(r.Pie.defaults,c):r.Pie.defaults;return new I(a,b,s)};this.Doughnut=function(a,c){r.Doughnut.defaults={segmentShowStroke:!0,segmentStrokeColor:"#fff",segmentStrokeWidth:2,percentageInnerCutout:50,animation:!0,animationSteps:100,animationEasing:"easeOutBounce",animateRotate:!0,animateScale:!1,
onAnimationComplete:null};var b=c?y(r.Doughnut.defaults,c):r.Doughnut.defaults;return new J(a,b,s)};this.Line=function(a,c){r.Line.defaults={scaleOverlay:!1,scaleOverride:!1,scaleSteps:null,scaleStepWidth:null,scaleStartValue:null,scaleLineColor:"rgba(0,0,0,.1)",scaleLineWidth:1,scaleShowLabels:!0,scaleLabel:"<%=value%>",scaleFontFamily:"'Arial'",scaleFontSize:12,scaleFontStyle:"normal",scaleFontColor:"#666",scaleShowGridLines:!0,scaleGridLineColor:"rgba(0,0,0,.05)",scaleGridLineWidth:1,bezierCurve:!0,
pointDot:!0,pointDotRadius:4,pointDotStrokeWidth:2,datasetStroke:!0,datasetStrokeWidth:2,datasetFill:!0,animation:!0,animationSteps:60,animationEasing:"easeOutQuart",onAnimationComplete:null};var b=c?y(r.Line.defaults,c):r.Line.defaults;return new K(a,b,s)};this.Bar=function(a,c){r.Bar.defaults={scaleOverlay:!1,scaleOverride:!1,scaleSteps:null,scaleStepWidth:null,scaleStartValue:null,scaleLineColor:"rgba(0,0,0,.1)",scaleLineWidth:1,scaleShowLabels:!0,scaleLabel:"<%=value%>",scaleFontFamily:"'Arial'",
scaleFontSize:12,scaleFontStyle:"normal",scaleFontColor:"#666",scaleShowGridLines:!0,scaleGridLineColor:"rgba(0,0,0,.05)",scaleGridLineWidth:1,barShowStroke:!0,barStrokeWidth:2,barValueSpacing:5,barDatasetSpacing:1,animation:!0,animationSteps:60,animationEasing:"easeOutQuart",onAnimationComplete:null};var b=c?y(r.Bar.defaults,c):r.Bar.defaults;return new L(a,b,s)};var G=function(a,c,b){var e,h,f,d,g,k,j,l,m;g=Math.min.apply(Math,[q,u])/2;g-=Math.max.apply(Math,[0.5*c.scaleFontSize,0.5*c.scaleLineWidth]);
d=2*c.scaleFontSize;c.scaleShowLabelBackdrop&&(d+=2*c.scaleBackdropPaddingY,g-=1.5*c.scaleBackdropPaddingY);l=g;d=d?d:5;e=Number.MIN_VALUE;h=Number.MAX_VALUE;for(f=0;f<a.length;f++)a[f].value>e&&(e=a[f].value),a[f].value<h&&(h=a[f].value);f=Math.floor(l/(0.66*d));d=Math.floor(0.5*(l/d));m=c.scaleShowLabels?c.scaleLabel:null;c.scaleOverride?(j={steps:c.scaleSteps,stepValue:c.scaleStepWidth,graphMin:c.scaleStartValue,labels:[]},z(m,j.labels,j.steps,c.scaleStartValue,c.scaleStepWidth)):j=C(l,f,d,e,h,
m);k=g/j.steps;x(c,function(){for(var a=0;a<j.steps;a++)if(c.scaleShowLine&&(b.beginPath(),b.arc(q/2,u/2,k*(a+1),0,2*Math.PI,!0),b.strokeStyle=c.scaleLineColor,b.lineWidth=c.scaleLineWidth,b.stroke()),c.scaleShowLabels){b.textAlign="center";b.font=c.scaleFontStyle+" "+c.scaleFontSize+"px "+c.scaleFontFamily;var e=j.labels[a];if(c.scaleShowLabelBackdrop){var d=b.measureText(e).width;b.fillStyle=c.scaleBackdropColor;b.beginPath();b.rect(Math.round(q/2-d/2-c.scaleBackdropPaddingX),Math.round(u/2-k*(a+
1)-0.5*c.scaleFontSize-c.scaleBackdropPaddingY),Math.round(d+2*c.scaleBackdropPaddingX),Math.round(c.scaleFontSize+2*c.scaleBackdropPaddingY));b.fill()}b.textBaseline="middle";b.fillStyle=c.scaleFontColor;b.fillText(e,q/2,u/2-k*(a+1))}},function(e){var d=-Math.PI/2,g=2*Math.PI/a.length,f=1,h=1;c.animation&&(c.animateScale&&(f=e),c.animateRotate&&(h=e));for(e=0;e<a.length;e++)b.beginPath(),b.arc(q/2,u/2,f*v(a[e].value,j,k),d,d+h*g,!1),b.lineTo(q/2,u/2),b.closePath(),b.fillStyle=a[e].color,b.fill(),
c.segmentShowStroke&&(b.strokeStyle=c.segmentStrokeColor,b.lineWidth=c.segmentStrokeWidth,b.stroke()),d+=h*g},b)},H=function(a,c,b){var e,h,f,d,g,k,j,l,m;a.labels||(a.labels=[]);g=Math.min.apply(Math,[q,u])/2;d=2*c.scaleFontSize;for(e=l=0;e<a.labels.length;e++)b.font=c.pointLabelFontStyle+" "+c.pointLabelFontSize+"px "+c.pointLabelFontFamily,h=b.measureText(a.labels[e]).width,h>l&&(l=h);g-=Math.max.apply(Math,[l,1.5*(c.pointLabelFontSize/2)]);g-=c.pointLabelFontSize;l=g=A(g,null,0);d=d?d:5;e=Number.MIN_VALUE;
h=Number.MAX_VALUE;for(f=0;f<a.datasets.length;f++)for(m=0;m<a.datasets[f].data.length;m++)a.datasets[f].data[m]>e&&(e=a.datasets[f].data[m]),a.datasets[f].data[m]<h&&(h=a.datasets[f].data[m]);f=Math.floor(l/(0.66*d));d=Math.floor(0.5*(l/d));m=c.scaleShowLabels?c.scaleLabel:null;c.scaleOverride?(j={steps:c.scaleSteps,stepValue:c.scaleStepWidth,graphMin:c.scaleStartValue,labels:[]},z(m,j.labels,j.steps,c.scaleStartValue,c.scaleStepWidth)):j=C(l,f,d,e,h,m);k=g/j.steps;x(c,function(){var e=2*Math.PI/
a.datasets[0].data.length;b.save();b.translate(q/2,u/2);if(c.angleShowLineOut){b.strokeStyle=c.angleLineColor;b.lineWidth=c.angleLineWidth;for(var d=0;d<a.datasets[0].data.length;d++)b.rotate(e),b.beginPath(),b.moveTo(0,0),b.lineTo(0,-g),b.stroke()}for(d=0;d<j.steps;d++){b.beginPath();if(c.scaleShowLine){b.strokeStyle=c.scaleLineColor;b.lineWidth=c.scaleLineWidth;b.moveTo(0,-k*(d+1));for(var f=0;f<a.datasets[0].data.length;f++)b.rotate(e),b.lineTo(0,-k*(d+1));b.closePath();b.stroke()}c.scaleShowLabels&&
(b.textAlign="center",b.font=c.scaleFontStyle+" "+c.scaleFontSize+"px "+c.scaleFontFamily,b.textBaseline="middle",c.scaleShowLabelBackdrop&&(f=b.measureText(j.labels[d]).width,b.fillStyle=c.scaleBackdropColor,b.beginPath(),b.rect(Math.round(-f/2-c.scaleBackdropPaddingX),Math.round(-k*(d+1)-0.5*c.scaleFontSize-c.scaleBackdropPaddingY),Math.round(f+2*c.scaleBackdropPaddingX),Math.round(c.scaleFontSize+2*c.scaleBackdropPaddingY)),b.fill()),b.fillStyle=c.scaleFontColor,b.fillText(j.labels[d],0,-k*(d+
1)))}for(d=0;d<a.labels.length;d++){b.font=c.pointLabelFontStyle+" "+c.pointLabelFontSize+"px "+c.pointLabelFontFamily;b.fillStyle=c.pointLabelFontColor;var f=Math.sin(e*d)*(g+c.pointLabelFontSize),h=Math.cos(e*d)*(g+c.pointLabelFontSize);b.textAlign=e*d==Math.PI||0==e*d?"center":e*d>Math.PI?"right":"left";b.textBaseline="middle";b.fillText(a.labels[d],f,-h)}b.restore()},function(d){var e=2*Math.PI/a.datasets[0].data.length;b.save();b.translate(q/2,u/2);for(var g=0;g<a.datasets.length;g++){b.beginPath();
b.moveTo(0,d*-1*v(a.datasets[g].data[0],j,k));for(var f=1;f<a.datasets[g].data.length;f++)b.rotate(e),b.lineTo(0,d*-1*v(a.datasets[g].data[f],j,k));b.closePath();b.fillStyle=a.datasets[g].fillColor;b.strokeStyle=a.datasets[g].strokeColor;b.lineWidth=c.datasetStrokeWidth;b.fill();b.stroke();if(c.pointDot){b.fillStyle=a.datasets[g].pointColor;b.strokeStyle=a.datasets[g].pointStrokeColor;b.lineWidth=c.pointDotStrokeWidth;for(f=0;f<a.datasets[g].data.length;f++)b.rotate(e),b.beginPath(),b.arc(0,d*-1*
v(a.datasets[g].data[f],j,k),c.pointDotRadius,2*Math.PI,!1),b.fill(),b.stroke()}b.rotate(e)}b.restore()},b)},I=function(a,c,b){for(var e=0,h=Math.min.apply(Math,[u/2,q/2])-5,f=0;f<a.length;f++)e+=a[f].value;x(c,null,function(d){var g=-Math.PI/2,f=1,j=1;c.animation&&(c.animateScale&&(f=d),c.animateRotate&&(j=d));for(d=0;d<a.length;d++){var l=j*a[d].value/e*2*Math.PI;b.beginPath();b.arc(q/2,u/2,f*h,g,g+l);b.lineTo(q/2,u/2);b.closePath();b.fillStyle=a[d].color;b.fill();c.segmentShowStroke&&(b.lineWidth=
c.segmentStrokeWidth,b.strokeStyle=c.segmentStrokeColor,b.stroke());g+=l}},b)},J=function(a,c,b){for(var e=0,h=Math.min.apply(Math,[u/2,q/2])-5,f=h*(c.percentageInnerCutout/100),d=0;d<a.length;d++)e+=a[d].value;x(c,null,function(d){var k=-Math.PI/2,j=1,l=1;c.animation&&(c.animateScale&&(j=d),c.animateRotate&&(l=d));for(d=0;d<a.length;d++){var m=l*a[d].value/e*2*Math.PI;b.beginPath();b.arc(q/2,u/2,j*h,k,k+m,!1);b.arc(q/2,u/2,j*f,k+m,k,!0);b.closePath();b.fillStyle=a[d].color;b.fill();c.segmentShowStroke&&
(b.lineWidth=c.segmentStrokeWidth,b.strokeStyle=c.segmentStrokeColor,b.stroke());k+=m}},b)},K=function(a,c,b){var e,h,f,d,g,k,j,l,m,t,r,n,p,s=0;g=u;b.font=c.scaleFontStyle+" "+c.scaleFontSize+"px "+c.scaleFontFamily;t=1;for(d=0;d<a.labels.length;d++)e=b.measureText(a.labels[d]).width,t=e>t?e:t;q/a.labels.length<t?(s=45,q/a.labels.length<Math.cos(s)*t?(s=90,g-=t):g-=Math.sin(s)*t):g-=c.scaleFontSize;d=c.scaleFontSize;g=g-5-d;e=Number.MIN_VALUE;h=Number.MAX_VALUE;for(f=0;f<a.datasets.length;f++)for(l=
0;l<a.datasets[f].data.length;l++)a.datasets[f].data[l]>e&&(e=a.datasets[f].data[l]),a.datasets[f].data[l]<h&&(h=a.datasets[f].data[l]);f=Math.floor(g/(0.66*d));d=Math.floor(0.5*(g/d));l=c.scaleShowLabels?c.scaleLabel:"";c.scaleOverride?(j={steps:c.scaleSteps,stepValue:c.scaleStepWidth,graphMin:c.scaleStartValue,labels:[]},z(l,j.labels,j.steps,c.scaleStartValue,c.scaleStepWidth)):j=C(g,f,d,e,h,l);k=Math.floor(g/j.steps);d=1;if(c.scaleShowLabels){b.font=c.scaleFontStyle+" "+c.scaleFontSize+"px "+c.scaleFontFamily;
for(e=0;e<j.labels.length;e++)h=b.measureText(j.labels[e]).width,d=h>d?h:d;d+=10}r=q-d-t;m=Math.floor(r/(a.labels.length-1));n=q-t/2-r;p=g+c.scaleFontSize/2;x(c,function(){b.lineWidth=c.scaleLineWidth;b.strokeStyle=c.scaleLineColor;b.beginPath();b.moveTo(q-t/2+5,p);b.lineTo(q-t/2-r-5,p);b.stroke();0<s?(b.save(),b.textAlign="right"):b.textAlign="center";b.fillStyle=c.scaleFontColor;for(var d=0;d<a.labels.length;d++)b.save(),0<s?(b.translate(n+d*m,p+c.scaleFontSize),b.rotate(-(s*(Math.PI/180))),b.fillText(a.labels[d],
0,0),b.restore()):b.fillText(a.labels[d],n+d*m,p+c.scaleFontSize+3),b.beginPath(),b.moveTo(n+d*m,p+3),c.scaleShowGridLines&&0<d?(b.lineWidth=c.scaleGridLineWidth,b.strokeStyle=c.scaleGridLineColor,b.lineTo(n+d*m,5)):b.lineTo(n+d*m,p+3),b.stroke();b.lineWidth=c.scaleLineWidth;b.strokeStyle=c.scaleLineColor;b.beginPath();b.moveTo(n,p+5);b.lineTo(n,5);b.stroke();b.textAlign="right";b.textBaseline="middle";for(d=0;d<j.steps;d++)b.beginPath(),b.moveTo(n-3,p-(d+1)*k),c.scaleShowGridLines?(b.lineWidth=c.scaleGridLineWidth,
b.strokeStyle=c.scaleGridLineColor,b.lineTo(n+r+5,p-(d+1)*k)):b.lineTo(n-0.5,p-(d+1)*k),b.stroke(),c.scaleShowLabels&&b.fillText(j.labels[d],n-8,p-(d+1)*k)},function(d){function e(b,c){return p-d*v(a.datasets[b].data[c],j,k)}for(var f=0;f<a.datasets.length;f++){b.strokeStyle=a.datasets[f].strokeColor;b.lineWidth=c.datasetStrokeWidth;b.beginPath();b.moveTo(n,p-d*v(a.datasets[f].data[0],j,k));for(var g=1;g<a.datasets[f].data.length;g++)c.bezierCurve?b.bezierCurveTo(n+m*(g-0.5),e(f,g-1),n+m*(g-0.5),
e(f,g),n+m*g,e(f,g)):b.lineTo(n+m*g,e(f,g));b.stroke();c.datasetFill?(b.lineTo(n+m*(a.datasets[f].data.length-1),p),b.lineTo(n,p),b.closePath(),b.fillStyle=a.datasets[f].fillColor,b.fill()):b.closePath();if(c.pointDot){b.fillStyle=a.datasets[f].pointColor;b.strokeStyle=a.datasets[f].pointStrokeColor;b.lineWidth=c.pointDotStrokeWidth;for(g=0;g<a.datasets[f].data.length;g++)b.beginPath(),b.arc(n+m*g,p-d*v(a.datasets[f].data[g],j,k),c.pointDotRadius,0,2*Math.PI,!0),b.fill(),b.stroke()}}},b)},L=function(a,
c,b){var e,h,f,d,g,k,j,l,m,t,r,n,p,s,w=0;g=u;b.font=c.scaleFontStyle+" "+c.scaleFontSize+"px "+c.scaleFontFamily;t=1;for(d=0;d<a.labels.length;d++)e=b.measureText(a.labels[d]).width,t=e>t?e:t;q/a.labels.length<t?(w=45,q/a.labels.length<Math.cos(w)*t?(w=90,g-=t):g-=Math.sin(w)*t):g-=c.scaleFontSize;d=c.scaleFontSize;g=g-5-d;e=Number.MIN_VALUE;h=Number.MAX_VALUE;for(f=0;f<a.datasets.length;f++)for(l=0;l<a.datasets[f].data.length;l++)a.datasets[f].data[l]>e&&(e=a.datasets[f].data[l]),a.datasets[f].data[l]<
h&&(h=a.datasets[f].data[l]);f=Math.floor(g/(0.66*d));d=Math.floor(0.5*(g/d));l=c.scaleShowLabels?c.scaleLabel:"";c.scaleOverride?(j={steps:c.scaleSteps,stepValue:c.scaleStepWidth,graphMin:c.scaleStartValue,labels:[]},z(l,j.labels,j.steps,c.scaleStartValue,c.scaleStepWidth)):j=C(g,f,d,e,h,l);k=Math.floor(g/j.steps);d=1;if(c.scaleShowLabels){b.font=c.scaleFontStyle+" "+c.scaleFontSize+"px "+c.scaleFontFamily;for(e=0;e<j.labels.length;e++)h=b.measureText(j.labels[e]).width,d=h>d?h:d;d+=10}r=q-d-t;m=
Math.floor(r/a.labels.length);s=(m-2*c.scaleGridLineWidth-2*c.barValueSpacing-(c.barDatasetSpacing*a.datasets.length-1)-(c.barStrokeWidth/2*a.datasets.length-1))/a.datasets.length;n=q-t/2-r;p=g+c.scaleFontSize/2;x(c,function(){b.lineWidth=c.scaleLineWidth;b.strokeStyle=c.scaleLineColor;b.beginPath();b.moveTo(q-t/2+5,p);b.lineTo(q-t/2-r-5,p);b.stroke();0<w?(b.save(),b.textAlign="right"):b.textAlign="center";b.fillStyle=c.scaleFontColor;for(var d=0;d<a.labels.length;d++)b.save(),0<w?(b.translate(n+
d*m,p+c.scaleFontSize),b.rotate(-(w*(Math.PI/180))),b.fillText(a.labels[d],0,0),b.restore()):b.fillText(a.labels[d],n+d*m+m/2,p+c.scaleFontSize+3),b.beginPath(),b.moveTo(n+(d+1)*m,p+3),b.lineWidth=c.scaleGridLineWidth,b.strokeStyle=c.scaleGridLineColor,b.lineTo(n+(d+1)*m,5),b.stroke();b.lineWidth=c.scaleLineWidth;b.strokeStyle=c.scaleLineColor;b.beginPath();b.moveTo(n,p+5);b.lineTo(n,5);b.stroke();b.textAlign="right";b.textBaseline="middle";for(d=0;d<j.steps;d++)b.beginPath(),b.moveTo(n-3,p-(d+1)*
k),c.scaleShowGridLines?(b.lineWidth=c.scaleGridLineWidth,b.strokeStyle=c.scaleGridLineColor,b.lineTo(n+r+5,p-(d+1)*k)):b.lineTo(n-0.5,p-(d+1)*k),b.stroke(),c.scaleShowLabels&&b.fillText(j.labels[d],n-8,p-(d+1)*k)},function(d){b.lineWidth=c.barStrokeWidth;for(var e=0;e<a.datasets.length;e++){b.fillStyle=a.datasets[e].fillColor;b.strokeStyle=a.datasets[e].strokeColor;for(var f=0;f<a.datasets[e].data.length;f++){var g=n+c.barValueSpacing+m*f+s*e+c.barDatasetSpacing*e+c.barStrokeWidth*e;b.beginPath();
b.moveTo(g,p);b.lineTo(g,p-d*v(a.datasets[e].data[f],j,k)+c.barStrokeWidth/2);b.lineTo(g+s,p-d*v(a.datasets[e].data[f],j,k)+c.barStrokeWidth/2);b.lineTo(g+s,p);c.barShowStroke&&b.stroke();b.closePath();b.fill()}}},b)},D=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(a){window.setTimeout(a,1E3/60)},F={}};
HTML
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
</head>
<body>
<h1>Live Updating Chart.js</h1>
<canvas id="myChart" width="400" height="150"></canvas>
</body>
</html>
The update() triggers an update of the chart.
chart.update( )
.update(config)
Triggers an update of the chart. This can be safely called after updating the data object. This will update all scales, legends, and then re-render the chart. A config object can be provided with additional configuration for the update process.
update() can be safely called after updating values of one or more existing points within the the data object, rendering the changes in one animated render loop.
// update the first dataset's value of 'March' to be 50
myBarChart.data.datasets[0].bars[2].value = 50;
// animate update of 'March' from 90 to 50.
myBarChart.update();
Here is how to do it in the last version of ChartJs:
setInterval(function(){
chart.data.datasets[0].data[5] = 80;
chart.data.labels[5] = "Newly Added";
chart.update();
}
Look at this clear video
or test it in jsfiddle
You also can use destroy() function. Like this
if( window.myBar!==undefined)
window.myBar.destroy();
var ctx = document.getElementById("canvas").getContext("2d");
window.myBar = new Chart(ctx).Bar(barChartData, {
responsive : true,
});
You just need to change the chartObject.data.datasets value and call update() like this:
chartObject.data.datasets = newData.datasets;
chartObject.data.labels = newData.labels;
chartObject.update();
Remove the canvas dom and add in again.
function renderChart(label,data){
$("#canvas-wrapper").html("").html('<canvas id="storeSends"></canvas>');
var lineChartData = {
labels : label,
datasets : [
{
fillColor : "rgba(49, 195, 166, 0.2)",
strokeColor : "rgba(49, 195, 166, 1)",
pointColor : "rgba(49, 195, 166, 1)",
pointStrokeColor : "#fff",
data : data
}
]
}
var canvas = document.getElementById("storeSends");
var ctx = canvas.getContext("2d");
myLine = new Chart(ctx).Line(lineChartData, {
responsive: true,
maintainAspectRatio: false
});
}
I think the easiest way is to write a function to update your chart including the chart.update()method. Check out this simple example I wrote in jsfiddle for a Bar Chart.
//value for x-axis
var emotions = ["calm", "happy", "angry", "disgust"];
//colours for each bar
var colouarray = ['red', 'green', 'yellow', 'blue'];
//Let's initialData[] be the initial data set
var initialData = [0.1, 0.4, 0.3, 0.6];
//Let's updatedDataSet[] be the array to hold the upadted data set with every update call
var updatedDataSet;
/*Creating the bar chart*/
var ctx = document.getElementById("barChart");
var barChart = new Chart(ctx, {
type: 'bar',
data: {
labels: emotions,
datasets: [{
backgroundColor: colouarray,
label: 'Prediction',
data: initialData
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true,
min: 0,
max: 1,
stepSize: 0.5,
}
}]
}
}
});
/*Function to update the bar chart*/
function updateBarGraph(chart, label, color, data) {
chart.data.datasets.pop();
chart.data.datasets.push({
label: label,
backgroundColor: color,
data: data
});
chart.update();
}
/*Updating the bar chart with updated data in every second. */
setInterval(function() {
updatedDataSet = [Math.random(), Math.random(), Math.random(), Math.random()];
updateBarGraph(barChart, 'Prediction', colouarray, updatedDataSet);
}, 1000);
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.3.0/Chart.min.js"></script>
<body>
<div>
<h1>Update Bar Chart</h1>
<canvas id="barChart" width="800" height="450"></canvas>
</div>
<script src="barchart.js"></script>
</body>
</head>
</html>
Hope this helps.
If destroy() and clear() is not working (just like what i had experience) you can use jquery to remove the canvas and append it again.
$('#chartAmazon').remove();
$('#chartBar').append('<canvas id="chartAmazon"></canvas>');
var ctxAmazon = $("#chartAmazon").get(0).getContext("2d");
var AmazonChart = new Chart(ctxAmazon, {
type: 'doughnut',
data: dataAmazon,
options: optionsA
});
I don't think it's possible right now.
However that's a feature which should come soon, as the author hinted here:
https://github.com/nnnick/Chart.js/issues/161#issuecomment-20487775
This is an example with ChartJs - 2.9.4
var maximumPoints = 5;// with this variable you can decide how many points are display on the chart
function addData(chart, label, data) {
chart.data.labels.push(label);
chart.data.datasets.forEach((dataset) => {
var d = data[0];
dataset.data.push(d);
data.shift();
});
var canRemoveData = false;
chart.data.datasets.forEach((dataset) => {
if (dataset.data.length > maximumPoints) {
if (!canRemoveData) {
canRemoveData = true;
chart.data.labels.shift();
}
dataset.data.shift();
}
});
chart.update();
}
window.onload = function () {
var canvas = document.getElementById('elm-chart'),
ctx = canvas.getContext('2d');
var myLineChart = new Chart(ctx, {
type: 'line',
data: {
labels: [],
datasets: [
{
data: [],
label: 'Dataset-1',
backgroundColor: "#36a2eb88",
borderColor: "#36a2eb",
},
{
data: [],
label: 'Dataset-2',
backgroundColor: "#ff638488",
borderColor: "#ff6384",
}
],
},
options: {
responsive: false,
maintainAspectRatio: false,
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
var index = 0;
setInterval(function () {
var data = [];
myLineChart.data.datasets.forEach((dataset) => {
data.push(Math.random() * 100);
});
addData(myLineChart, index, data);
index++;
}, 1000);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js"></script>
<canvas id="elm-chart" width="640" height="480"></canvas>
There are 2 ways to solve it:
chart.update()
Delete existing chart using chart.destroy() and create new chart object.
The simplest way is to replace the canvas element and then call new Chart() again:
function reloadMyChart() {
$('myChart').replaceWith('<canvas id="myChart"></canvas>');
new Chart(document.getElementById("myChart"), {
data: yourChartData,
type: yourChartType,
options: yourChartOptions
});
}
Of course, you must replace yourChartData, yourChartType and yourChartOptions with the correct values required to initialize Chart.js. See Chart.js Docs.
You can call reloadMyChart function on a button click or any other event you need. Probably you'll add parameters to this function and use these to make a REST call to dynamically update your chart, like this:
function reloadMyChart(param1, param2) {
$('myChart').replaceWith('<canvas id="myChart"></canvas>');
$.get("restUrl?param1=" + param1 + "&param2=" + param2 + ",
function(data) {
// call new Chart() here and use returned data
}
);
Hope it helps! =)
Showing realtime update chartJS
function add_data(chart, label, data)
{
var today = new Date();
var time = today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds();
myLineChart.data.datasets[0].data.push(Math.random() * 100);
myLineChart.data.datasets[1].data.push(Math.random() * 100);
myLineChart.data.labels.push(time)
myLineChart.update();
}
setInterval(add_data, 10000); //milisecond
full code , you can download in description link
As of 2022 and using ChartJS v3.7.1 you can use the code below.
Note that it is based on the JSBin snippets in doub1ejack's answer but these were not up to date and wouldn't work with the latest ChartJS version, mainly because the path to charts' data changed (now being yourChart._metasets[0]._dataset.data).
var canvas = document.getElementById('updating-chart'),
ctx = canvas.getContext('2d'),
startingData = {
labels: [1, 2, 3, 4, 5, 6, 7],
datasets: [
{
fillColor: "rgba(220,220,220,0.2)",
strokeColor: "rgba(220,220,220,1)",
pointColor: "rgba(220,220,220,1)",
pointStrokeColor: "#fff",
data: [65, 59, 80, 81, 56, 55, 40]
},
{
fillColor: "rgba(151,187,205,0.2)",
strokeColor: "rgba(151,187,205,1)",
pointColor: "rgba(151,187,205,1)",
pointStrokeColor: "#fff",
data: [28, 48, 40, 19, 86, 27, 90]
}
]
};
// Reduce the animation steps for demo clarity.
const myLiveChart = new Chart(ctx, {
type: 'bar',
data: startingData,
options: {
scales: {
y: {
beginAtZero: true
}
},
maintainAspectRatio: false,
}
});
setInterval(function(){
// Get a random index point
var indexToUpdate = Math.round(Math.random() * startingData.labels.length);
// Update one of the points in the second dataset
myLiveChart._metasets[0]._dataset.data[indexToUpdate] = Math.random() * 100;
myLiveChart.update();
}, 5000);
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Updating chart example</title>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body>
<canvas id="updating-chart" width="500" height="300"></canvas>
</body>
</html>
You can check instance of Chart by using Chart.instances.
This will give you all the charts instances.
Now you can iterate on that instances and and change the data, which is present inside config.
suppose you have only one chart in your page.
for (var _chartjsindex in Chart.instances) {
/*
* Here in the config your actual data and options which you have given at the
time of creating chart so no need for changing option only you can change data
*/
Chart.instances[_chartjsindex].config.data = [];
// here you can give add your data
Chart.instances[_chartjsindex].update();
// update will rewrite your whole chart with new value
}
My solve was to actually store the charts outside of the state of Vue. Store the charts in a const variable in like a utility.js file. Then I was able to simply do this:
const PVR_CANVASES = {}
//This was my vue method for building the charts
build_metrics() {
this.votingResults.metrics.forEach(metric => {
const el = document.getElementById(metric.metric_data.canvas);
const n_chart = new Chart(el, {
type: 'line',
data: metric.chart.data,
options: {
responsive: true,
maintainAspectRatio: true,
layout: {
autoPadding: false
},
plugins: {
legend: {
display: false,
}
},
scales: {
x: {
display: false
},
y: {
display: false
}
},
elements: {
line: {
tension: 0.4
},
point: {
backgroundColor: 'rgba(0, 0, 0, 0.1)'
}
}
}
});
PVR_CANVASES[metric.chart.id] = n_chart;
})
}
//UPDATE CHART IS THIS SIMPLE
this.votingResults.metrics.forEach(metric => {
const n_chart = PVR_CANVASES[metric.chart.id];
n_chart.data = metric.chart.data;
n_chart.update();
});
So simple, Just replace the chart canvas element.
$('#canvas').replaceWith(' id="canvas" height="200px"
width="368px">');

Change color of a single point by clicking on it - Chart.JS

I'm building a scatter chart using Chart.JS(latest version), one of the behaviours I'm trying to implement is clicking on a single point and highlighting it by changing the background color of the selected point.
I've used the getElementsAtEvent method from the Chart.JS API in order to get the active element and change it's background. For a brief moment I can see it changing the color but it returns to its original color and all the other points now have the color I wanted to apply to the selected one... I tried various approaches to this, using the updated and render methods but with no desired result...
Here's the code inside the function that'll run onClick
function (evt, activeElements, chart) {
const selectedPoint = chart.getElementsAtEventForMode(evt, 'nearest', { intersect: true }, true);
selectedPoint[0].element.options.backgroundColor = '#fa6400';
chart.update();
}
Here's a fiddle
https://jsfiddle.net/dc3x70yg/1/
Thanks in advance
You can define the option pointBackgroundColor on the dataset. When the user clicks on a point, you recreate pointBackgroundColor, but now use an array that contains the desired color for each point.
Please take a look at your amended code below and see how it works.
new Chart('myChart', {
type: 'scatter',
data: {
datasets: [{
label: '# of Votes',
data: [{ x: -10, y: 0 }, { x: 0, y: 10 }, { x: 10, y: 5 }, { x: 0.5, y: 5.5 }],
pointBackgroundColor: '#ddd',
pointRadius: 5,
}]
},
options: {
onClick: (event, elements, chart) => {
const dataset = chart.data.datasets[0];
dataset.pointBackgroundColor = dataset.data.map((v, i) => i == elements[0]?.index ? '#fa6400': '#ddd');
chart.update();
},
scales: {
y: {
beginAtZero: true
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.0/chart.min.js"></script>
<canvas id="myChart" width="400" height="200"></canvas>

Decimal in x-axis

I'm trying to create a line chart with chart.js where the data in a dataset contains points:
data: [{x:0,y:5},{x:2.1,y:4.3},{x:3.9,y:3}]
The x values of those points contain decimals. The resulting chart looks like this:
Instead of showing the second data point at (2.1 | 4.3) it is drawn at (1 | 4.3)!
Can someone point me into the right direction on this one?
The code to reproduce this behavior:
<body>
<div>
<canvas id="myChart" width="400" height="200"></canvas>
</div>
<script>
var ctx = document.getElementById('myChart');
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: [0.0, 1.0, 2.0, 3.0, 4.0, 5.0],
datasets: [{
label: 'some label',
data: [{x:0,y:5},{x:2.1,y:4.3},{x:3.9,y:3}],
borderColor: 'red',
fill: false,
lineTension: 0
}]
},
options: {
scales: {
xAxes: [{
ticks: {
max: 10,
min: 0,
stepSize: 0.1
}
}],
yAxes: [{
ticks: {
max: 6,
min: 0,
stepSize: 1
}
}]
}
}
});
</script>
</body>
For the y-axis, using the stepSize variable of the ticks option does the trick. Doing the same for the x-axis is a little more complex but not impossible.
The first issue is that your x-axis labels are at integer intervals so the chart has nowhere to position the decimal values than at the closest integer. This can be fixed by specifying all the values in the desired intervals (ie: 0.1, 0.2,...,3.0) in the labels.
Then, making use of the autoSkip and maxTicksLimit, you can hide the labels not needed and so create the chart seen in your image, but with the points in the correct position.
I made a working version of this using your code in this fiddle. Hope this helps!

ChartJS Update specific bar's background colour

I would like to update specific column background colour but I couldn't do this. Seem like it is very easy but all the solution I tried out from google doesn't work. The code is as below.
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels : ["A","B","C","D","E"],
datasets: [{
data : [<?php echo $graph_data;?>],
backgroundColor: "rgba(0,0,220,0.5)",
borderColor: "rgba(0,0,220,1)",
borderWidth: 2
}]
}
});
//I would like to achieve something like this, let's say change the first and second bar's background color
myChart.datasets[0].bars[0].fillColor = "rgba(220,0,0,0.5)";
myChart.datasets[0].bars[1].fillColor = "rgba(220,0,0,0.5)";
myChart.update();
I had an old code which run succesfully under version 1.0.1-beta.4, but now I world like to use the latest version 2.5.0, and then I faced this issue.
Thanks for any helps!
You can just pass an array to the backgroundColor bar chart dataset property (instead of a single color) where the position in the array maps to the position in the data array.
For example, if you have 3 bars and want all 3 to be a different color, just pass an array to backgroundColor where all 3 elements have a different color value.
var ctx = document.getElementById("canvas").getContext("2d");
var myBar = new Chart(ctx, {
type: 'bar',
data: {
labels: ["Car", "Bike", "Walking"],
datasets: [{
label: 'Fuel',
backgroundColor: [
chartColors.red,
chartColors.blue,
chartColors.yellow],
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
]
}]
},
options: {
title: {
display: true,
text: "Chart.js - Different Bar Colors"
},
tooltips: {
mode: 'index',
intersect: false
},
legend: {
display: false,
},
responsive: true,
}
});
Here is a codepen example demonstrating this.

How to fix bar width in chartjs?

i'm starting new project using python and chart.js and i am using bar chart of chart.js, I want to fix width of every bars but it's still look like this, so how can i apply fix width for all bar?
Max 6 bar showing at a time, when we add 7th bar then horizontal scroll is appeared.
you can use :
barPercentage property like this
xAxes:[{
barPercentage: 0.1,
gridLines: {
display:false
}
}]
barPercentage takes value from 0 to 1 where 1 being the 100% available width
For more details on barPercentage see this
Sample FIDDLE
For fix width with different data variant :
Try this link1 link2
This fixes it
works for most versions, including in react.js
import {Chart} from "chart.js"
Chart.defaults.datasets.bar.barThickness = 73;
//also try barPercentage, maxBarThickness
use this as example
var ctx = document.getElementById("my_chart").getContext("2d");
new Chart(ctx, {
type: 'bar',
data: {
labels: ["Jan", "Feb", "Mar", "Apr"],
datasets: [{
label: "Title on top",
data: [10, 80, 56, 60],
backgroundColor: "#1491e5",
barThickness: 30 //<---- here important
}]
},
options: {
maintainAspectRatio: false//<---- here important
}
});