Save graph as image after click link full script - chart.js

I have this code
<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-2.0.2.js"></script>
<script type="text/javascript" src="js/chart-js/Chart.js"></script>
<script type="text/javascript">
var data = [
{
value: 300,
color:"#F7464A",
highlight: "#FF5A5E",
label: "Red"
},
{
value: 50,
color: "#46BFBD",
highlight: "#5AD3D1",
label: "Green"
},
{
value: 100,
color: "#FDB45C",
highlight: "#FFC870",
label: "Yellow"
}
];
$(document).ready(
function () {
var ctx = document.getElementById("myChart").getContext("2d");
var myNewChart = new Chart(ctx).Pie(data);
document.getElementById("canvas_link").src = document.getElementById("myChart").toDataURL();
}
);
</script>
</head>
<body>
<p>save as image</p>
<canvas id="myChart" width="400" height="400"></canvas>
<p>export to pdf</p>
</body>
I need create pdf export and add into image with gener graph. Berofe I must save render image. I try use method .toBase64Image() but I dont know have can I start.
My proceed
create canvas_link (.toDataUrl). After click save as image I can greate and upload image to server. Then I can generate pdf export (across mPDF) and to add imageto into export. This i can create, but I dont know create and upload image of graph to server.
I need more examples from http://www.chartjs.org/docs/

in that case you don't need to upload as an image.
you could put the result of the call to toDataUrl function in the value of a hidden field and send it in a form (with an iframe as target) or by an ajax call
use the following options in the chart
//new options var
var options = {
bezierCurve : false,
//animation: false
onAnimationComplete: done
};
//your code with a little modification
$(document).ready(
function () {
var ctx = document.getElementById("myChart").getContext("2d");
//use the previously defined "options" here!!!
var myNewChart = new Chart(ctx).Pie(data, options);
}
);
//callback function, called when the pie ends his animation
function done(){
//this part of your code was moved here to avoid that store an empty image
document.getElementById("canvas_link").src = document.getElementById("myChart").toDataURL();
var postdata={
file: document.getElementById("myChart").toDataURL()
}
$.post( "store.php", postdata)
.done(function( ret ) {
console.log( "Data status: Loaded successfully ");
})
.fail(function( ret ) {
console.log( "Data status: error ");
})
;
}
Reference: http://api.jquery.com/jquery.post/
in php you can handle the content in this way
// file: store.php
// Interpret data uri
$uriPhp = 'data://' . substr($file, 5);
// Get content
$binary = file_get_contents($uriPhp);
$file = 'uploads/charts/'. time() .'.png';
// Save image
file_put_contents($file, $binary);
Reference: https://github.com/nnnick/Chart.js/issues/99#issuecomment-75359927

As per the documentation, you can print or save graph by API calls;
Example
var chart = new CanvasJS.Chart("chartContainer", {
theme: "theme2",
title:{
text: "Print Chart using print() method"
},
data: [
{
type: "column",
dataPoints: [
{ label: "apple", y: 10 },
{ label: "orange", y: 15 },
{ label: "banana", y: 25 },
{ label: "mango", y: 30 },
{ label: "grape", y: 28 }
]
}
]
});
chart.render();
document.getElementById("printChart").addEventListener("click",function(){
chart.print();
//chart.exportChart({format: "jpg"});
});

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">');

Resource interpreted as Document but transferred with MIME type image/octet-stream

