using ajax populate dynamic piechart from chartjs - javascript

Hello there stack overflow programmers, i have a question related to getting data from my database using ajax and display it in piechart from chartjs library. Now i am trying to make dynamic data to be accepted by format within piechart format.
Here is my ajax and its response: ( still it doesn't show my piegraph. i dont know why)
function getpieclinic() {
$.ajax({
type: "POST",
url: siteurl+"patients_report/piedataclinic",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: OnSuccess_,
error: OnErrorCall_
});
function OnSuccess_(response) {
// alert("hi");
var aData = response.d;
var arr = [];
$.each(aData, function (inx, val) {
var obj = {};
obj.color = val.color;
obj.value = val.value;
obj.label = val.label;
arr.push(obj);
});
var ctx = $("#myChart").get(0).getContext("2d");
var myPieChart = new Chart(ctx).Pie(arr);
}
function OnErrorCall_(response) {}
}
the response of my ajax is these:
[{"clinic_name":"Clinic 1","total_checked_up":"4"},{"clinic_name":"Clinic 2","total_checked_up":"0"},{"clinic_name":"Clinic 3","total_checked_up":"0"},{"clinic_name":"Clinic 4","total_checked_up":"0"}]
now, i want to make a dynamic format of piechart chartjs data format to be able to display it. this is the default format from the example:
var pieChartCanvas = $("#pieChart").get(0).getContext("2d");
var pieChart = new Chart(pieChartCanvas);
var PieData = [
{
value: 700,
color: "#f56954",
highlight: "#f56954",
label: "Chrome"
},
{
value: 500,
color: "#00a65a",
highlight: "#00a65a",
label: "IE"
},
{
value: 400,
color: "#f39c12",
highlight: "#f39c12",
label: "FireFox"
},
{
value: 600,
color: "#00c0ef",
highlight: "#00c0ef",
label: "Safari"
},
{
value: 300,
color: "#3c8dbc",
highlight: "#3c8dbc",
label: "Opera"
},
{
value: 100,
color: "#d2d6de",
highlight: "#d2d6de",
label: "Navigator"
}
];
var pieOptions = {
//Boolean - Whether we should show a stroke on each segment
segmentShowStroke: true,
//String - The colour of each segment stroke
segmentStrokeColor: "#fff",
//Number - The width of each segment stroke
segmentStrokeWidth: 2,
//Number - The percentage of the chart that we cut out of the middle
percentageInnerCutout: 50, // This is 0 for Pie charts
//Number - Amount of animation steps
animationSteps: 100,
//String - Animation easing effect
animationEasing: "easeOutBounce",
//Boolean - Whether we animate the rotation of the Doughnut
animateRotate: true,
//Boolean - Whether we animate scaling the Doughnut from the centre
animateScale: false,
//Boolean - whether to make the chart responsive to window resizing
responsive: true,
// Boolean - whether to maintain the starting aspect ratio or not when responsive, if set to false, will take up entire container
maintainAspectRatio: true,
//String - A legend template
legendTemplate: "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<segments.length; i++){%><li><span style=\"background-color:<%=segments[i].fillColor%>\"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>"
};
//Create pie or douhnut chart
// You can switch between pie and douhnut using the method below.
pieChart.Doughnut(PieData, pieOptions);

You could accomplish this in the following way ...
// for demonstration purposes only
// use response.d in real case scenario
var response = [{ "clinic_name": "Clinic 1", "total_checked_up": "10" }, { "clinic_name": "Clinic 2", "total_checked_up": "20" }, { "clinic_name": "Clinic 3", "total_checked_up": "30" }, { "clinic_name": "Clinic 4", "total_checked_up": "40" }]; // response from ajax request
OnSuccess_(response);
function OnSuccess_(response) {
var pieChartCanvas = $("#pieChart").get(0).getContext("2d");
var pieChart = new Chart(pieChartCanvas);
var PieData = [];
// create PieData dynamically
response.forEach(function(e) {
var random_color = '#' + Math.floor(Math.random() * 16777215).toString(16);
PieData.push({
value: e.total_checked_up,
color: random_color,
highlight: random_color,
label: e.clinic_name
});
});
var pieOptions = {
//Boolean - Whether we should show a stroke on each segment
segmentShowStroke: true,
//String - The colour of each segment stroke
segmentStrokeColor: "#fff",
//Number - The width of each segment stroke
segmentStrokeWidth: 2,
//Number - The percentage of the chart that we cut out of the middle
percentageInnerCutout: 0, // This is 0 for Pie charts
//Number - Amount of animation steps
animationSteps: 100,
//String - Animation easing effect
animationEasing: "easeOutBounce",
//Boolean - Whether we animate the rotation of the Doughnut
animateRotate: true,
//Boolean - Whether we animate scaling the Doughnut from the centre
animateScale: false,
//Boolean - whether to make the chart responsive to window resizing
responsive: true,
// Boolean - whether to maintain the starting aspect ratio or not when responsive, if set to false, will take up entire container
maintainAspectRatio: true,
//String - A legend template
legendTemplate: "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<segments.length; i++){%><li><span style=\"background-color:<%=segments[i].fillColor%>\"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>"
};
//Create pie or douhnut chart
// You can switch between pie and douhnut using the method below.
pieChart.Doughnut(PieData, pieOptions);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.2/Chart.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id="pieChart"></canvas>

Related

Saving pie chart as an image using database data

Require some help when trying to save chart as an image. Sorry just started this new chart.js.
Issue:
How do I add my database data inside the chart? I keep try to add in $user but it keep giving me undefined user.
Here is the data that I want to add in from my database,
$users = DB::table('personal_infos')
->join('evaluations','evaluations.user_id', '=', 'personal_infos.id')
->select('evaluations.recommendation','evaluations.created_at' )
->where('evaluations.recommendation', '=', 'Yes')
->get();
For now I just used something like this to generate the pie chart:
<script type="text/javascript">
$("#save-btn").click(function() {
$("#canvas").get(0).toBlob(function(blob) {
saveAs(blob, "chart_1.png");
});
});
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"
}
];
var ctx = $("#canvas").get(0).getContext("2d");
var mychart = new Chart(ctx).Pie(data,
{
//Boolean - Whether we should show a stroke on each segment
segmentShowStroke : false,
//String - The colour of each segment stroke
segmentStrokeColor : "#fff",
//Number - The width of each segment stroke
segmentStrokeWidth : 2,
//Number - The percentage of the chart that we cut out of the middle
percentageInnerCutout : 0, // This is 0 for Pie charts
//Number - Amount of animation steps
animationSteps : 10,
//String - Animation easing effect
animationEasing : "linear",
//Boolean - Whether we animate the rotation of the Doughnut
animateRotate : true,
//Boolean - Whether we animate scaling the Doughnut from the centre
animateScale : false,
//String - A legend template
legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<segments.length; i++){%><li><span style=\"background-color:<%=segments[i].fillColor%>\"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>"
}
);
</script>

