Highstock - irregular time interval - javascript

Highcharts has an example using irregular time intervals, I want to do the same on highstock howeverthere is no parameter for the xAxis-type.
JSFiddle code
My options are
$(function() {
$.getJSON('http://184.173.195.228/~ktwsn/temp2.php?action=get_sensor&sensor_serial%5B%5D=3B74F41400000069&sensor_serial%5B%5D=3BB2FA14000000E6&sensor_serial%5B%5D=3B91F11400000079&sensor_serial%5B%5D=3BC7F114000000E5&sensor_serial%5B%5D=3BC0F314000000E3&callback=?',
{action: "get_sensor"},
function(data) {
var seriesOptions = [];
$.each(data, function(key, val) {
seriesOptions.push({
name: val.name,
data: val.samples,
marker : {
enabled : true,
radius : 3
}
});
});
// create the chart
chart = new Highcharts.StockChart({
chart: {
renderTo: 'container',
},
xAxis: {
type: 'datetime'
},
rangeSelector: {
selected: 4
},
series: seriesOptions
});
});
});

Found it. The nomenclature between highcharts and highstock are different.
For Hightstock it's
xAxis: {
ordinal: false
}
The company really needs to combine highcharts and highstock. A single API documentation would be easier to follow.

I would verify that the output data is actually using the same time stamp.
Many cases like this include time stamps for the same date, but different times, which will always result in different x axis placement.
(I know that may be an obvious check, but I have seen it many times...)

Related

Highcharts Windbarb with ajax data loading

