Charts using Highcharts with multiple series from JSON - javascript

I have a JSON file of the following format :
[
{ name: 'Pay Off',
data: [ [2850,0],
[3135,0],
[3420,0],
[3705,0],
[3990,0],
[4275,0],
[4560,0],
[4845,0],
[5130,0],
[5415,0],
[5700,0],
[5985,285],
[6270,570],
[6555,855],
[6840,1140],
[7125,1425],
[7410,1710],
[7695,1995],
[7980,2280],
[8265,2565],
[8550,2850]
]
},
{
name: 'Profit',
data: [ [2850,-250],
[3135,-250],
[3420,-250],
[3705,-250],
[3990,-250],
[4275,-250],
[4560,-250],
[4845,-250],
[5130,-250],
[5415,-250],
[5700,-250],
[5985,35],
[6270,320],
[6555,605],
[6840,890],
[7125,1175],
[7410,1460],
[7695,1745],
[7980,2030],
[8265,2315],
[8550,2600]
]
}
]
I have to plot graph for 'Pay Off' and 'Profit' together. Even more plots maybe added to the list as per requirement. The data array has x-axis as 0th element and y-axis as 1st element.
What I am currently doing is the following -
$(document).ready(function() {
var options = {
chart: {
renderTo: 'container',
type: 'line'
},
title: {
text: 'PayOff Curve'
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'middle',
borderWidth: 0
},
series: []
};
$.getJSON('data.json', function(list) {
var newseries = {
name: '',
data: []
};
$.each(list, function(i,item){
newseries.name = item.name;
newseries.data = item.data;
options.series.push(newseries);
});
// Create the chart
var chart = new Highcharts.Chart(options);
});
But I don't any graph at all. I can't figure out the issue with it as I am new to both JavaScript and Python. Please suggest an efficient method to do this.
Thanks for your help..

Your JSON isn't proper one, try to validate it. Properties names shold have double quotes, change from: name: 'Pay Off' to: "name": "Pay Off"

Your JSON is valid for a highcharts series - you don't need to try to transform it at all:
$(document).ready(function() {
var options = {
chart: {
renderTo: 'container',
type: 'line'
},
title: {
text: 'PayOff Curve'
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'middle',
borderWidth: 0
},
series: []
};
$.getJSON('data.json', function(list) {
options.series = list; // <- just assign the data to the series property.
var chart = new Highcharts.Chart(options);
});
});
If that still doesn't work, open the console to see whether there's a JavaScript error.
Here's a fiddle.

Related

Highcharts - Display the noData overlay and the x-axis labels

I can get the noData overlay working when there are no series data values, and I can get the x-axis displaying along with the noData label by setting a xAxis.max value, but I can't get the x-axis labels displaying.
Any ideas?
Ideally I would be able to do this without any fake series data (as without data I don't have any series names to provide). This is used in a column chart of well defined x values (like in the js fiddle below, with known fruits, where only each series counts are dynamic)
Closest I've been able to get is this jsfiddle:
http://jsfiddle.net/eLdn6Lfc/
$(function () {
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container1',
type: 'column'
},
xAxis: {
categories: ['Mulligatawny', 'Crab bisque', 'Lima bean', 'Wild mushroom'],
max:3
},
series: [{
data: []
}],
lang: {
noData: "No Soup For You!"
},
});
});
You also need to set min limit to x-axis if there is no data.
Working solution here
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'column'
},
xAxis: {
categories: ['Mulligatawny', 'Crab bisque', 'Lima bean', 'Wild mushroom'],
min: 0,
max: 3
},
series: [{
showInLegend: false,
data: []
}],
lang: {
noData: "No Soup For You!"
},
});

Highcharts Map not rendering no errors

