I am trying to reload the data for a Highcharts chart via JSON based on a button click elsewhere in the page. Initially I would like to display a default set of data (spending by category) but then load new data based on user input (spending by month, for example). The easiest way I can think of to output the JSON from the server is by passing a GET request to the PHP page, for example $.get('/dough/includes/live-chart.php?mode=month', retrieving this value from the button's ID attribute.
Here is what I have so far to retrieve the default data (spending by category). Need to find how to load completely different data into the pie chart, based on user input, on demand:
$(document).ready(function() {
//This is an example of how I would retrieve the value for the button
$(".clickMe").click(function() {
var clickID = $(this).attr("id");
});
var options = {
chart: {
renderTo: 'graph-container',
margin: [10, 175, 40, 40]
},
title: {
text: 'Spending by Category'
},
plotArea: {
shadow: null,
borderWidth: null,
backgroundColor: null
},
tooltip: {
formatter: function() {
return '<b>'+ this.point.name +'</b>: $'+ this.y;
}
},
credits: {
enabled: false
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
dataLabels: {
enabled: true,
formatter: function() {
if (this.y > 5) return '$' + this.y;
},
color: 'white',
style: {
font: '13px Trebuchet MS, Verdana, sans-serif'
}
}
}
},
legend: {
layout: 'vertical',
style: {
left: 'auto',
bottom: 'auto',
right: '50px',
top: '100px'
}
},
series: [{
type: 'pie',
name: 'Spending',
data: []
}]
};
$.get('/dough/includes/live-chart.php', function(data) {
var lines = data.split('\n');
$.each(lines, function(lineNo, line) {
var items = line.split(',');
var data = {};
$.each(items, function(itemNo, item) {
if (itemNo === 0) {
data.name = item;
} else {
data.y = parseFloat(item);
}
});
options.series[0].data.push(data);
});
// Create the chart
var chart = new Highcharts.Chart(options);
});
});
Any help would be greatly appreciated
EDIT
Here is the updated Javascript thanks to Robodude. John, you have me on the right track here - thanks! I'm now getting stuck with how to replace the data on the chart from the AJAX request. I must admit that the code following the $.get() is most likely from sample code, I do not fully understand what is going on when it is run - perhaps there is a better way to format the data?
I was able to make some progress in that the chart now loads new data but it is added on top of what is already there. I suspect that the culprit is this line:
options.series[0].data.push(data);
I tried options.series[0].setData(data); but nothing happens. On the bright side, the AJAX request works flawlessly based on the value of the select menu and there are no Javascript errors. Here is the code in question, sans chart options:
$.get('/dough/includes/live-chart.php?mode=cat', function(data) {
var lines = data.split('\n');
$.each(lines, function(lineNo, line) {
var items = line.split(',');
var data = {};
$.each(items, function(itemNo, item) {
if (itemNo === 0) {
data.name = item;
} else {
data.y = parseFloat(item);
}
});
options.series[0].data.push(data);
});
// Create the chart
var chart = new Highcharts.Chart(options);
});
$("#loadChart").click(function() {
var loadChartData = $("#chartCat").val();
$.get('/dough/includes/live-chart.php?mode=' + loadChartData, function(data) {
var lines = data.split('\n');
$.each(lines, function(lineNo, line) {
var items = line.split(',');
var data = {};
$.each(items, function(itemNo, item) {
if (itemNo === 0) {
data.name = item;
} else {
data.y = parseFloat(item);
}
});
options.series[0].data.push(data);
});
// Create the chart
var chart = new Highcharts.Chart(options);
});
});
});
EDIT 2 This is the format that the chart is pulling from - very simple, category name and value with \n after each.
Coffee, 4.08
Dining Out, 5.05
Dining: ODU, 5.97
Dining: Work, 38.41
Entertainment, 4.14
Gas, 79.65
Groceries, 228.23
Household, 11.21
Misc, 12.20
Snacks, 20.27
This question is related to
jquery
json
highcharts
You need to clear the old array out before you push the new data in. There are many ways to accomplish this but I used this one:
options.series[0].data.length = 0;
So your code should look like this:
options.series[0].data.length = 0;
$.each(lines, function(lineNo, line) {
var items = line.split(',');
var data = {};
$.each(items, function(itemNo, item) {
if (itemNo === 0) {
data.name = item;
} else {
data.y = parseFloat(item);
}
});
options.series[0].data.push(data);
});
Now when the button is clicked the old data is purged and only the new data should show up. Hope that helps.
Actually maybe you should choose the function update
is better.
Here's the document of function update
http://api.highcharts.com/highcharts#Series.update
You can just type code like below:
chart.series[0].update({data: [1,2,3,4,5]})
These code will merge the origin option, and update the changed data.
You can always load a json data
here i defined Chart as namespace
$.getJSON('data.json', function(data){
Chart.options.series[0].data = data[0].data;
Chart.options.series[1].data = data[1].data;
Chart.options.series[2].data = data[2].data;
var chart = new Highcharts.Chart(Chart.options);
});
Correct answer is:
$.each(lines, function(lineNo, line) {
var items = line.split(',');
var data = {};
$.each(items, function(itemNo, item) {
if (itemNo === 0) {
data.name = item;
} else {
data.y = parseFloat(item);
}
});
options.series[0].data.push(data);
data = {};
});
You need to flush the 'data' array.
data = {};
data = [150,300]; // data from ajax or any other way
chart.series[0].setData(data, true);
The setData
will call redraw method.
Reference: http://api.highcharts.com/highcharts/Series.setData
If you are using push to push the data to the option.series dynamically .. just use
options.series = [];
to clear it.
options.series = [];
$("#change").click(function(){
}
The other answers didn't work for me. I found the answer in their documentation:
http://api.highcharts.com/highcharts#Series
Using this method (see JSFiddle example):
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container'
},
series: [{
data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]
}]
});
// the button action
$('#button').click(function() {
chart.series[0].setData([129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4, 29.9, 71.5, 106.4] );
});
Source: Stackoverflow.com