OK. Rephrasing an unanswered earlier question.
I have a chart as shown below with the data loading dynamically through ajax.
A simplified version (without ajax) of this graph works fine as shown in this jsfiddle.
The code below is the chart as I use it, straight from its context.
The idea is there are several timeseries (x-axis) in the graph and I wish to display the wind characteristics of speed and direction at those same times through windbarbs. The windbarbs take two arguments at each defined x-value all other series take one argument (the y-axis).
My question is: why doesn't it work (why the stackdump) while it does work in jsfiddle (without the ajax call and thus without the addSeries call?
As a derivative: in the jsfiddle the onSeries attribute does not work. What is wrong there?
And finally: is it possible to get the windbarbs above the series graphs and not fixed on the x-axis?
The problem seems to be in the loading of the wind data after the loading of the other series. As that part is in the ajax call with the (idx == 'wind') condition it is quite easy to spot. It breaks in the setData call of highStock with the following stackdump:
Uncaught TypeError: r is undefined
setData highstock.src.js:33902
init highstock.src.js:33182
init highstock.src.js:54816
init windbarb.src.js:361
initSeries highstock.src.js:27886
addSeries highstock.src.js:36888
fireEvent highstock.src.js:2112
addSeries highstock.src.js:36887
success line 2 > injectedScript:176
success line 2 > injectedScript:171
jQuery 6
doSensorIn2p5 line 2 > injectedScript:162
SetGraphView0 line 2 > injectedScript:276
onclick (index):1
Without the wind data it works fine.
var doSensorIn10 = function(){
let ReferenceColours = ['#79bc6a', '#bbcf4c', '#eec20b', '#f29305', '#960018' ];
let ReferenceConcentrations10 = [0,25,50,90,180];
let t ={chart: { renderTo: 'chartcontainerIn10',type: 'spline',alignTicks: false, zoomType: 'xy', pinchType: 'xy'},
title: { text: 'AirQuality Sensor In for PM10'},
credits: { enabled: true},
xAxis: { type: 'datetime', ordinal: false, dateTimeLabelFormats: { day: '%e %b',week: '%e %b %y',month: '%b %y',year: '%Y'} },
yAxis:
[{
title: { text: 'Luchtkwaliteit (μg/m3)'},
opposite: false, labels: { align: 'right',x: -5},
},
{
linkedTo: 0,
gridLineWidth: 0,
opposite: true,
title: { text: null},
labels: { align: 'left',x: 5},
tickInterval: 20
}],
legend: { enabled: true},
tooltip: { valueSuffix: 'μg/m3',valueDecimals: 1,xDateFormat: '%A, %b %e, %H:%M'},
series:[],
rangeSelector:
{
buttons:[{ count: 6,type: 'hour',text: '6h'},
{ count: 12,type: 'hour',text: '12h'},
{ type: 'all',text: 'All'}],
inputEnabled: false
}
};
let chart = new Highcharts.StockChart(t);
chart.showLoading();
$.ajax({
url: 'airlinkdataIn10.json',
cache: false,
dataType: 'json',
success: function(resp){
let titles = {
'In_pm10': 'In_pm10','In_pm10_1hr': 'In_pm10_1hr','In_pm10_3hr': 'In_pm10_3hr','In_pm10_24hr': 'In_pm10_24hr','In_pm10_nowcast': 'In_pm10_nowcast','wind': 'wind'}
let idxs = ['In_pm10','In_pm10_1hr','In_pm10_3hr','In_pm10_24hr','In_pm10_nowcast','wind']
let cnt = 0;
idxs.forEach(function(idx) {
console.log('idx = ' + idx);
if (idx in resp) {
if (idx == 'wind') {
console.log('Doing Wind correctly : Before addSeries');
chart.addSeries({name: titles[idx], type: 'windbarb', showInLegend: false, onSeries: 'InPM2p5', tooltip: {valueSuffix: ' m/s'}, data: resp[idx] }, false);
console.log('Doing Wind correctly : After addSeries');
}
else {
console.log('Doing ' + idx + ' correctly');
chart.addSeries({name: titles[idx], data: resp[idx]}, false);
}
chart.series[cnt].options.zIndex = cnt+50;
}
cnt++;
});
chart.hideLoading();
chart.redraw();
}
}
)};
The data series (in short version) is as follows:
{"In_pm2p5":[[1609484460000,26.20], ... ]],
"In_pm2p5_1hr":[[1609484460000,32.90], ... ]],
...
"wind":[[1609484460000,0.0,194], ...]]}
Each parameter has 2880 values, wind may have one value less (which I tested in jsfiddle and does not seem to be a problem).
Thank you for your wide and clear description!
In this case it is hard to say why the chart is not rendering properly without reproduction of your data fetching. The addSeries feature should work without any issues with the windbarb type series.
Demo: https://jsfiddle.net/BlackLabel/ktLyunw8/
2.
in the jsfiddle the onSeries attribute does not work. What is wrong there?
I cannot see it, everything seems to work fine:
3.
And finally: is it possible to get the windbarbs above the series graphs and not fixed on the x-axis?
Like in the case of using the onSeries feature? Or render it totally above the plot area?
I'd like to render it above the plot area or in the top of the plot area (like without onSeries it is at the bottom) so all windbarbs in one line.
In this case, you can render the second xAxis and assign the winbarb series to it.
API: https://api.highcharts.com/highcharts/xAxis.opposite
Demo: https://jsfiddle.net/BlackLabel/ud0kyrgh/

Highcharts: how to define x-axis for dynamic chart