I am attempting to take the example produced by Highcharts here http://www.highcharts.com/maps/demo/color-axis and substitute the data loaded by the $.getJson with a local JSON file called 'testdata1.json'.
The code I've modified below produces no errors yet the map does not render. I think it's because the testdata1.json is loaded late, after the javascript is executed. If so, is there a better way I should be doing this -- perhaps waiting for the data to load before executing the JS file? I attempted to do this by placing a
$(document).ready(
in front of the function but it didn't work. Any thoughts are greatly appreciated, I think it's something relatively minor that is just escaping me.
Thank you.
$(function () {
// Map options
var options = {
chart : {
renderTo: '#map',
borderWidth : 1
},
title : {
text : 'US population density (/km²)'
},
legend: {
layout: 'horizontal',
borderWidth: 0,
backgroundColor: 'rgba(255,255,255,0.85)',
floating: true,
verticalAlign: 'top',
y: 25
},
mapNavigation: {
enabled: true
},
colorAxis: {
min: 1,
type: 'logarithmic',
minColor: '#EEEEFF',
maxColor: '#000022',
stops: [
[0, '#EFEFFF'],
[0.67, '#4444FF'],
[1, '#000022']
]
},
series : [{
animation: {
duration: 1000
},
mapData: Highcharts.maps['countries/us/us-all'],
joinBy: ['postal-code', 'code'],
dataLabels: {
enabled: true,
color: 'white',
format: '{point.code}'
},
name: 'Population density',
tooltip: {
pointFormat: '{point.code}: {point.value}/km²'
}
}]
};
$.getJSON('static/data/testdata1.json', function (data) {
// Make codes uppercase to match the map data
$.each(data, function () {
this.code = this.code.toUpperCase();
});
options.series.data= data;
var chart = new Highcharts.Chart(options)
});
});
You have three problems. Here's a fiddle based on their sample that uses your approach, but still uses their data, and works: http://jsfiddle.net/g29k24vw/1/
Here are the important parts:
chart : {
renderTo: 'container',
borderWidth : 1,
type: 'map'
},
And:
$.getJSON('http://www.highcharts.com/samples/data/jsonp.php?filename=us-population-density.json&callback=?', function (data) {
// Make codes uppercase to match the map data
$.each(data, function () {
this.code = this.code.toUpperCase();
});
options.series[0].data= data;
var chart = new Highcharts.Chart(options);
});
Note the differences here:
You need to specify the chart type in options if you're going to instantiate the chart object directly instead of using the jQuery helper.
renderTo doesn't want a hash in front of the element name.
options.series[0].data, not options.series.data...series is actually an array of objects.

Data Not Showing in Highcharts

I'm attempting to combine a couple of different chart demos from Highcharts.
My examples are: Data classes and popup and Small US with data labels
I want the map from the first with the popup feature of the second. I need to connect the map to my own google spreadsheet but for now I'm just trying to get the data from the first example to work.
This is what I have so far but can't seem to get any data in the map. I thought I had a joinBy problem, and I may still, but when I set joinBy to null I thought "the map items are joined by their position in the array", yet nothing happened.
https://jsfiddle.net/9eq6mydv/
$(function () {
// Load the data from a Google Spreadsheet
// https://docs.google.com/a/highsoft.com/spreadsheet/pub?hl=en_GB&hl=en_GB&key=0AoIaUO7wH1HwdFJHaFI4eUJDYlVna3k5TlpuXzZubHc&output=html
Highcharts.data({
googleSpreadsheetKey: '0AoIaUO7wH1HwdDFXSlpjN2J4aGg5MkVHWVhsYmtyVWc',
googleSpreadsheetWorksheet: 1,
// custom handler for columns
parsed: function (columns) {
// Make the columns easier to read
var keys = columns[0],
names = columns[1],
percent = columns[10],
// Initiate the chart
options = {
chart : {
renderTo: 'container',
type: 'map',
borderWidth : 1
},
title : {
text : 'US presidential election 2008 result'
},
subtitle: {
text: 'Source: <a href="http://en.wikipedia.org/wiki/United_States_presidential_election,' +
'_2008#Election_results">Wikipedia</a>'
},
mapNavigation: {
enabled: true,
enableButtons: false
},
legend: {
align: 'right',
verticalAlign: 'top',
x: -100,
y: 70,
floating: true,
layout: 'vertical',
valueDecimals: 0,
backgroundColor: (Highcharts.theme && Highcharts.theme.legendBackgroundColor) || 'rgba(255, 255, 255, 0.85)'
},
colorAxis: {
dataClasses: [{
from: -100,
to: 0,
color: '#C40401',
name: 'McCain'
}, {
from: 0,
to: 100,
color: '#0200D0',
name: 'Obama'
}]
},
series : [{
data : data,
dataLabels: {
enabled: true,
color: '#FFFFFF',
format: '{point.code}',
style: {
textTransform: 'uppercase'
}
},
mapData: Highcharts.geojson(Highcharts.maps['countries/us/custom/us-small']),
joinBy: keys,
name: 'Democrats margin',
point: {
events: {
click: pointClick
}
},
tooltip: {
ySuffix: ' %'
},
cursor: 'pointer'
}, {
type: 'mapline',
data: Highcharts.geojson(Highcharts.maps['countries/us/custom/us-small'], 'mapline'),
color: 'silver'
}]
};
/**
* Event handler for clicking points. Use jQuery UI to pop up
* a pie chart showing the details for each state.
*/
function pointClick() {
var row = this.options.row,
$div = $('<div></div>')
.dialog({
title: this.name,
width: 400,
height: 300
});
window.chart = new Highcharts.Chart({
chart: {
renderTo: $div[0],
type: 'pie',
width: 370,
height: 240
},
title: {
text: null
},
series: [{
name: 'Votes',
data: [{
name: 'Obama',
color: '#0200D0',
y: parseInt(columns[3][row], 10)
}, {
name: 'McCain',
color: '#C40401',
y: parseInt(columns[4][row], 10)
}],
dataLabels: {
format: '<b>{point.name}</b> {point.percentage:.1f}%'
}
}]
});
}
// Read the columns into the data array
var data = [];
$.each(keys, function (i, key) {
data.push({
key: key,//.toUpperCase(),
value: parseFloat(percent[i]),
name: names,
row: i
});
});
// Initiate the chart
window.chart = new Highcharts.Map(options);
},
error: function () {
$('#container').html('<div class="loading">' +
'<i class="icon-frown icon-large"></i> ' +
'Error loading data from Google Spreadsheets' +
'</div>');
}
});
});
UPDATE:
I wanted to share with everyone my final solution. Although Ondkloss did a magnificent job answering my question the popup feature still didn't work and this is because I forgot to include the jQuery for the .dialog call. Once I included that I had an empty popup with a highchart error 17, this is because the highmaps.js code doesn't include the pie chart class. So I had to add the highcharts.js code and include map.js module afterward. You can see my final jsfiddle here.
Thanks again to Ondkloss for the excellent answer!
The problem here mostly comes down to the use of joinBy. Also to correct it there are some required changes to your data and mapData.
Currently your joinBy is an array of strings, like ["al", "ak", ...]. This is quite simply not an accepted format of the joinBy option. You can read up on the details in the API documentation, but the simplest approach is to have a attribute in common in data and mapData and then supply a string in joinBy which then joins those two arrays by that attribute. For example:
series : [{
data : data,
mapData: mapData,
joinBy: "hc-key",
]
Here the "hc-key" attribute must exist in both data and mapData.
Here's how I'd create the data variable in your code:
var data = [];
$.each(keys, function (i, key) {
if(i != 0)
data.push({
"hc-key": "us-"+key,
code: key.toUpperCase(),
value: parseFloat(percent[i]),
name: names[i],
row: i
});
});
This skips the first key, which is just "Key" (the title of the column). Here we make the "hc-key" fit the format of the "hc-key" in our map data. An example would be "us-al". The rest is just metadata that will be joined in. Note that you were referencing your data in the options prior to filling it with data, so this has to be moved prior to this.
This is how I'd create the mapData variable in your code:
var mapData = Highcharts.geojson(Highcharts.maps['countries/us/custom/us-small']);
// Process mapdata
$.each(mapData, function () {
var path = this.path,
copy = { path: path };
// This point has a square legend to the right
if (path[1] === 9727) {
// Identify the box
Highcharts.seriesTypes.map.prototype.getBox.call(0, [copy]);
// Place the center of the data label in the center of the point legend box
this.middleX = ((path[1] + path[4]) / 2 - copy._minX) / (copy._maxX - copy._minX);
this.middleY = ((path[2] + path[7]) / 2 - copy._minY) / (copy._maxY - copy._minY);
}
// Tag it for joining
this.ucName = this.name.toUpperCase();
});
The first part is your "standard map data". The rest is to correctly center the labels for the popout states, and gotten directly from the example.
And voila, see this JSFiddle demonstration to witness your map in action.
I suggest doing some console.log-ing to see how data and mapData have the hc-key in common and that leads to the joining of the data in the series.

Javascript+Highcharts: Substituting series.data for my own

I've been doing this script for a volunteering university-site job.
Please ignore all parameters apart from wattages and schools. Those are SQL result sets that have been converted to arrays using json_encode(). Result sets have Strings as values, I believe, so both wattages and schools should be arrays of strings.
What I want to do is input my own data for the pie graph, in this case mySeries, which I build/fill up at the start and put as data later.
function createPieChartGradient(data,title,xlabel,ylabel,type,step,div_id,wattages,schools){
var float_watt = new Array();
for(var index = 0; index < wattages.length; index++)
{
float_watt[index] = parseFloat(wattages[index]).toFixed(2);
}
var mySeries = []; //Hopefully this creates a [String, number] array that can be used as Data.
for (var i = 0; i < float_watt.length; i++) {
mySeries.push([schools[i], float_watt[i]]);
}
var options = {
chart: {
renderTo: 'graph',
zoomType: 'x',
defaultSeriesType: type
},
title: {
text: 'Consumption Percentage of IHU Schools, Last 7 days'
},
tooltip: {
//pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>'
},
xAxis: {
categories: [],
tickPixelInterval: 150,
// maxZoom: 20 * 1000,
title: {
style: {
fontSize: '14px'
},
text: xlabel
},
labels: {
rotation: -45,
step: step,
align: 'right'//,
// step: temp
}
},
yAxis: {
title: {
style: {
fontSize: '14px'
},
text: ylabel
},
labels: {
align: 'right',
formatter: function() {
return parseFloat(this.value).toFixed(2);
}
},
min: 0
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'center',
floating: true,
shadow: true
},
series: [{
type: 'pie',
name: 'Consumption Percentage',
data: mySeries //Problematic line.
}] //Faculty with the smallest wattage -> Green.
}; //end of var options{} //Next: -> Yellow.
//Last -> Red.
//Draw the chart.
var chart = new Highcharts.Chart(options); //TODO: Change colours.
document.write("FINISHED");
}
The thing is, the above won't work. Since I'm not using an environment (writing in notepad++ and testing on my apache web server, via the results) I have manually aliminated the problematic line to be data: mySeries.
Any idea why that is? Aren't they the same type of array, [String, number]?
Additionally, are there any environments that will help me debug javascript programs? I'm really at my wit's end with this situation and I'd very much prefer to have an IDE tell me what's wrong, or at least point me at the right direction.
You see where you are calling "toFixed"? Let's run a small experiment:
var wattages = [2.0, 3.0];
var float_watt = new Array();
for(var index = 0; index < wattages.length; index++)
{
float_watt[index] = parseFloat(wattages[index]).toFixed(2);
}
console.log(JSON.stringify(float_watt));
The output is not what you expect:
["2.00", "3.00"]
See how it got converted to a string? If you delete the "toFixed" and let your formatter do its job, things will go just fine.
EDIT
Here's how you fix your formatter:
plotOptions: {
pie: {
dataLabels: {
formatter: function() {
return parseFloat(this.y).toFixed(2);
}
}
}
},
The yLabels formatter is doing nothing for the pie.

Highcharts JSON, chart not displaying

I have some data I wish to display on a chart but it just shows the title and no points get drawn. The JSON data I receive is correct as per my knowledge, I think it's somewhere in the chart function but I can't really point it out.
This is what I have so far:
data.php (the output):
{"name":"Temperature","data":[34,28,29,28,34,28,32,27,24,30,25,32,34,28,34,33,24,33,30,27,24,27,26,29]}
The important bits of the html:
<script>
$(function () {
var chart;
$(document).ready(function() {
$.getJSON("data.php", function(json) {
chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'line',
marginRight: 130,
marginBottom: 25
},
title: {
text: 'Temperature vs. Time',
x: -20 //center
},
xAxis: {
categories: ['12AM', '1AM', '2AM', '3AM', '4AM', '5AM', '6AM', '7AM', '8AM', '9AM', '10AM', '11AM','12PM', '1PM', '2PM', '3PM', '4PM', '5PM', '6PM', '7PM', '8PM', '9PM', '10PM', '11PM']
},
yAxis: {
title: {
text: 'Temperature'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
series: json
});
});
});
});
</script>
It's supposed to show temperature per hour but unfortunately nothing comes up. Any idea what could be wrong?
series should be an array. So you need to just change:
series: json
To:
series: [json]
Working example: http://codepen.io/anon/pen/Kfgsd
Documentation: http://www.highcharts.com/docs/chart-concepts/series
your problem i think that you haven't specified where your chart should be inserted to, afaik you either should specify the renderTo option for the class constructor options or use the $('#container').haighcharts({...}) jquery helper

Categories