Stackedbars on jqPlot with a dynamic json - javascript

I've been trying to accomplish a chart on jqPlot using the stacked bars (imho, there would be a better way to graphically display the data above, but thats not up to me.)
so heres the dummy data:
var data = {
"Network 1": {
"Avg. Speed": 10000,
"D/S": 10000,
"U/S": 10000
},
"Network 2": {
"Avg. Speed": 15000,
"D/S": 15000,
"U/S": 15000
},
"Network 3": {
"Avg. Speed": 20000,
"D/S": 20000,
"U/S": 20000
}
};
Network's would be the X axis and the Avg. Speed/ DS and US would be the facts so each network would have, in this case 3 stacked bars with their data.
I've been passing jqplot data like this just to check the results but, the graph is blank:
plot2 = $.jqplot('divGraphNetwork', [], {
animate: !$.jqplot.use_excanvas,
stackSeries: true,
dataRenderer: data,
seriesDefaults: {
renderer: $.jqplot.BarRenderer,
rendererOptions: {
barPadding: 2,
barMargin: 0,
barDirection: 'vertical',
barWidth: 20
},
pointLabels: {
//location: 'se',
ypadding: 0
}
},
title: {
text: 'Network Information', // title for the plot,
show: true,
},
legend: {
show: false,
location: 'e',
placement: 'outside'
},
axes: {
xaxis: {
renderer: $.jqplot.CategoryAxisRenderer
},
yaxis: {
min:0,
autoscale: true
}
}
});

dataRenderer should be a function not a JSON object. This function should take the JSON object and convert it to a 2D array.
The 2D array should be in the following format:
[[Network1 AV/Speed, Network2 AV/Speed, Network3 AV/Speed],
[Network1 D/S, Network2 D/S, Network3 D/S],
[Network1 U/S, Network2 U/S, Network3 U/S]]
I've created a Fiddle here to demonstrate. I've added a dataRenderer() function as follows:
function dataRenderer() {
var result = [];
var avgSpeed = [];
var ds = [];
var us = [];
// Loop over each network
for (var network in data) {
// Add each of the stats for the network into the corresponding array
avgSpeed.push(data[network]["Avg. Speed"]);
ds.push(data[network]["D/S"]);
us.push(data[network]["U/S"]);
}
// Add the av speed, DS and US arrays to the result array creating a 2D array
result.push(avgSpeed);
result.push(ds);
result.push(us)
return result;
}
I've then modified the dataRenderer option to point to the function instead of the JSON object data:
var plot2 = $.jqplot('divGraphNetwork', [], {
...
dataRenderer: dataRenderer,
....
});

Related

Highcharts map appending unwanted data