angular chart pie-chart data click event

Angular JS chart is awesome, But i need to implement click event in the piechart which i have created.. Here is the coding..
This is the JavaScript Coding...
$scope.pied = [{
value: 4,
color: "#FF5A5E",
highlight: "#FF5A5E",
label: "Prospective"
}, {
value: 0,
color: "#46BFBD",
highlight: "#46BFBD",
label: "Pending"
}, {
value: 0,
color: "#FDB45C",
highlight: "#FDB45C",
label: "CallBacks"
}, {
value: 4,
color: "#e6e6fa",
highlight: "#e6e6fa",
label: "FollowUp"
}, {
value: 1,
color: "#cc5229",
highlight: "#cc5229",
label: "Not Interested"
}, {
value: 0,
color: "#556b2f",
highlight: "#556b2f",
label: "Close"
}]
var pieOptions = {
//Boolean - Whether we should show a stroke on each segment
segmentShowStroke: true,
//String - The colour of each segment stroke
segmentStrokeColor: "#fff",
//Number - The width of each segment stroke
segmentStrokeWidth: 2,
//Boolean - Whether we should animate the chart
animation: true,
//Number - Amount of animation steps
animationSteps: 100,
//String - Animation easing effect
animationEasing: "easeOutBounce",
//Boolean - Whether we animate the rotation of the Pie
animateRotate: true,
//Boolean - Whether we animate scaling the Pie from the centre
animateScale: false,
//Function - Will fire on animation completion.
onAnimationComplete: null
}
var ctx = document.getElementById("pieChart").getContext("2d");
var myPieChart = new Chart(ctx).Pie($scope.pied, pieOptions);
ctx.onclick = function(evt){
var activePoints = myPieChart.getPointsAtEvent(evt);
console.log("active: "+activePoints);
// => activePoints is an array of points on the canvas that are at the same position as the click event.
};
document.getElementById('js-legend').innerHTML = myPieChart.generateLegend();
This is the HTML Coding..
<canvas id="pieChart" width="440" height="200" ></canvas>
<div id="js-legend" class="chart-legend"></div>
This is the image of the above program.. i have wrote coding that when i click on The FollowUP it must the datas related to it.. But the click event is not working..??
Please see to the above code and picture and guide me to get the exact output what i expect. Thanks in advance guys...
I have Used angular-chart.js instead this chart.js Angular JS Documentation is here . Angular Chart is little bit easy than chart.js..
Thanks for the support guys.. :)