I am using Highcharts to automatically plot an array which is output from a sensor and is updated every second or so. The array is x elements long. This particular sensor measures the light intensity at x steps between some min and max wavelengths (that is, it measures the intensity at increments of (max-min)/x--in my case this increment is not an integer). I also have a static data set that is plotted on the same axes with the same x-axis requirements.
I am able to successfully graph this data dynamically, but the x-axis scale is wrong. Instead of ranging from min to max, Highcharts defaults to a range of min to min+x. I'd like to change the x-axis increment so that the scaling is correct.
Can a min, max, and number of data points or step be defined to generate the x-axis? Or is there a way to define the x- and y-axis values as individual arrays that are plotted against each other? Some other way? I have done lots of searching and experimenting but have come up short.
The relevant snippet of my code is below.
function showData(result) { // 'result' is an array that comes from the sensor
var numbers = int(split(resultString, ","));
chart.series[1].setData(numbers);
socket.send('a'); // send a byte to tell it to start sending new data
loop++; //increase loop every time the server receives data
chart.setTitle({ text: 'Spectrum, reading #' + loop });
} //showData
$(function () {
chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'area',
load: function() {
chart = this;
showData();
}
},
title: {
text: 'Spectrum, reading 0'
},
xAxis: {
title: {
text: 'Wavelength [nm]',
allowDecimals: false,
},
},
yAxis: {
title: {
text: ''
},
},
tooltip: {
pointFormat: '{point.x}'
},
plotOptions: {
area: {
pointStart: 340,
marker: {
enabled: false,
symbol: 'circle',
radius: 2,
states: {
hover: {
enabled: true
}
}
}
}
},
series: [{
name: '404 nm laser spectrum',
data: [130,130,114,113,113,116,112,111,112,112,115,113,113,115,
112,114,113,113,114,115,113,114,113,114,115,115,117,119,124,
136,145,164,190,217,252,363,482,491,417,285,188,156,140,132,
127,122,117,118,117,115,116,115,116,118,116,116,117,116,117,
116,113,117,114,113,115,112,116,114,114,116,114,114,116,113,
116,115,114,115,115,114,115,115,115,116,114,115,116,114,118,
114,116,116,115,118,114,113,117,113,116,116,115,116,115,115,
115,114,117,116,117,118,120,118,122,119,128,127,130,134,136,
138,140,137,139,134,136,134,132,133,134,131,132,130,130,131,
128,128,131,129,131,131,134,136,134,140,139,137,143,140,138,
141,136,134,132,127,126,126,123,123,118,119,122,118,120,117,
116,118,116,118,116,115,117,116,115,116,115,115,116,114,119,
113,114,116,115,116,114,114,116,116,113,117,116,114,118,112,
115,114,113,116,115,114,115,113,116,114,114,116,115,115,114,
112,114,114,113,114,115,113,117,114,115,112,114,114,113,115,
114,114,115,113,112,115,112,113,115,112,116,113,113,115,116,
113,116,113,115,113,114,115,115,114,116,114,116,113,116,117,
113,115,116,115,117,115,114,117,113,115,118,114,116,115,115,
116,114,113,116,114,117,115,114,117,115,114,115,116,116,116,
117,117,114,0],
color: '#36D39F'
}, {
name: 'Current measured spectrum',
data: numbers,
color: '#4A235A'
}]
});
});
EDIT: here's a demo showing how mine currently functions: https://jsfiddle.net/bgzgc1d9/2/. The x-axis should range from 340 to 850 with 288 data points evenly spaced on this interval

Prevent Area plot Y-axis from starting with ZERO

