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/
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
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/