I made a spline chart using Highcharts library containing two series of data loaded from two different CSV files and it works fine. Now I need another spline chart, but with 54 data series.
I used PHP to create the 54 CSV files, then my Javascript code generating the chart is:
<script type="text/javascript">
$(function () {
var chart;
$(document).ready(function() {
var options = {
chart: {
renderTo: 'chart_day',
type: 'spline'
},
title: {
text: 'Andamento giornaliero temperatura.'
},
xAxis: {
type: 'datetime',
second: '%H:%M:%S'
},
yAxis: {
title: {
text: 'Temperatura (°C)'
},
},
tooltip: {
formatter: function() {
return '<b>'+ this.series.name +'</b><br/>'+
Highcharts.dateFormat('%H:%M:%S', this.x) +': '+ this.y +' °C';
}
},
series: [ <?php for($i=0;$i<52;$i++)
echo "{ name: \"Sensor".($i+1)."\", data: []},";
echo "{ name: \"Sensor".($i+1)."\", data: []}";
?>]
};
for( i=1; i<=54; i++){
if(i!=5){
$.get('file/file'+i+'.txt', function(data) {
// Split the lines
var lines = data.split('\n');
// Iterate over the lines and add categories or series
$.each(lines, function(lineNo,line) {
if (line != "") {
var items = line.split(',');
var timeElements = items[0].split(':');
var date = Date.UTC(2004, 2, 1, timeElements[0], timeElements[1], timeElements[2], 0);
options.series[i-1].data.push([date,parseFloat(items[1])]);
}
});
if(i==54)
chart = new Highcharts.Chart(options);
});
}
}
});
});
</script>
There is an error in the JS consolle:
"Uncaught TypeError: Cannot read property 'data' of undefined "
Seems like your series initialization is broken. Try this
var series = [];
for(i=0;i<52;i++)
{
series.push({name: ('Sensor' + (i + 1)), data: []});
}
and set this series object at your options:
var options = {
..
series: series
};
Related
I am loading Highcharts like this.
var options = {
credits: {
enabled: false
},
chart: {
renderTo: 'chart_box',
type: 'areaspline'
},
title: {
text: ''
},
xAxis: {
crosshairs: true,
labels: {
step: 5,
rotation: -45
}
},
series: []
};
Then I have a function which is called when graph needs to be loaded. Upon calling the function, data is fetched through AJAX and assigned to series and date lie this:
$.ajax({
url: 'url/charts',
type: 'post',
data: data
}).done(function(data) {
var dateCount = data.dates.length;
var stepCount = 1;
if (dateCount > 10) {
stepCount = 5;
}
options.xAxis.categories = data.dates;
$.each(data.series, function(name, elem) {
options.series.push({
name: name.replace('_', ' ').toUpperCase().trim(),
data: elem
})
});
chart = new Highcharts.Chart(options);
});
The issue here is that even though I have given step as 5 , it is showing dates with 15 dates interval. I mean in xAxis labels. It seems like it will be multiplied by three always. If I give 2, it will show 6 days interval in labels. Everything working fine in a chart which is not using AJAX to load data.
I am working on stock charts where i have to show the stock data of three currencies. I am able to see the chart and rates corresponding to it but dates on x axis are not coming properly. my json response is like this .
[{"rate":1.3349,"month":"1422403200000"},{"rate":1.3415,"month":"1422316800000"},{"rate":1.3394,"month":"1422230400000"},{"rate":1.3202,"month":"1421971200000"},{"rate":1.304,"month":"1421884800000"},{"rate":1.3109,"month":"1421798400000"},{"rate":1.3017,"month":"1421712000000"},{"rate":1.3114,"month":"1421625600000"},{"rate":1.305,"month":"1421366400000"},{"rate":1.292,"month":"1421280000000"},{"rate":1.2876,"month":"1421193600000"},{"rate":1.2819,"month":"1421107200000"},{"rate":1.2801,"month":"1421020800000"}]
its just an example of json response. in my java vo rate is of double type and month is of String type.
my js code is here
function drawChart(){
var seriesOptions = [],
seriesCounter = 0,
names = ['EURGBP', 'EURJPY', 'EURCHF'],
// create the chart when all data is loaded
createChart = function () {
$('#drawchart').highcharts('StockChart', {
rangeSelector: {
selected: 4
},
yAxis: {
labels: {
formatter: function () {
return (this.value > 0 ? ' + ' : '') + this.value + '%';
}
},
plotLines: [{
value: 0,
width: 2,
color: 'silver'
}]
},
plotOptions: {
series: {
compare: 'percent'
}
},
tooltip: {
pointFormat: '<span style="color:{series.color}">{series.name}</span>: <b>{point.y}</b> ({point.change}%)<br/>',
valueDecimals: 2
},
series: seriesOptions
});
};
$.each(names, function (i, name) {
$.getJSON('/bin/drawChart, function (data) {
var dataArray = new Array;
$.each(data, function (i, obj) {
dataArray.push([obj.month,obj.rate]);
});
alert(dataArray);
seriesOptions[i] = {
name: name,
data: dataArray,
tooltip: {
valueDecimals: 2
}
};
// As we're loading the data asynchronously, we don't know what order it will arrive. So
// we keep a counter and create the chart when all the data is loaded.
seriesCounter += 1;
if (seriesCounter === names.length) {
createChart();
}
});
});
}
Why date is not appearing correctly on x-axis
The problem is that in your JSON should be fields x and y. Morever values should be number not string as you have. So you should prepare correct JSON structure in your backend or parse it after loading.
your X-axis information is missing in draw chart method
I'm still pretty wet behind the ears when it comes to javascript. I need some help adding a secondary axis that is something like revenue to a highstock chart that also uses $.getJSON (JSONP) to snag a json file to populate the data.
Check out the JSFiddle example here. And here is the sample data set to play with. And finally, an example of secondary axis in Highcharts.
$(function () {
var seriesOptions = [],
seriesCounter = 0,
names = ['MSFT', 'AAPL', 'GOOG'],
// create the chart when all data is loaded
createChart = function () {
$('#container').highcharts('StockChart', {
rangeSelector: {
selected: 4
},
yAxis: {
labels: {
formatter: function () {
return (this.value > 0 ? ' + ' : '') + this.value + '%';
}
},
plotLines: [{
value: 0,
width: 2,
color: 'silver'
}]
},
yAxis: {
floor: 0
},
plotOptions: {
series: {
compare: 'value'
}
},
tooltip: {
pointFormat: '<span style="color:{series.color}">{series.name}</span>: <b>{point.y}</b> ({point.change}%)<br/>',
valueDecimals: 2
},
series: seriesOptions
});
};
$.each(names, function (i, name) {
$.getJSON('http://www.highcharts.com/samples/data/jsonp.php?filename=' + name.toLowerCase() + '-c.json&callback=?', function (data) {
seriesOptions[i] = {
name: name,
data: data
};
// As we're loading the data asynchronously, we don't know what order it will arrive. So
// we keep a counter and create the chart when all the data is loaded.
seriesCounter += 1;
if (seriesCounter === names.length) {
createChart();
}
});
});
});
Any help and explanations (so I can learn) is much appreciated. I'm still trying to learn how to tie jsonp and charting together, especially multiple series of data and json files.
Write it like this:
yAxis: [{
labels: { ... },
title: { ... },
...
},
{
labels: { ... },
title: { ... },
...
}]
http://jsfiddle.net/5eem7a2a/1/
(function($){
$(function () {
$(document).ready(function() {
Highcharts.setOptions({
global: {
useUTC: false
}
});
var i=0;
var chart = new Highcharts.Chart({
chart: {
type: 'spline',
renderTo: 'container',
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];
setInterval(function() {
var Name = new Array();
Name[0] = "Random data";
Name[1] = "Volvo";
var length=chart.series.length;
var flag=0;
var index=0;
var x = (new Date()).getTime(), // current time
y = Math.random();
for (var k=0;k<Name.length;k++) {
for(var j=0;j<chart.series.length;j++) {
if(chart.series[j].name==Name[k]) {
flag=1;
index=j;
x = (new Date()).getTime();
y = Math.random();
break;
}
}
if(flag==1) {
chart.series[index].addPoint([x, y], true, true);
flag=0;
} else {
chart.addSeries({name: '' + Name[k] + '', data: [] });
chart.series[length].addPoint([x, y+1], true);
length=length+1;
}
}
}, 1000);
}
}
},
title: {
text: 'Live random data'
},
xAxis: {
type: 'datetime',
tickPixelInterval: 150
},
yAxis: {
title: {
text: 'Value'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
tooltip: {
formatter: function() {
return '<b>'+ this.series.name +'</b><br/>'+
Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.x) +'<br/>'+
Highcharts.numberFormat(this.y, 2);
}
},
legend: {
enabled: false
},
exporting: {
enabled: false
},
series: [{
name: 'Random data',
data: (function() {
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;
for (i = -19; i <= 0; i++) {
data.push({
x: time + i * 1000,
y: Math.random()
});
}
return data;
})()
}]
});
});
});
})(jQuery);
I am able to add series and add point in charts but the series that I add after initialization, which is "volvo", is not drawing lines between its points. What might be the problem?
And is there any other way of comparing arrays and adding points without a for-loop? Because I can get millions of series at times and I don't want to be looping over arrays to check if it exists or not. So is there any efficient way of finding wheteher a list already exists, and if it does what is its index?
here is its fiddle: www.jsfiddle.net/2jYLz/
It is related with fact that you have enabled shifting in addPoint() when you add new serie. In other words, shifting remove first point and add new in the end of serie. So when you have one point it caused your scenario. So you need to disable shipfing, and when lenght of series.data achieve i.e 10 points, shifting should be enabled.
×212414
×123754
I am calling a PageMethod in codebehind.aspx.cs file which returns me a string array[] in the javascript code in the aspx page the problem at hand is that string array returns Time(X axis-Value),Data/Name(Y axis Value),Type(Defines the type of chart (Spline or Column)) from a WEB SERVICE. I am using that data to add series dynamically to the chart. Using the function chart.AddSeries() but I am unable to do so.
Can anyone please guide me how to do that and upon doing that I want to add points to the particular Series.
Please Note that I would be displaying to types{Spline and Column} on the same chart.
<script type="text/javascript">
alert("Bingo");
$(function () {
$(document).ready(function () {
Highcharts.setOptions({
global: {
useUTC: false
}
});
var chart;
chart = new Highcharts.Chart({
chart: {
renderTo: 'ltrChart',
type: 'spline',
marginRight: 10,
events: {
load: function () {
PageMethods.GetSingleValue(function (result) {
var Name = new Array();
var Type = new Array();
var Data = new Array();
var Time = new Array();
var Ser = chart.series;
for (var i = 0; i < 6; i++) {
Type[i] = result[i].split('-')[0];
Name[i] = result[i].split('-')[1];
Data[i] = result[i].split('-')[2];
Time[i] = result[i].split('-')[3];
chart.addSeries({ name :Name[i], data : [ [Time[i], Data[i]] ] }, true, true);
/* Test Method To ensure data Fetching */
// alert(Type[i] + Name[i] + Data[i] + Time[i]);
// alert(result[i]);
}
})
//console.log(typeof PageMethods.GetSingleValue);
// PageMethods.GetSingleValue();
setInterval("PageMethods.GetSingleValue()", 5000);
}
}
},
title: {
text: 'Live random data'
},
xAxis: {
//type: 'datetime',
//tickPixelInterval: 150
},
yAxis: {
title: {
text: 'Value'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
tooltip: {
formatter: function () {
return '<b>' + this.series.name + '</b><br/>' +
Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.x) + '<br/>' +
Highcharts.numberFormat(this.y, 2);
}
},
legend: {
enabled: false
},
exporting: {
enabled: false
},
series: [{
name: 'Test Data',
data: [[10, 50], [15, 55]]
}]
});
});
});
</script>
This is what I've done and works like a charm. On a side-note, since you mentioned aspx page, why don't you just buy the dot net highcharts library? It makes life a lot easier if you're a dot net fan!
I am initially creating a chart with 5 elements, and then using the "iterated" JSON serialized string to pass data to client-side. Traversing the elements gives me a dynamic live chart!
Highcharts chart = new Highcharts("livechart")
.InitChart(new Chart
{
Events = new ChartEvents { Load = "ChartEventsLoad" }
})
.SetSeries(initialSeries)
.SetXAxis(new XAxis { Categories = lsst.ToArray() })
.AddJavascripVariable("iterated", iterateData.ToString())
.AddJavascripVariable("index", "5")
.AddJavascripFunction("ChartEventsLoad",
#"// set up the updating of the chart each 5 seconds
var result = iterated;
var theseries = eval(result); // De-serializing the JSON object
var loopseries = function() {
var sseries = livechart.series[0]
,shift = sseries.data.length > 5; // shift if the series is longer than 5;
sseries.addPoint(theseries[0].data[index], true, shift);
var sseries1 = livechart.series[1]
sseries1.addPoint(theseries[1].data[index], true, shift);
index++; };
setInterval(loopseries, 5000);")
You can add as many series as you like; you can use a loop if needed and the same code I've added as a function can be used to create the chart completely in Javascript.