What is the configuration for Y-axis to not start with ZERO but rather start with value close to lowest Y-axis data point in HighCharts/HighStock?
Here is the demo of chart which has a very great Y-axis data values while the minimal Y-axis plot point is ZERO: http://jsfiddle.net/ubnjjups/
and sample configuration used in the demo:
{
series: [{
type: 'area',
data: [
[1375660800000, 106861],
[1375747200000, 107397],
[1375833600000, 108674],
[1375920000000, 108792],
[1376006400000, 110504],
[1376265600000, 110658],
[1376352000000, 110792]
]
}],
}
The problem here is that you are using 'area' type which by definition needs to show you area from 0 to the point. If you switch to say 'spline', it automatically does what you want.
$(function () {
$('#container').highcharts('StockChart', {
series: [{
type: 'spline',
data: [[1375660800000, 106861],[1375747200000, 107397],[1375833600000, 108674],[1375920000000, 108792],[1376006400000, 110504],[1376265600000, 110658],[1376352000000, 110792],[1376438400000, 111095],[1376524800000, 112334],[1376611200000, 112775],[1376870400000, 113051],[1376956800000, 113426],[1377043200000, 113516]]
}],
});
});
UPDATE:
If you want to continue to use Area chart (so you have filled area under), I recommend you use min on your yAxis. I have changed your code here
$(function () {
$('#container').highcharts('StockChart', {
series: [{
type: 'area',
data: [[1375660800000, 106861],[1375747200000, 107397],[1375833600000, 108674],[1375920000000, 108792],[1376006400000, 110504],[1376265600000, 110658],[1376352000000, 110792],[1376438400000, 111095],[1376524800000, 112334],[1376611200000, 112775],[1376870400000, 113051],[1376956800000, 113426],[1377043200000, 113516]]
}],
yAxis:{
min: 105000
}
});
});
The value of min can be calculated ahead of time when you get your data back from the server and calculate your minimum value point. Hope this helps.
Based on #Vadim's answer, as of today I suggest calculating lowest Y-axis value inside the yAxis.min configuration itself to keep code consistent and portable. The only requirement is to extract the data into a variable outside the chart initialization.
With data in format <Timestamp>, <Y-axis value> following would work:
var data = [
[1375660800000, 106861],
[1375747200000, 107397],
[1375833600000, 108674]
];
$('#container').highcharts('StockChart', {
series: [{
type: 'area',
data: data
}],
yAxis: {
min: (function() {
var min = data[0][1];
for (var i = 0; i < data.length; i++) {
var value = data[i][1];
if (value < min) {
min = value;
}
}
return min;
})()
}
});
Live demo: http://jsfiddle.net/squuwqmg/

Highstock X-Axis: Categories in Place of Time

Is it possible to use categories as x-values in Highstock?
I don't need a time bar as x-axes, but something like numbered ratings.
This works in Highcharts, but i need the scrollbar functionality from Highstock.
You can use highstock release, but use highcharts and scrollbar.
Take look at example:
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container'
},
xAxis:{
min:0,
max:2,
categories:['first','second','third','fourth']
},
scrollbar: {
enabled: true
},
rangeSelector: {
enabled:false
},
series: [{
name: 'USD to EUR',
data: [1,3,4,6]
}]
});
http://jsfiddle.net/b826C/
You may be able to get the functionality you want using Highstock and the following workaround:
The x-axis is a datetime and your series date ranges from datetime 0 to datetime x, here x is the number of categories you have.
Then when you format the xAxis label use:
labels: {
formatter: function() {
return categoryText[this.value];
}
}
Similarly you can format, the text in the navigator,
categoryText is a local variable that contains the text names of your categories.
Here is the fiddle: https://jsfiddle.net/b826C/98/
One of the developers of Highcharts/Highstock answered to my support request:
It's not possible to switch the navigator to something else than time intervals.
The only solution to my problem is a navigation with a master and detail chart like in this sample: http://www.highcharts.com/demo/dynamic-master-detail

Getting HighCharts to show fewer data points

I'm plotting a chart where the x axis is a datetime. My data contains lots of sample from each day, and the resulting chart is jittery.
Is there an easy way to get highcharts to only display 1 or 2 datapoints from each day, to make the chart smoother?
http://jsfiddle.net/RjPRd/72/
var data = [[1354282654000,13],[1354285785000,13],[1354289387000,14],[1354292990000,15],[1354296592000,13],[1354419090000,20],[1354422692000,21],[1354426295000,20],[1354435425000,19],[1354438087000,19],[1354538087000,24]];
var options = {
chart: { renderTo: 'graph' },
xAxis: { type: 'datetime' },
series: [{data: data}]
};
var chart = new Highcharts.Chart(options);
​
If you are asking if HighCharts can do interpolation/projections then the answer is no.
What you can do is pre-process your data or use HighStock with dataGrouping. Here is a very basic example.
This is the code that does it:
plotOptions: {
series: {
dataGrouping: {
approximation: 'average', //default
units: [[
'day',
[1]
]]
}
}

Categories