Using the following code to save a Google chart. But it is getting downloaded as a file and not an image, it was throwing following
"Resource interpreted as Document but transferred with MIME type image/octet-stream: "data:image/octet-stream;base64,..."
And the code:
function getImgData(chartContainer) {
var chartArea = chartContainer.getElementsByTagName('div')[1];
var svg = chartArea.innerHTML;
var doc = chartContainer.ownerDocument;
var canvas = doc.createElement('canvas');
canvas.setAttribute('width', chartArea.offsetWidth);
canvas.setAttribute('height', chartArea.offsetHeight);
canvas.setAttribute(
'style',
'position: absolute; ' +
'top: ' + (-chartArea.offsetHeight * 2) + 'px;' +
'left: ' + (-chartArea.offsetWidth * 2) + 'px;');
doc.body.appendChild(canvas);
canvg(canvas, svg);
var imgData = canvas.toDataURL("image/png");
canvas.parentNode.removeChild(canvas);
return imgData;
}
function saveAsImg(chartContainer) {
var imgData = getImgData(chartContainer);
window.location = imgData.replace("image/png", "image/octet-stream");
}
you can use an anchor tag with a download attribute to assign the file name
and most charts have a getImageURI method
also, don't see the need to replace("image/png", "image/octet-stream")
see following working snippet...
google.charts.load('current', {
callback: function () {
var chart = new google.visualization.PieChart(document.getElementById('chart_div'));
google.visualization.events.addListener(chart, 'ready', function () {
// set anchor tag
var saveLink = document.getElementById('saveLink');
saveLink.href = chart.getImageURI();
// cause download to occur
saveLink.click();
});
chart.draw(google.visualization.arrayToDataTable([
['Task', 'Hours'],
['A', 19.2],
['B', 30.8],
['C', 50.0]
]), {
height: 200,
chartArea: {
top: 24
},
legend: 'none',
pieHole: 0.4,
theme: 'maximized',
width: 200
});
},
packages: ['corechart']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
<a id="saveLink" download="chart.png">Save Chart</a>

Hide text from Google GeoChart tooltip

I have a Google Geochart that is connected to a Google Spreadsheet. The aim of the chart is to show different categories of universities in our state and their locations. I have assigned values in the spreadsheet in order to have the appropriate marker color for the map to denote the categories.
My problem is that the text denoting the type (a number) is showing in the tooltip. (Example: tooltip shows "ABC University Type 3." I need to either hide this text, or create a string based on conditional logic so that, for example, Type 3 translates to "XYZ System" in the tooltip. Which do you think is the better way to do it, and can you provide guidance as to how to do this?
<html>
<head>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script>
google.charts.load('current', { 'packages': ['geochart'] });
google.charts.setOnLoadCallback(drawMap);
function drawMap() {
var query = new google.visualization.Query("https://docs.google.com/spreadsheets/d/1m3ujxzPQJh3haReNDzGGF73Mh6-u6HxyCVPK_5MK2hw/gviz/tq?sheet=Sheet3");
query.send(handleQueryResponse);
}
function handleQueryResponse(response) {var data = response.getDataTable();
var options = {
//showTip: true,
mapType: 'styledMap',
useMapTypeControl: true,
resolution: 'provinces',
//displayMode: 'text',
//magnifyingGlass: {'enable': true, 'zoomFactor': '7'},
region: 'US-KY',
keepAspectRatio: true,
legend: 'none',
sizeAxis: { minValue: 1, maxValue: 3, minSize: 10, maxSize: 10 },
colorAxis: {colors: ['green', 'blue', 'purple'], values: [1, 2, 3]},
markerOpacity: 0.75,
tooltip: {showColorCode: false, isHTML: true, textStyle:{fontSize: 21}},
dataMode: 'markers'
};
var map = new google.visualization.GeoChart(document.getElementById('chart_div'));
map.draw(data, options);
};
</script>
<style type="text/css">
html, body {height: 100%;}
#chart_div {width: 100%; height: 100%;}
</style>
</head>
<body>
<div id="chart_div"></div>
</body>
</html>
You can use the DataView Class to change the formatted value of the Type column.
For instance, the value of the Type column in the DataTable looks like this...
{"v":3.0,"f":"3"}
With the DataView, change it to this...
{"v":3.0,"f":"XYZ System"}
We can also remove the column Label, to avoid seeing it in the tooltip.
See following example...
google.charts.load('current', {
callback: drawMap,
packages: ['geochart']
});
function drawMap() {
var query = new google.visualization.Query("https://docs.google.com/spreadsheets/d/1m3ujxzPQJh3haReNDzGGF73Mh6-u6HxyCVPK_5MK2hw/gviz/tq?sheet=Sheet3");
query.send(handleQueryResponse);
}
function handleQueryResponse(response) {
var data = response.getDataTable();
// setup school type array
var schoolTypes = [
'ABC System',
'LMO System',
'XYZ System'
];
// create DataView from DataTable
var view = new google.visualization.DataView(data);
// set view columns, keep first three columns
// use calculated column for Type
view.setColumns([0, 1, 2, {
type: 'number',
label: '',
calc: function (dataTable, rowIndex) {
return {
v: dataTable.getValue(rowIndex, 3),
// get school type from array
f: schoolTypes[dataTable.getValue(rowIndex, 3) - 1]
}
}
}]);
var options = {
//showTip: true,
mapType: 'styledMap',
useMapTypeControl: true,
resolution: 'provinces',
//displayMode: 'text',
//magnifyingGlass: {'enable': true, 'zoomFactor': '7'},
region: 'US-KY',
keepAspectRatio: true,
legend: 'none',
sizeAxis: { minValue: 1, maxValue: 3, minSize: 10, maxSize: 10 },
colorAxis: {colors: ['green', 'blue', 'purple'], values: [1, 2, 3]},
markerOpacity: 0.75,
tooltip: {showColorCode: false, isHTML: true, textStyle:{fontSize: 21}},
dataMode: 'markers'
};
var map = new google.visualization.GeoChart(document.getElementById('chart_div'));
map.draw(view, options);
};
<script src="https://www.gstatic.com/charts/loader.js"></script>
<script src="https://www.google.com/jsapi"></script>
<div id="chart_div"></div>
ALSO -- Recommend including loader.js and jsapi only once per page

Power bi api - Label width needs adjustment

My vertical labels in the graph are getting cut off.
Is there a way to set/increase the label width?
Please see the image below.
The left hand labels need more width. (Y axis labels)
Power BI Column Graph Using API
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<link href="https://raw.githubusercontent.com/Microsoft/PowerBI-visuals/master/lib/visuals.css" rel="stylesheet">
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript" src="http://microsoft.github.io/PowerBI-visuals/playground/externals.min.js"> </script>
<script type="text/javascript" src="http://microsoft.github.io/PowerBI-visuals/playground/powerbi-visuals.js" ></script>
<script type="text/javascript" src="http://microsoft.github.io/PowerBI-visuals/playground/PowerBIVisualsPlayground.js"></script>
<style>
.visual {
'background-color' : 'white',
'padding' : '10px',
'margin' : '5px'
}
</style>
</head>
<body>
<h1> hello </h1>
<div class="visual"></div>
<script type="text/javascript">
var createDataView = function () {
var DataViewTransform = powerbi.data.DataViewTransform;
var fieldExpr = powerbi.data.SQExprBuilder.fieldExpr({ column: { entity: "table1", name: "country" } });
var categoryValues = ["Australia", "Canada", "France", "Germany", "United Kingdom", "United States"];
var categoryIdentities = categoryValues.map(function (value) {
var expr = powerbi.data.SQExprBuilder.equal(fieldExpr, powerbi.data.SQExprBuilder.text(value));
return powerbi.data.createDataViewScopeIdentity(expr);
});
// Metadata, describes the data columns, and provides the visual with hints
// so it can decide how to best represent the data
var dataViewMetadata = {
columns: [
{
displayName: 'Country',
queryName: 'Country',
type: powerbi.ValueType.fromDescriptor({ text: true })
},
{
displayName: 'Sales Amount (2014)',
isMeasure: true,
format: "$0",
queryName:'sales1',
type: powerbi.ValueType.fromDescriptor({ numeric: true }),
}
,
{
displayName: 'Sales Amount (2013)',
isMeasure: true,
format: "$0",
queryName:'sales2',
type: powerbi.ValueType.fromDescriptor({ numeric: true })
}
],
};
var columns = [
{
source: dataViewMetadata.columns[1],
// Sales Amount for 2014
values: [742731.43, 162066.43, 283085.78, 300263.49, 376074.57, 814724.34],
},
{
source: dataViewMetadata.columns[2],
// Sales Amount for 2013
values: [742731.43, 162066.43, 283085.78, 300263.49, 376074.57, 814724.34].reverse()
}
];
var dataValues = DataViewTransform.createValueColumns(columns);
var dataView = {
metadata: dataViewMetadata,
categorical: {
categories: [{
source: dataViewMetadata.columns[0],
values: categoryValues,
identity: categoryIdentities,
}],
values: dataValues
}
};
return dataView;
};
function createDefaultStyles(){
var dataColors = new powerbi.visuals.DataColorPalette();
return {
titleText: {
color: { value: 'rgba(51,51,51,1)' }
},
subTitleText: {
color: { value: 'rgba(145,145,145,1)' }
},
colorPalette: {
dataColors: dataColors,
},
labelText: {
color: {
value: 'rgba(51,51,51,1)',
},
fontSize: '11px'
},
isHighContrast: false,
};
}
function createVisual() {
var pluginService = powerbi.visuals.visualPluginFactory.create();
var defaultVisualHostServices = powerbi.visuals.defaultVisualHostServices;
var width = 600;
var height = 400;
var element = $('.visual');
element.height(height).width(width);
// Get a plugin
var visual = pluginService.getPlugin('columnChart').create();
powerbi.visuals.DefaultVisualHostServices.initialize();
visual.init({
// empty DOM element the visual should attach to.
element: element,
// host services
host: defaultVisualHostServices,
style: createDefaultStyles(),
viewport: {
height:height,
width: width
},
settings: { slicingEnabled: true },
interactivity: { isInteractiveLegend: false, selection: false },
animation: { transitionImmediate: true }
});
// Call update to draw the visual with some data
visual.update({
dataViews: [createDataView()] ,
viewport: {
height: height,
width: width
},
duration: 0
});
}
createVisual();
</script>
</body>
</html>
To do it automatically, you'll need to measure the text and allocate sufficient room. You might try an approach similar to this. Alternately, you could add a property for label size in the formatting pane and let your users override the default.

Chartjs Graph is not showing in colorbox

I am trying to display a Doughnut Chart in the popup(colorbox) with the dummy values but it is giving error, but if i simply call it in browser(via url) it display the graph.
IndexSizeError: Index or size is negative or greater than the allowed amount.
var DoughnutChart = [{
value: 60,
color: "#fcc79e"
}, {
value: 30,
color: "#beefd2"
}, {
value: 50,
color: "#ffddfb"
}, {
value: 20,
color: "#cdecff"
}, {
value: 90,
color: "#fff5bc"
}];
var myDoughnutChart = new Chart(document.getElementById("canvas").getContext("2d")).Doughnut(DoughnutChart);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<canvas id="canvas" height="450" width="600"></canvas>
Chart.js needs the canvas to have a rendered size before it can be rendered. So you need to have your chart initialization inside the cbox_complete event hook instead of doing it first and then opening the colorbox
Something like
$(document).bind('cbox_complete', function () {
var DoughnutChart = [{
...
...
var myDoughnutChart = new Chart(document.getElementById("canvas").getContext("2d")).Doughnut(DoughnutChart);
});