jqPlot bar graph with multiseries showing empty data series - javascript
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();
}
Related
Stop Highchart when end of the Array element reached
So What I am trying to Create is a Chart in which around 130 points data are flowing in a single second time. Now, Suppose I Have an array of 1000 elements which I want to render in Highchart. I am able to render the Highchart with the 1000 elements of array, but the problem is that after the end of the array, the Highchart is not stopping. it keeps running. I just want to stop the Highchart when it reaches end of the array. Here is the Code that I have tried var data = [7,10,8,6,8,2,5,2,2,2,3,4,4,10,6,10,5,10,0,2,9,5,7,0,5,0,5,7,8,7,5,1,9,1,5,7,10,3,7,0,2,10,8,8,1,1,0,7,6,3,1,10,0,8,3,5,5,10,3,8,4,0,3,5,8,7,0,0,0,8,7,3,2,1,0,6,7,7,3,7,5,0,1,0,0,4,9,4,4,3,0,2,10,9,0,2,7,6,5,9,0,6,7,9,0,6,2,7,1,6,5,1,3,1,0,5,0,4,2,7,2,0,7,0,3,10,6,3,4,9,9,10,10,9,5,9,8,5,3,2,5,9,5,10,10,7,8,3,8,9,5,3,9,0,1,2,6,4,1,9,0,5,0,5,6,4,1,1,3,8,2,0,7,6,4,0,6,5,5,6,4,6,6,3,3,5,5,8,7,3,4,7,5,6,1,4,2,4,7,9,8,4,0,3,8,6,2,6,10,8,10,1,10,8,6,8,8,3,8,7,8,6,7,10,9,10,0,7,7,8,1,10,1,4,7,10,7,0,9,6,3,3,3,1,4,3,4,5,0,5,9,0,6,1,8,5,1,8,9,4,0,4,5,4,3,8,2,10,5,9,4,9,5,3,6,5,7,2,2,7,1,1,9,7,4,1,7,5,2,10,6,4,3,5,7,2,4,5,7,3,2,0,8,5,5,7,8,2,9,5,9,1,2,0,7,8,10,5,6,9,2,5,1,9,4,0,7,4,4,7,10,0,8,6,0,6,4,4,8,3,9,1,3,0,0,4,4,2,5,3,3,6,1,4,6,6,4,9,7,0,2,2,1,2,2,6,2,0,2,5,7,8,8,1,7,3,9,0,0,0,9,4,9,8,9,7,10,8,2,0,5,10,10,0,1,7,5,9,2,8,10,10,4,6,6,6,10,10,5,1,5,2,1,9,3,2,5,3,1,3,10,7,1,3,5,3,0,6,7,5,1,10,5,9,0,9,2,3,0,10,0,6,9,8,3,8,7,0,10,4,2,2,5,6,7,0,10,10,9,9,8,6,10,5,9,0,6,4,8,5,0,4,4,4,1,8,3,0,9,3,3,9,1,5,0,10,1,1,3,10,6,5,8,0,6,5,2,7,10,4,2,0,10,1,7,6,2,0,1,6,10,10,6,6,10,1,4,7,5,6,5,4,1,5,6,9,1,8,4,7,2,8,5,9,7,3,9,2,2,8,10,6,10,10,7,8,7,2,6,8,7,4,6,1,5,9,2,0,5,4,4,0,4,5,7,2,3,8,9,1,0,8,6,10,8,3,7,3,3,6,7,2,7,6,6,2,8,6,9,6,8,5,4,8,4,6,7,9,8,7,8,5,8,2,0,8,5,0,5,2,8,4,7,0,7,1,4,8,10,8,2,5,10,9,1,9,3,0,6,9,2,10,5,1,4,0,4,9,1,1,3,5,0,5,5,2,5,1,1,7,0,2,6,8,10,7,9,3,0,9,4,2,4,6,2,2,9,2,7,3,6,6,9,2,2,0,2,9,1,5,7,10,10,1,8,5,9,9,4,1,7,1,0,0,6,7,7,7,2,9,9,2,10,5,4,2,3,10,9,9,7,1,1,6,8,4,9,6,7,4,9,4,2,7,6,2,6,0,1,5,5,8,9,5,1,7,8,7,3,2,3,1,1,2,5,6,4,10,8,10,3,3,1,0,6,7,0,7,4,8,4,7,6,0,7,1,2,3,10,4,1,10,7,9,4,7,7,10,10,10,6,8,9,7,3,10,9,0,3,6,2,10,5,3,6,8,5,0,2,3,1,6,9,10,9,10,7,5,8,7,4,4,3,10,2,3,4,3,10,8,5,9,8,5,6,2,4,9,1,5,0,7,1,1,4,4,10,4,7,8,8,9,7,1,9,5,5,4,3,0,0,9,5,6,3,3,4,6,1,2,6,2,8,4,10,0,9,1,10,2,7,3,6,3,9,2,3,5,7,8,1,1,9,3,4,6,7,6,2,2,8,0,10,3,3,5,7,4,1,3,9,5,4,3,3,2,9,8,7,8,7,6,8,7,7,1,2,10,10,2,9,3,2,3,2,9,9,0,3,0,4,9,6,0,1,6,9,5,8,7,9,5,6,8,3,5,3,4,9,8,0,3,4,8,6,9,4,7,1,9,8,0,4,8,1,0,7,3,3,1,6,9,9,5,4,3,8,8,9,10,4,9,0,7,8,6,9,8,4,10,4,1,2,5,4,0,6,4,1]; var json_array = data ; var i = 0; function next() { return json_array[i++]; // i++; } Highcharts.chart('container', { chart: { type: 'line', animation: Highcharts.svg, // don't animate in old IE marginRight: 10, events: { load: function() { // set up the updating of the chart each second var series = this.series[0], chart = this; var count = 0 ; setInterval(function() { var x = (new Date()).getTime(), // current time y =next(); console.log(y) ; series.addPoint([x, y], false, true); chart.redraw(false); }, 1000/130); } } }, time: { useUTC: false }, title: { text: 'ECG Graph Plot From MySQl Data' }, xAxis: { type: 'datetime', labels: { enabled: false }, tickPixelInterval: 150 }, yAxis: { //max: 1.5, //min: -1.5, title: { text: 'Value' }, plotLines: [{ value: 0, width: 1, color: '#808080' }] }, tooltip: { headerFormat: '<b>{series.name}</b><br/>', pointFormat: '{point.x:%Y-%m-%d %H:%M:%S}<br/>{point.y:.2f}' }, legend: { enabled: false }, exporting: { enabled: false }, series: [{ animation: false, name: 'ECG Graph Plot From MySQl Data', dataGrouping: { enabled: false }, data: (function() { // generate an array of random data var data = [], time = (new Date()).getTime(), i; for (i = -1000 ; i <= 0; i += 1) { data.push([ time + i * 10, null ]); } return data; }()) }] }); I Have also created a Fiddle for it as you can see below. https://jsfiddle.net/abnitchauhan/toqaxLj7/
Just clear Interval when it reached the last element of the array. check out following code. var draw = setInterval(function() { var x = (new Date()).getTime(), // current time y =next(); console.log(y) ; if (i == data.length) { clearInterval(draw); return; } series.addPoint([x, y], false, true); chart.redraw(false); }, 1000/130); here is the fiddle code link. https://jsfiddle.net/geekcode/8nL53x01/1/
how to redraw a jqplot bar chart using javascript
I have two functions. FunctionToChangeBarChart and getPreviousDayValues. I want to draw jqPlot barchart in each function. So i wrote code for drawing bar chart in a fuction LoadBarChart and called this function both FunctionToChangeBarChart and getPreviousDayValues functoins. The problem is that the bar chart redraws, one over another, in each function call. how can i refresh the bar chart? FunctionToChangeBarChart = function(event){ var totalNoUsers = 10; var tempStart = 4; var pendingTaskCount = 7; var completedTaskCount = 2; LoadBarChart(totalNoUsers,tempStart,pendingTaskCount,completedTaskCount); }); getPreviousDayValues = function(Event){ var totalUsers = 20; var tempStart = 4; var pendingTaskCount = 9; var completedTaskCount = 3; LoadBarChart(totalUsers,tempStart,pendingTaskCount,completedTaskCount); } function LoadBarChart(total,start,pending,complete,todayVal){ var s1 = [total, start, pending, complete]; var ticks = ['total', 'started', 'pending','completed' ]; plot1 = $.jqplot('chart1', [s1], { animate: !$.jqplot.use_excanvas, seriesDefaults:{ renderer:$.jqplot.BarRenderer, rendererOptions: {barMargin: 0 , varyBarColor : true}, pointLabels: { show: true } }, title:{text:"Task Status and Users"}, grid: { background: 'transparent', // CSS color spec for background color of grid. drawBorder:false, drawGridlines:false, shadow:false }, axes: { xaxis: { renderer: $.jqplot.CategoryAxisRenderer, ticks: ticks, tickOptions : { // showGridline : false } }, yaxis: { tickOptions : { // showGridline : false }, // label:'Status', labelRenderer: $.jqplot.CanvasAxisLabelRenderer } }, seriesColors: [ "#000", "#ccc", "red","green"], highlighter: { show: false } }); $('#chart1').bind('jqplotDataClick', function (ev, seriesIndex, pointIndex, data) {$('#info1').html('series: '+seriesIndex+', point: '+pointIndex+', data: '+data); }); }
Stackedbars on jqPlot with a dynamic json
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, .... });
How to divide data from the series in highcharts
I want to process data from a .csv file to: Divide the data coming in by 10, e.g., 588 => 58.8 Remove outliers from the data or to change to zero, e.g., 8888 => 0 Here is my javascript, I appreciate the help!! $.get('http://www.geoinc.org/Dropbox/geo/sites/GC_ROOM/charts/hassayampa.csv', function(data) { // Split the lines var lines = data.split('\n'); var i = 0; var csvData = []; // Iterate over the lines and add categories or series $.each(lines, function(lineNo, line) { csvData[i] = line.split(','); i = i + 1; }); var columns = csvData[0]; var categories = [], series = []; for(var colIndex=0,len=columns.length; colIndex<len; colIndex++) { //first row data as series's name var seriesItem= { data:[], name:csvData[0][colIndex] }; for(var rowIndex=1,rowCnt=csvData.length; rowIndex<rowCnt; rowIndex++) { //first column data as categories, if (colIndex == 0) { categories.push(csvData[rowIndex][0]); } else if(parseFloat(csvData[rowIndex][colIndex])) // <-- here { seriesItem.data.push(parseFloat(csvData[rowIndex][colIndex])); } }; //except first column if(colIndex>0)series.push(seriesItem); } // Create the chart var chart = new Highcharts.Chart( { chart: { renderTo: 'test', type: 'line', zoomType: 'x', }, title: { text: 'Daily Average Temperature', x: -20 //center }, subtitle: { text: 'Source: HASSAYAMPA', x: -20 }, xAxis: { categories: categories, labels: { step: 80, }, tickWidth: 0 }, yAxis: { title: { text: 'Temperature (\xB0C)' }, //min: 0 }, tooltip: { formatter: function() { return '<b>'+ this.series.name +'</b><br/>'+ this.x +': '+ this.y +'\xB0C'; } }, legend: { layout: 'vertical', //backgroundColor: '#FFFFFF', //floating: true, align: 'left', //x: 100, verticalAlign: 'top', //y: 70, borderWidth: 0 }, plotOptions: { area: { animation: false, stacking: 'normal', lineColor: '#666666', lineWidth: 1, marker: { lineWidth: 1, lineColor: '#666666' } } }, series: series }); });
I'm not sure what you are asking, but I'll take a shot at it... First things first, this snippet of code is not sound. It'll not only skip NaNs but 0s as well (which is valid numeric data): else if(parseFloat(csvData[rowIndex][colIndex])) { seriesItem.data.push(parseFloat(csvData[rowIndex][colIndex])); } Instead I'd do: //first column data as categories, if (colIndex == 0) { categories.push(csvData[rowIndex][0]); } else { var fVal = parseFloat(csvData[rowIndex][colIndex]); if (!isNaN(fVal)) { fVal = fVal / 10.0; //<-- here's the division!! seriesItem.data.push(fVal); } } As far as how to exclude outliers, the big question there is how do you want to exclude outliers? A simple min/max criteria? Then just check that fVal is within those limits before seriesItem.data.push...
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.