Cannot get react-chartjs to update

I am trying to follow the "Example usage" code from react-chartjs github page
I am new to javascript and react and probably just being naive. How can I get the new chartData from "_onChange" to update my PolarAreaChart? I tried something more direct by calling element.getDocumentById("polarChart"), but that returns nothing and then I cannot call .update on it... the whole "insert redraw in the xml" and it will magically call update seems magical to me :(
PolarPlot.jsx
var React = require ('react');
var PolarAreaChart = require ('react-chartjs').PolarArea;
var FilterStore = require ('FilterStore')
var PolarPlot = React.createClass ({
componentWillMount: function () {
FilterStore.addChangeListener (this._onChange);
},
_onChange: function () {
console.log("time to update")
chartData = [
{
value: 300,
color:"#F7464A",
highlight: "#FF5A5E",
label: "Red"
}]
},
render: function () {
return (
<PolarAreaChart id="polarChart" data={chartData} options={chartOptions} redraw/>
);
}
});
var chartData = [
{
value: 300,
color:"#F7464A",
highlight: "#FF5A5E",
label: "Red"
},
{
value: 50,
color: "#46BFBD",
highlight: "#5AD3D1",
label: "Green"
},
{
value: 100,
color: "#FDB45C",
highlight: "#FFC870",
label: "Yellow"
},
{
value: 40,
color: "#949FB1",
highlight: "#A8B3C5",
label: "Grey"
},
{
value: 120,
color: "#4D5360",
highlight: "#616774",
label: "Dark Grey"
}
];
var chartOptions = [
{
//Boolean - Show a backdrop to the scale label
scaleShowLabelBackdrop : true,
//String - The colour of the label backdrop
scaleBackdropColor : "rgba(255,255,255,0.75)",
// Boolean - Whether the scale should begin at zero
scaleBeginAtZero : true,
//Number - The backdrop padding above & below the label in pixels
scaleBackdropPaddingY : 2,
//Number - The backdrop padding to the side of the label in pixels
scaleBackdropPaddingX : 2,
//Boolean - Show line for each value in the scale
scaleShowLine : true,
//Boolean - Stroke a line around each segment in the chart
segmentShowStroke : true,
//String - The colour of the stroke on each segement.
segmentStrokeColor : "#fff",
//Number - The width of the stroke value in pixels
segmentStrokeWidth : 2,
//Number - Amount of animation steps
animationSteps : 100,
//String - Animation easing effect.
animationEasing : "easeOutBounce",
//Boolean - Whether to animate the rotation of the chart
animateRotate : true,
//Boolean - Whether to animate scaling the chart from the centre
animateScale : false,
//String - A legend template
legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<segments.length; i++){%><li><span style=\"background-color:<%=segments[i].fillColor%>\"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>"
}
];
module.exports = PolarPlot;
Your PolarPlot component is not rendered unless you explicitly change the state. Your chartData is not part of the component state. So assigning a new array to that variable does nothing more than that. Move this chartData to the component state. Then, whenever you update this state variable you are going to force the re-render. Something like this:
var PolarPlot = React.createClass ({
componentWillMount: function () {
FilterStore.addChangeListener (this._onChange);
},
getInitialState: function() {
return {chartData: chartData};
},
_onChange: function () {
console.log("time to update")
this.setState({
chartData: [{
value: 300,
color:"#F7464A",
highlight: "#FF5A5E",
label: "Red"
}]
});
},
render: function () {
return (
<PolarAreaChart id="polarChart" data={this.state.chartData} options={chartOptions} redraw/>
);
}
});
If you want to know more about how components rendering reacts to state changes check Reactive state section from the React Tutorial.

Flot Graph inconstencies with axis and tooltips?

I am working on an application where I am trying to plot a similar graph to what is plotted at Open Weather. I am using the FlotJS library to query their API and plot the graphs.
Here is my code. I apologize for the verbosity.
/*
* RUN PAGE GRAPHS
*/
// load all flot plugins
loadScript("js/plugin/flot/jquery.flot.cust.min.js", function(){
loadScript("js/plugin/flot/jquery.flot.resize.min.js", function(){
loadScript("js/plugin/flot/jquery.flot.time.min.js", function(){
loadScript("js/plugin/flot/jquery.flot.tooltip.min.js", generatePageGraphs);
});
});
});
function generatePageGraphs(){
var fetchWeatherUrl = '//api.openweathermap.org/data/2.5/forecast?lat=' + farmLat + '&lon=' + farmLng;
$.ajax({
method: 'get',
dataType: "jsonp",
url: fetchWeatherUrl,
success: function(response){
var temp = [];
var humidity = [];
var rain = [];
$.each(response.list, function(i, item){
if(moment(item.dt, 'X').isSame(moment(), 'day')){
var temperature = ( ( parseFloat(item.main.temp)-273.15 )*1.80 ).toFixed(0);
temp.push([moment(item.dt, 'X').valueOf(), temperature]);
humidity.push([moment(item.dt, 'X').valueOf(), parseFloat(item.main.humidity)]);
if(item.rain != undefined){
rain.push([moment(item.dt, 'X').valueOf(), parseFloat(item.rain["3h"])]);
}
}
});
var mainWeatherGraphData = [{
label: "Temperature",
data: temp,
lines: {
show: true
},
points: {
show: true
}
},
{
label: "Humidity",
data: humidity,
lines: {
show: true
},
points: {
show: true
},
yaxis: 2
},
{
label: "Rain",
data: rain,
bars: {
show: true,
barWidth: 1000*60*30,
align: 'center'
},
yaxis: 3
}];
var mainWeatherGraphOptions = {
xaxis : {
mode : "time",
},
yaxes : [
{
position: 'left'
},
{
position: 'right'
},
{
position: 'right'
}
],
tooltip : true,
tooltipOpts : {
content : "<b>%s</b> on <b>%x</b> will be <b>%y</b>",
dateFormat : "%y-%m-%d",
defaultTheme : false
},
legend : {
show : true,
noColumns : 1, // number of colums in legend table
labelFormatter : null, // fn: string -> string
labelBoxBorderColor : "#000", // border color for the little label boxes
container : null, // container (as jQuery object) to put legend in, null means default on top of graph
position : "ne", // position of default legend container within plot
margin : [0, 5], // distance from grid edge to default legend container within plot
backgroundColor : "#efefef", // null means auto-detect
backgroundOpacity : 0.4 // set to 0 to avoid background
},
grid : {
hoverable : true,
clickable : true
}
};
var mainWeatherGraph = $.plot($("#mainWeatherGraph"), mainWeatherGraphData, mainWeatherGraphOptions);
}
});
// Daily forecast
fetchForecastUrl = 'http://api.openweathermap.org/data/2.5/forecast/daily?lat=' + farmLat + '&lon=' + farmLng;
$.ajax({
method: 'get',
dataType: "jsonp",
url: fetchForecastUrl,
success: function(response){
var temp = [];
var humidity = [];
var rain = [];
$.each(response.list, function(i, item){
var temperature = ( ( parseFloat(item.temp.day)-273.15 )*1.80 ).toFixed(0);
temp.push([moment(item.dt, 'X').valueOf(), temperature]);
humidity.push([moment(item.dt, 'X').valueOf(), parseFloat(item.humidity)]);
if(item.rain != undefined){
rain.push([moment(item.dt, 'X').valueOf(), parseFloat(item.rain)]);
}
});
var dailyForecastGraphData = [{
label: "Temperature",
data: temp,
lines: {
show: true
},
points: {
show: true
},
},
{
label: "Humidity",
data: humidity,
lines: {
show: true
},
points: {
show: true
},
yaxis: 2
},
{
label: "Rain",
data: rain,
bars: {
show: true,
barWidth: 1000*60*60*8,
align: 'center'
},
yaxis: 3
}];
var dailyForecastGraphOptions = {
xaxis : {
mode : "time",
},
yaxes : [
{
position: 'left'
},
{
position: 'right'
},
{
position: 'right'
}
],
tooltip : true,
tooltipOpts : {
content : "<b>%s</b> on <b>%x</b> will be <b>%y</b>",
dateFormat : "%y-%m-%d",
defaultTheme : false
},
legend : {
show : true,
noColumns : 1, // number of colums in legend table
labelFormatter : null, // fn: string -> string
labelBoxBorderColor : "#000", // border color for the little label boxes
container : null, // container (as jQuery object) to put legend in, null means default on top of graph
position : "ne", // position of default legend container within plot
margin : [0, 5], // distance from grid edge to default legend container within plot
backgroundColor : "#efefef", // null means auto-detect
backgroundOpacity : 0.4 // set to 0 to avoid background
},
grid : {
hoverable : true,
clickable : true
}
};
var dailyForecastGraph = $.plot($("#dailyForecastGraph"), dailyForecastGraphData, dailyForecastGraphOptions);
}
});
}
The two graphs are almost identical except the data which they are portraying.
The main (first) graph has the all the y axis plotted correctly. And we can see the axis for all 3 correctly. The daily (second) graph does have the rain y axis, although the options for them are similar.
Other than this, all tooltips are working fine but the temperature tooltips where I can see the placeholder %y and not the real value.
I have been debugging this code for the past 2 hours and I am not a Flot expert and I am not able to figure what is wrong.
Can anybody look at the code and tell me what is going wrong? Thank you in advance.
While you're creating your temperature data arrays, you need to parse the temperature value as a float. Make sure to parse the value as a float for both graphs. You're doing this for your humidity variable, and that is why the tooltip is working for that series.
var temperature = ((parseFloat(item.main.temp) - 273.15) * 1.80).toFixed(0);
temp.push([moment(item.dt, 'X').valueOf(), parseFloat(temperature)]);
JSFiddle updated with all of the same versions used in the theme you're using: JSFiddle

jqplot grid on top of plot

I've been tinkering with a jqplot graph where the grid lines are on top (or in front depending how you look at it) of the graph as opposed to the default background area. I've made several attempts to get it to overlay the grid using the z-index. However, each attempt renders the entire graph non-functional and I receive no error for some unknown reason.
I'm working with a stacked bar chart that actually fills the entire grid, so I don't get to see any of the grid lines, they are all hidden beneath (or behind) the graph.
Here is the code:
<script type="text/javascript" language="javascript">
$.jqplot.config.enablePlugins = true;
var plot;
var data1 = [];
var data2 = [];
var index = 0;
var num = 0;
var delta = 0;
$(document).ready(function(){
for (i=0; i<100; i++) {
num = getRandomNumber();
delta = 100 - num;
index++;
data1.push([ index, num]);
data2.push([ index, delta]);
}
plot = $.jqplot('graph', [data1, data2],{
title: 'my title',
animate: true,
stackSeries: true,
seriesDefaults:{
renderer:$.jqplot.BarRenderer,
rendererOptions: { highlightMouseDown: true },
pointLabels: {show: true}
},
series: [ {label: 'one'}, {label: 'two'} ],
seriesColors:['#ff0000', '#0000ff'],
legend: {
show: true,
location: 'e',
placement: 'outsideGrid'
},
grid: {
gridLineColor: '#333333',
borderWidth: 0
},
axesDefaults: {
pad: 0,
padMin: 0
},
axes: {
xaxis: {
showTicks: false,
pad: 0,
padMin: 0,
rendererOptions: { forceTickAt0: true, forceTickAt100: true }
},
yaxis: {
pad: 0,
padMin: 0,
rendererOptions: { forceTickAt0: true, forceTickAt100: true }
}
}
});
});
getRandomNumber = function(){
return Math.floor(Math.random()* 100);
};
</script>
Anyone run into this requirement and know how to get the grid lines to show up on top of the graph? Thanks
With a little DOM manipulation you can do this BUT you need to make sure to set the grid background color transparent for it to work. After your plot call:
gridCanvas = $($('.jqplot-grid-canvas')[0])
seriesCanvas = $($('.jqplot-series-canvas')[0])
gridCanvas.detach();
seriesCanvas.after(gridCanvas);​
Here's a sample fiddle.

Categories

Resources