I have a small problem with my Highcharts maps. I managed to get it plotting the data I want and even included a selector so the user can adjust which data series is shown. However, it appears that after rendering one particular series once, the Map is appending data objects to each series for those U.S. territories I don't have data for. My biggest series has 53 data objects (US States plus DC, Puerto Rico, Virgin Islands) but after being rendered once the series shows up with 62 structures including those for which I didn't have data (Saint John, Saipan, etc.). This is causing problems with the snippet of code I use to change the state code to the hc-key format needed by this map. While I could just add some extra checks to that function, i would like to understand why Highcharts is adding data to my data structures. Any help would be most appreciated. My Javascript code is below:
<script type="text/javascript">
var states ={resStates: [{code: "AK",value:3},{code: "AL",value:49},{code: "AR",value:9},{code: "AZ",value:28},{code: "CA",value:170},{code: "CO",value:26},{code: "CT",value:12},{code: "DC",value:10},{code: "DE",value:5},{code: "FL",value:126},{code: "GA",value:51},{code: "HI",value:7},{code: "IA",value:5},{code: "ID",value:13},{code: "IL",value:31},{code: "IN",value:28},{code: "KS",value:15},{code: "KY",value:12},{code: "LA",value:17},{code: "MA",value:54},{code: "MD",value:124},{code: "ME",value:13},{code: "MI",value:60},{code: "MN",value:8},{code: "MO",value:19},{code: "MS",value:16},{code: "MT",value:6},{code: "NC",value:43},{code: "ND",value:3},{code: "NE",value:10},{code: "NH",value:14},{code: "NJ",value:72},{code: "NM",value:35},{code: "NV",value:7},{code: "NY",value:70},{code: "OH",value:84},{code: "OK",value:23},{code: "OR",value:11},{code: "PA",value:101},{code: "PR",value:2},{code: "RI",value:20},{code: "SC",value:26},{code: "SD",value:5},{code: "TN",value:19},{code: "TX",value:91},{code: "UT",value:67},{code: "VA",value:112},{code: "VI",value:1},{code: "VT",value:1},{code: "WA",value:29},{code: "WI",value:13},{code: "WV",value:2},{code: "WY",value:4}],
acadStates: [{code: "AK",value:1},{code: "AL",value:47},{code: "AR",value:12},{code: "AZ",value:31},{code: "CA",value:163},{code: "CO",value:34},{code: "CT",value:9},{code: "DC",value:18},{code: "DE",value:7},{code: "FL",value:121},{code: "GA",value:80},{code: "HI",value:6},{code: "IA",value:9},{code: "ID",value:9},{code: "IL",value:29},{code: "IN",value:55},{code: "KS",value:16},{code: "KY",value:8},{code: "LA",value:14},{code: "MA",value:65},{code: "MD",value:81},{code: "ME",value:8},{code: "MI",value:66},{code: "MN",value:7},{code: "MO",value:20},{code: "MS",value:13},{code: "MT",value:4},{code: "NB",value:1},{code: "NC",value:53},{code: "ND",value:4},{code: "NE",value:8},{code: "NH",value:13},{code: "NJ",value:32},{code: "NM",value:32},{code: "NV",value:4},{code: "NY",value:93},{code: "OH",value:83},{code: "OK",value:25},{code: "OR",value:7},{code: "PA",value:123},{code: "PR",value:2},{code: "RI",value:15},{code: "SC",value:17},{code: "SD",value:4},{code: "TN",value:9},{code: "TX",value:103},{code: "UT",value:62},{code: "VA",value:114},{code: "VT",value:2},{code: "WA",value:27},{code: "WI",value:19},{code: "WV",value:4},{code: "WY",value:4}],
empStates: [{code: "AK",value:2},{code: "AL",value:71},{code: "AR",value:4},{code: "AZ",value:12},{code: "CA",value:235},{code: "CO",value:1},{code: "DC",value:36},{code: "FL",value:104},{code: "GA",value:70},{code: "HI",value:5},{code: "IL",value:17},{code: "IN",value:18},{code: "KS",value:14},{code: "LA",value:5},{code: "MA",value:61},{code: "MD",value:244},{code: "MI",value:39},{code: "MN",value:3},{code: "MO",value:4},{code: "MS",value:64},{code: "NC",value:22},{code: "NE",value:2},{code: "NH",value:20},{code: "NJ",value:62},{code: "NM",value:95},{code: "NY",value:22},{code: "OH",value:133},{code: "OK",value:53},{code: "OR",value:7},{code: "PA",value:38},{code: "RI",value:37},{code: "SC",value:26},{code: "TN",value:9},{code: "TX",value:22},{code: "UT",value:75},{code: "VA",value:126},{code: "WA",value:22},{code: "WV",value:2}]};
$(init)
function init() {
drawMap();
}
function drawMap() {
var map_select = $('#smartStates').val();
var map_text = $('#smartStates option:selected').text();
var mydata = states[map_select];
var mycolors = {resStates: {
min: 1,
type: 'linear',
minColor: '#EEEEFF',
maxColor: '#000022',
stops: [
[0, '#EFEFFF'],
[0.67, '#4444FF'],
[1, '#000022']
]
}, acadStates: {
min: 1,
type: 'linear',
minColor: '#FFEEEE',
maxColor: '#220000',
stops: [
[0, '#FFFFEE'],
[0.67, '#FF4444'],
[1, '#220000']
]
}, empStates: {
min: 1,
type: 'linear',
minColor: '#EEFFEE',
maxColor: '#002200',
stops: [
[0, '#EEFFEE'],
[0.67, '#44FF44'],
[1, '#002200']
]
}
}
// Adjusting codes to fit with the us-all-territories map
$.each(mydata, function(){ //looping through each instance of mydata
if (this.code == "PR") {
this.code = "pr-3614";
} else if (this.code == "undefined"){
//not sure what to do here
}
else if (this.code.length==2) {
this.code = "us-" + this.code.toLowerCase();
}
});
// Instanciate the map
$('#container').highcharts('Map', {
chart : {
borderWidth : 1
},
title : {
text : 'SMART Participant Counts by ' + map_text
},
legend: {
layout: 'horizontal',
borderWidth: 0,
backgroundColor: 'rgba(255,255,255,0.85)',
floating: true,
verticalAlign: 'top',
y: 25
},
mapNavigation: {
enabled: true
},
colorAxis: mycolors[map_select],
series : [{
animation: {
duration: 1000
},
data : mydata,
mapData: Highcharts.maps['countries/us/custom/us-all-territories'],
joinBy: ['hc-key', 'code'],
dataLabels: {
enabled: true,
color: '#FFFFFF',
format: '{point.name}'
},
name: 'SMART Participants',
tooltip: {
pointFormat: '{point.name}: {point.value} participants'
}
}]
});
}
</script>
This is because in your mapData property you have this:
mapData: Highcharts.maps['countries/us/custom/us-all-territories'],
us-all-territories, but as you stated, you don't have the data for all of the territories.
The solution is to use a different custom map from Highcharts, unfortunately it doesn't look like they have one with only the US territories you are looking for.
Update: as the comment by Kacper has mentioned: If you set allAreas in series to false, then empty map zones will not be displayed. Example: http://jsfiddle.net/oen00hec/

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.

