How to populate Jvector Map with countries from database? - php

(I am new to Javascript and jQuery..) I have a dashboard and I want to display a map that shows the countries where participants of a particular event are coming from. With this, I opted with Jvector Map. I am having a hard time displaying the countries in the map, coming from my database.
dashboard.js
var mapData = {};
$('#world-map').vectorMap({
map: 'world_mill_en',
backgroundColor: "transparent",
regionStyle: {
initial: {
fill: '#e4e4e4',
"fill-opacity": 0.9,
stroke: 'none',
"stroke-width": 0,
"stroke-opacity": 0
}
},
series: {
regions: [{
values: function() {
$.ajax({
url:"includes/sql/fetchcountries.php",
method:"GET",
data:mapData,
dataType:"json",
success: function(data){
mapData = data;
console.log(mapData);
}
})
},
scale: ["#1ab394", "#22d6b1"],
normalizeFunction: 'polynomial'
}]
},
});
fetch.php
<?php
require '../auth/dbh.inc.auth.php';
$id = $_SESSION['ntc_id'];
$stmt = $conn->prepare("SELECT DISTINCT(participants.p_country) FROM ntc_participants
INNER JOIN participants ON participants.p_id=ntc_participants.p_id_fk
WHERE ntc_participants.ntc_id_fk=?");
$data = array();
mysqli_stmt_bind_param($stmt, "i", $id);
$stmt->execute();
$result = $stmt->get_result();
if($result->num_rows === 0);
if($row = $result->fetch_assoc()) {
$data[] = [
$row['p_country'] => 0 ]; //the value 0 is just a placeholder.. The jvector map feeds on this format: "US":298, "SA": 200
}
echo json_encode($data);
?>
Could anyone be gracious enough to walk me through all the wrong things I'm doing in my code? Appreciate all the help! :)

Ajax is asynchronous, so You are creating the map before the data has been downloaded.
Initialize the map with empty values for Your region:
$('#world-map').vectorMap({
...
values: {}
...
});
Then, whenever You need to show the data, set it dynamically:
$.get("includes/sql/fetchcountries.php", function(data) {
var mapObj = $("#world-map").vectorMap("get", "mapObject");
mapObj.series.regions[0].setValues(data);
});
During the ajax invocation and data download maybe You can show a spinner (please look at beforeSend inside the jQuery full ajax documentation: https://api.jquery.com/jquery.ajax/).
Here is the reference for setValues:
http://jvectormap.com/documentation/javascript-api/jvm-dataseries/

http://api.worldbank.org/v2/country/all/indicator/NY.GDP.PCAP.PP.CD?format=json&date=2018
This link will give you up-to-date stats for most common indicators via json - and then you can pluck whatever data that you like. I don't have all the code yet, as I am working on this today too.
This answers the question above whenever your database can also present JSON
document.addEventListener('DOMContentLoaded', () => {
console.log("loaded")
fetchCountryData()
})
function fetchCountryData () {
fetch('http://api.worldbank.org/v2/country/all/indicator/NY.GDP.PCAP.PP.CD?format=json&date=2018')
//
.then(resp => resp.json())
.then(data => {
let country.id = data[1]
let indicator.id = data[1]
create-GDP-Data(country.id,indicator.id)
})
}
function create-GDP-Data(country.id,indicator.id){
let gdpData = ?
}
$('#world-map-gdp').vectorMap({
map: 'world_mill',
series: {
regions: [{
values: gdpData,
scale: ['#C8EEFF', '#0071A4'],
normalizeFunction: 'polynomial'
}]
},
onRegionTipShow: function(e, el, code){
el.html(el.html()+' (GDP - '+gdpData[code]+')');
}
});

Related

how to this line chart update mysql data using php ajax [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">');

AJAX data not posting using FullCalendar when trying to update

I have a calendar.php file which looks up "php/get-events" to display calendar events from the database (This currently works as expected). I am trying to use "php/calendarupdate" to then update the database with the new start/end times that have been dragged, but the data posting to this page always comes back as undefined, so it's not finding it for some reason.
"Calendar.php"
<script>
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
headerToolbar: {
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek'
},
initialDate: '2021-03-18',
editable: true,
eventDrop: function(event, delta) {
start=moment(event.start).format('Y-MM-DD HH:mm:ss');
end=moment(event.end).format('Y-MM-DD HH:mm:ss');
$.ajax({
url: 'php/calendarupdate.php',
data: 'title=' + event.title + '&start='+ event.start +'&end=' + event.end + '&id=' + event.id ,
type: "POST",
success: function(json) {
alert("Updated Successfully");
}
});
},
navLinks: true, // can click day/week names to navigate views
dayMaxEvents: true, // allow "more" link when too many events
events: {
url: '/php/get-events.php',
failure: function() {
document.getElementById('script-warning').style.display = 'block'
}
},
loading: function(bool) {
document.getElementById('loading').style.display =
bool ? 'block' : 'none';
}
});
calendar.render();
});
</script>
The following is where I get the data which successfully displays events on the calendar.
"php/get-events.php"
$stmt = $pdo->prepare("Select id,task_name,start,end,notes,task_type,status from tasks where attendees like ".$attendees);
$stmt->execute();
//$stmt->debugDumpParams();
foreach ($stmt as $row){
$rawdata[] = array('id' => $row['id'], 'title'=> $row['task_name'], 'start'=> $row['start'], 'end'=> $row['end']);
}
$rawdata = json_encode($rawdata);
echo $rawdata;
The following is the update file, which it is getting into ok, but the echo's I try to display are all undefined.
/* Values received via ajax */
echo "id -".$_POST['id'];
echo "start -".$_POST['start'];
echo "end -".$_POST['end'];
// update the records
$stmt = $pdo->prepare('UPDATE tasks SET start=?, end=? WHERE id=?');
$stmt->execute($_POST['start'], $_POST['end'], $_POST['id']);
$stmt->debugDumpParams();
It may be something simple, but from the documentation I've read, I can't seem to figure out why my variables are not posting successfully. Thanks.
You have the wrong syntax for your eventDrop signature. See https://fullcalendar.io/docs/eventDrop
It should be
eventDrop: function(info) {
And then replace
event.start
and
event.end
with
info.event.start
and
info.event.end
This will get the information you need correctly from the data which fullCalendar supplies.

multiple ajax requests from one page + how to do + best practice

I am working on google charts at the minute and I have got a basic one setup.
What it does at present is connects to a DB and returns a dataset based on 1 query. I am wondering is, if I want to draw more charts with different queries to the database how do I do this? Or what is the best practice?
For instance, there is already one connection with one query, how can I add another query, and then draw the charts based on what is returned?
I understand that might be a broad question, but maybe someone could show me how I would return a different query/dataset from the DB?
This is my code:
$(document).ready(function(){
console.log("hello world")
//alert("result")
$.ajax({
url:"data.php",
dataType : "json",
success : function(result) {
google.charts.load('current', {
'packages':['corechart','bar']
});
google.charts.setOnLoadCallback(function() {
console.log(result[0]["name"])
drawChart(result);
});
}
});
//add a 2nd call - will need a 2nd draw charts to draw the different dataset assuming it will be different
// - will need a 2nd data.php as the query will be different on the dataset
$.ajax({
url:"data.php",
dataType : "json",
success : function(result2) {
google.charts.load('current', {
'packages':['corechart','bar']
});
google.charts.setOnLoadCallback(function() {
console.log(result2[0]["name"])
drawChart(result2);
});
}
});
function drawChart(result) {
var data = new google.visualization.DataTable();
data.addColumn('string','Name');
data.addColumn('number','Quantity');
var dataArray=[];
$.each(result, function(i, obj) {
dataArray.push([ obj.name, parseInt(obj.quantity) ]);
});
data.addRows(dataArray);
var piechart_options = {
title : 'Pie Chart: How Much Products Sold By Last Night',
width : 400,
height : 300
}
var piechart = new google.visualization.PieChart(document
.getElementById('piechart_div'));
piechart.draw(data, piechart_options)
var columnchart_options = {
title : 'Bar Chart: How Much Products Sold By Last Night',
width : 400,
height : 300,
legend : 'none'
}
//var barchart = new google.visualization.BarChart(document
// .getElementById('barchart_div'));
//barchart.draw(data, barchart_options)
var chart = new google.charts.Bar(document.getElementById('columnchart_material'));
chart.draw(data, google.charts.Bar.convertOptions(columnchart_options));
} //have added this column chart but need to wrok out if it is best practice????
});
I am getting an object back from my DB query, but I want to know how to return more/different datasets from the same DB connection? For example what if I wanted to draw another chart with the dataset returned from this query select * from product where name="Product1" OR name="Product2";
0: Object { id: "1", name: "Product1", quantity: "2" }
​1: Object { id: "2", name: "Product2", quantity: "3" }
​2: Object { id: "3", name: "Product3", quantity: "4" }
​3: Object { id: "4", name: "Product4", quantity: "2" }
​4: Object { id: "5", name: "Product5", quantity: "6" }
​5: Object { id: "6", name: "Product6", quantity: "11" }
For what it is worth my php code is as follows:
data.php
<?php
require_once 'database.php';
$stmt = $conn->prepare('select * from product');
$stmt->execute();
$results = $stmt->fetchAll(PDO::FETCH_OBJ);
echo json_encode($results);
?>
database.php
<?php
$conn = new PDO('mysql:host=192.168.99.100;dbname=demo','root', 'root');
?>
note: this might be of interest
google charts only needs to be loaded once per page load,
not every time you need to draw a chart
also, google.charts.load can be used in place of --> $(document).ready
it will wait for the page to load before executing the callback / promise
recommend setup similar to following snippet...
google.charts.load('current', {
packages: ['corechart', 'bar']
}).then(function () {
$.ajax({
url: 'data.php',
dataType: 'json'
}).done(drawChart1);
$.ajax({
url: 'data.php',
dataType: 'json'
}).done(drawChart2);
});
function drawChart1(result) {
...
}
function drawChart2(result) {
...
}

Data will not draw onto my chart

I am trying to output data onto a chart using the chart.js lib. I have successfully pulled the data out I need and created the datasets but for some reason it just will not render onto the chart.
I have three files:
teamData.js
$(document).ready(function(){
$.ajax({
url : "http://localhost/acredashAdv/teamData.php",
type : "GET",
success :function(data){
console.log(data);
var score_1 = [];
var score_2 = [];
for (var i in data) {
score_1.push(data[i].score_1);
score_2.push(data[i].score_2);
}
var chartata = {
labels: [
"Strategic Development and Ownership",
"Driving change through others",
"Exec Disposition",
"Commercial Acumen",
"Develops High Performance Teams",
"Innovation and risk taking",
"Global Leadership",
"Industry Leader"
],
datasets : [
{
label: "user 1",
backgroundColor: "rgba(0,0,0,0)",
borderColor: "#B71C1C",
data: score_1,
},
{
label: "user 2",
backgroundColor: "rgba(0,0,0,0)",
borderColor: "#B71C1C",
data: score_2
},
]
};
var ctx = $("#mycanvas");
var LineGraph = new Chart(ctx, {
type: 'radar',
data: chartata,
animationEasing: 'linear'
});
},
error :function(data){
},
});
});
teamData.php
<?php
include 'config.php';
$query = sprintf("SELECT member_id, firstName, lastName, score_1, score_2, score_3, score_4, score_5, score_6, score_7, score_8 FROM members");
$result = $conn->query($query);
$data = array();
foreach ($result as $row) {
$data[] = $row;
}
$result->close();
$conn->close();
print json_encode($data);
?>
teams.php
<div style="max-width: 500px;">
<canvas id="mycanvas" class="container"></canvas>
</div>
On my console.log I can see the data is coming through correctly:
[{"member_id":"144","firstName":"Dan","lastName":"Barrett","score_1":"4","score_2":"2","score_3":"3","score_4":"5","score_5":"1","score_6":"3","score_7":"5","score_8":"4"},{"member_id":"145","firstName":"Jon","lastName":"Smith","score_1":"3","score_2":"4","score_3":"1","score_4":"2","score_5":"1","score_6":"2","score_7":"3","score_8":"4"},{"member_id":"146","firstName":"Dan","lastName":"Barrett","score_1":"1","score_2":"2","score_3":"1","score_4":"1","score_5":"4","score_6":"1","score_7":"4","score_8":"3"}]
But unless I am getting mixed up it will not draw out the data... I end up with an empty chart.
Maybe could be the version of your Chart.js, here is your code running:
https://jsfiddle.net/6xdvj5u3/
Using this version of Chart.js
https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.4/Chart.bundle.min.js
try to take the PabloMartinez's recommendation adding a header to your PHP file, before your print line:
header('Content-type: application/json');
print json_encode($data);

Highcharts Pie Chart via AJAX/JSON: But Slice Errors and Json Format Not Correct?

I'm a newbie php/js/mysql programmer.
I'm trying to create a pie chart in highcharts using jquery, where the data is discovered dynamically via ajax from echo json_encode in php (includes a select query from mysql).
Two problems:
1) The pie chart has these trailing "Slice: 0 %" flares everywhere. Don't know where these are coming from, what it means, nor how to fix it.
2) Json is new to me. The json data feed appears to be getting through (firebug sees it), but the format looks like this. I'm trying to boil it down to name and percent number only. Like this ['Pages', 45.0] but not sure how. Is this done in the json/php or should it be done in the sql query itself?
[{"contenttype":"BLOGPOST","count(*)":"2076"},{"contenttype":"COMMENT","count(*)":"2054"},{"contenttype":"MAIL","count(*)":"29448"},{"contenttype":"PAGE","count(*)":"33819"}]
Any help much appreciated
The highcharts js file is here:
//Define the chart variable globally,
var chart;
//Request data from the server, add it to the graph and set a timeout to request again
function requestData() {
$.ajax({
url: 'hc1.php',
success: function(point) {
var series = chart.series[0],
shift = series.data.length > 20; // shift if the series is longer than 20
// add the point
chart.series[0].addPoint(point, true, shift);
// call it again after one second
setTimeout(requestData, 1000);
},
cache: false
});
}
$(document).ready(function(){
//Create the test chart
chart = new Highcharts.Chart({
chart: {
renderTo: 'mycontainer2',
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false,
events: {load: requestData}
},
title: {text: 'Content Types in Wiki'},
tooltip: {formatter: function() {return '<b>'+ this.point.name +'</b>: '+ this.percentage +' %';}
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
dataLabels: {
enabled: true,
//color: Highcharts.theme.textColor || '#000000',
//connectorColor: Highcharts.theme.textColor || '#000000',
formatter: function() {
return '<b>'+ this.point.name +'</b>: '+ this.percentage +' %';
}
}
}
},
series: [{
type: 'pie',
name: 'Content',
data: []
}]
});
The php file is here:
<?php
// Set the JSON header
header("Content-type: text/json");
// Connect to db
include('dbconnect.php');
// Count version 1 of content types of interest
$query = ("select contenttype, count(*)
from CONTENT
where version='1' and contenttype='page' or contenttype='comment' or contenttype='blogpost' or contenttype='mail' or contenttype='drafts'
group by CONTENT.contenttype;");
// execute query
$result = mysql_query($query) or die ("Error in query: $query. ".mysql_error());
// create a php array and echo it as json
//$row = mysql_fetch_assoc($result);
//echo json_encode($row);
$results = array(); while ( $row = mysql_fetch_assoc( $result )) { $results[] = $row; }
echo json_encode($results);
?>
First problem, how do you get your data into a format that highcharts is going to accept (namely arrays of arrays, [[name,percent],[nextname,percent],etc])? I would handle this in your PHP:
<snip>
// execute query
$result = mysql_query($query) or die ("Error in query: $query. ".mysql_error());
$total = 0;
$results = array();
while ( $row = mysql_fetch_assoc( $result )) {
$results[$row["contenttype"] = $row["count()"];
$total += $row["count()"];
}
$forHigh = array();
foreach ($results as $k => $v) {
$forHigh[]=array($k,($v/$total) * 100); // get percent and push onto array
}
echo json_encode($forHigh); // this should be an array of array
Now that our JSON returned structure is ready for HighCharts, we just need to call the plot creation once after our JSON call to create the plot. I would do it in the success callback of the $.ajax call.
$.ajax({
url: 'hc1.php',
success: function(jsonData) {
chart = new Highcharts.Chart({
<snip>
series: [{
type: 'pie',
name: 'Content',
data: jsonData
}]
<snip>
},
cache: false
});

Categories