Parsing CSV data into JS Objects to use in chart. Uncaught ReferenceError: data is not defined(jsfiddle included)

Here's what I'm trying to do:
Use papa parse to parse a CSV file.
Create two JS Objects(ohlc and volume) with that parsed data.
Then that data is used to create a highstocks chart.
Parsing with papa parse example:
function doStuff(data) {
//do stuff here
console.log(data);
}
function parseData(url, callBack) {
Papa.parse(url, {
download: true,
dynamicTyping: true,
complete: function(results) {
callBack(results.data);
}
});
}
parseData("https://www.quandl.com/api/v3/datasets/WIKI/AAPL.csv", doStuff);
A working Highchart example: jsfiddle
Me trying to combine the top two examples: jsfiddle
$(function () {
var ohlc = [],
volume = [],
dataLength = data.length,
// set the allowed units for data grouping
groupingUnits = [[
'week', // unit name
[1] // allowed multiples
], [
'month',
[1, 2, 3, 4, 6]
]],
i = 1;
function parseData(url, callBack) {
Papa.parse(url, {
download: true,
dynamicTyping: true,
complete: function(results) {
callBack(results.data);
}
});
}
function setObjects(data) {
console.log(data[i][0]);
for (i; i < dataLength; i += 1) {
ohlc.push([
data[i][0], // the date
data[i][1], // open
data[i][2], // high
data[i][3], // low
data[i][4] // close
]);
volume.push([
data[i][0], // the date
data[i][5] // the volume
]);
}
}
parseData("https://www.quandl.com/api/v3/datasets/WIKI/AAPL.csv", setObjects);
// create the chart
$('#container').highcharts('StockChart', {
rangeSelector: {
selected: 1
},
title: {
text: 'AAPL Historical'
},
yAxis: [{
labels: {
align: 'right',
x: -3
},
title: {
text: 'OHLC'
},
height: '60%',
lineWidth: 2
}, {
labels: {
align: 'right',
x: -3
},
title: {
text: 'Volume'
},
top: '65%',
height: '35%',
offset: 0,
lineWidth: 2
}],
series: [{
type: 'candlestick',
name: 'AAPL',
data: ohlc,
dataGrouping: {
units: groupingUnits
}
}, {
type: 'column',
name: 'Volume',
data: volume,
yAxis: 1,
dataGrouping: {
units: groupingUnits
}
}]
});
});
Can anyone help me out with what I am doing wrong? I know two things that haven't been done. The data needs to be reverse so that it is in ascending order by date. And the date needs to be converted to milliseconds. However it would help me to get the current data at least inserting to the objects first and then go from there.
This bit
var i = 1;
dataLength = data.length;
Should be in the first lines of the setObjects function, where data is present and the value dataLength is actually used.

Why does my addSeries (in highcharts) only display names of the series but not the actual pie chart itself

When trying to add Series to a Highcharts piechart only the names of the series displays but not the graph itself.
If I input the series manually the chart displays correctly but when it's done via .each loop it only shows the added series names.
Here is my code:
function my_pie(){
// Build the chart
$('#pie_chart').highcharts({
chart: {
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false,
marginBottom: 0,
spacingTop: 0,
marginTop:0,
marginLeft:50,
marginRight:50
},
credits:{
enabled:false
},
title: {
text: ''
},
tooltip: {
pointFormat: '{point.percentage:.1f}%</b>'
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
dataLabels: {
enabled: false
},
showInLegend: false
}
},
series: [{
type: 'pie',
name: 'Innehav',
data: [ ]
}]
});
var chart = $('#pie_chart').highcharts();
$.each(data_array, function( index, value ) {
chart.addSeries({
name: index,
y: parseInt(value)
}, false);
});
chart.redraw();
};
Here is the output from console.log(data_array)
Object {Ja: "272", Nej: "30", Vet ej: "1"}
Update:
Here is how the data_array is generated (I added num_check to make values integers)
var data_array = <?php echo json_encode($data_pie, JSON_NUMERIC_CHECK ) ?>;
And now the console.log(data_array) looks like this:
Object {Ja: 272, Nej: 30, Vet ej: 1}
Pie chart is just one series, not multiple ones like other types. You should be adding values instead:
$.each(data_array, function( index, value ) {
chart.series[0].addPoint({
name: index,
y: parseInt(value)
}, false);
});
chart.redraw();
Or better, use setData:
var data = []
$.each(data_array, function( index, value ) {
data.push( [index, parseInt(value) ]);
});
chart.series[0].setData(data);

jqPlot bar graph with multiseries showing empty data series

I´m building a dynamic 6 series bar graph with jqPlot. In my implementation, the user will choose which data will go into each serie and the system will load data according to his choice. The function `GetDataFromSeries() loads the series data given a serie number and the available ticks (as categories - it gets all ticks from all series and builds an unique category array).
If the user choose to load all series, everything runs fine. The problem is if the user decide not to load one series (that´s possible). In that case, I will not load that data in GetDataFromSeries() and jqPlot gives me error.
I´m trying several ways to do it, but I´m being successfull. In the code the way it is, I´m getting Uncaught Error: No data specified if the user decides not to load one of the series. I have tried to put dummy data (null or zero) in case one of the series are empty, but doing so the bars are moved and shrinked as If I have more bars to be shown.
Don´t know how to solve that. Appreciate very much any kind of help.
Rds.
[CODE]
function GeneratePlot() {
var tickAxis = new Array();
var data0 = new Array();
var data1 = new Array();
var data2 = new Array();
var data3 = new Array();
var data4 = new Array();
var data5 = new Array();
///
/// Convert series into meaningfull data
///
tickAxis = GetTickAxisFromSeries();
data0 = GetDataFromSeries(0, tickAxis);
data1 = GetDataFromSeries(1, tickAxis);
data2 = GetDataFromSeries(2, tickAxis);
data3 = GetDataFromSeries(3, tickAxis);
data4 = GetDataFromSeries(4, tickAxis);
data5 = GetDataFromSeries(5, tickAxis);
var options = {
title: 'Evolution Plot',
height: 500,
series: [
{ show: (data0.length != 0) },
{ show: (data1.length != 0) },
{ show: (data2.length != 0) },
{ show: (data3.length != 0) },
{ show: (data4.length != 0) },
{ show: (data5.length != 0) }
],
axes: {
xaxis: {
renderer: $.jqplot.CategoryAxisRenderer,
ticks: tickAxis,
tickRenderer: $.jqplot.CanvasAxisTickRenderer,
tickOptions: {
angle: -90,
fontSize: '8pt',
formatter: $.jqplot.DateTickFormatter
}
},
yaxis: {
pad: 1.05,
tickOptions: {
formatString: '%d',
fontSize: '8pt'
}
}
},
seriesDefaults: {
renderer: $.jqplot.BarRenderer,
rendererOptions: {
fillToZero: true
}
},
highlighter: {
show: true,
sizeAdjust: 7.5
},
cirsor: {
show: false
}
}
var plot = $.jqplot('chart', [data0, data1, data2, data3, data4, data5], options).replot();
}
I think this would solve your problem:
function GeneratePlot() {
var tickAxis = new Array();
var data = new Array();
var tempData = [];
///
/// Convert series into meaningfull data
///
tickAxis = GetTickAxisFromSeries();
for(var i = 0; i < 6; i++){
tempData = GetDataFromSeries(i, tickAxis);
if(tempData.length > 0){
data.push(tempData);
}
}
var options = {
title: 'Evolution Plot',
height: 500,
axes: {
xaxis: {
renderer: $.jqplot.CategoryAxisRenderer,
ticks: tickAxis,
tickRenderer: $.jqplot.CanvasAxisTickRenderer,
tickOptions: {
angle: -90,
fontSize: '8pt',
formatter: $.jqplot.DateTickFormatter
}
},
yaxis: {
pad: 1.05,
tickOptions: {
formatString: '%d',
fontSize: '8pt'
}
}
},
seriesDefaults: {
renderer: $.jqplot.BarRenderer,
rendererOptions: {
fillToZero: true
}
},
highlighter: {
show: true,
sizeAdjust: 7.5
},
cirsor: {
show: false
}
}
var plot = $.jqplot('chart', data, options).replot();
}

Categories