Issue: Currently I am trying to build a live stream graph which will display data in the range of 0.5 hour to 3 hours. So the graph updates continuously, but it updates at the extreme right side of the graph.
Requirement: My requirement is that I want to do the same thing, but it should be done at the centre of the graph. The live stream should be updated at the centre of the graph and right side should contain future time values with no data plotted against it.
I tried plotting null data against future timestamp values, but Stockchart does not accept such kind of data and displays nothing.
Here is a JSFiddle, the important part:
Highcharts.stockChart('container', {
chart: {
events: {
load: function () {
// set up the updating of the chart each second
var series = this.series[0];
setInterval(function () {
var x = (new Date()).getTime(), // current time
y = Math.round(Math.random() * 100);
series.addPoint([x, y], true, true);
}, 1000);
var series1 = this.series[1];
setInterval(function () {
var x = (new Date()).getTime(), // current time
y = Math.round(Math.random() * 100);
series1.addPoint([x, y], true, true);
}, 1000);
var series2 = this.series[2];
setInterval(function () {
var x = (new Date()).getTime(), // current time
y = Math.round(Math.random() * 100);
series2.addPoint([x, y], true, true);
}, 1000);
}
}
},
I tried plotting null data against future timestamp values, but Stockchart does not accept such kind of data and displays nothing.
It happens because by default xAxis.ordinal = true
it means that points are equally spaced in the chart regardless of the actual time or x distance between them. The solution is simple, set xAxis.ordinal = false
and set axis extremes to show future time before the graph line. Check the demo and code posted below.
var power = [],
speed = [],
torque = [],
i = 0;
let time = 1542278447000;
for (i; i < 100; i += 1) {
let torqueValue = Math.floor(Math.random() * (100 - 5 + 1)) + 5;
let speedValue = Math.floor(Math.random() * (100 - 5 + 1)) + 5;
powerValue = torqueValue * speedValue
time = time + 1000
torque.push([
time, // the date
torqueValue // the torque
]);
speed.push([
time, // the date
speedValue // the speed
]);
power.push([
time, // the date
powerValue // the power
]);
}
// create the chart
Highcharts.stockChart('container', {
chart: {
events: {
load: function() {
var chart = this,
multiplier,
dataLength,
x,
y;
setInterval(function() {
chart.series.forEach(function(series) {
multiplier = series.dataMax;
dataLength = chart.series[0].xData.length;
x = chart.series[0].xData[dataLength - 1] + 1000;
y = Math.round(Math.random() * multiplier);
series.addPoint([x, y], false, true);
});
chart.xAxis[0].setExtremes(null, x + 15000);
}, 1000);
}
}
},
rangeSelector: {
enabled: false,
selected: 2
},
navigator: {
enabled: false
},
scrollbar: {
enabled: false
},
title: {
text: ''
},
exporting: {
enabled: false
},
subtitle: {
text: ''
},
xAxis: {
title: {
text: 'Time'
},
ordinal: false
},
yAxis: [{
opposite: false,
startOnTick: true,
endOnTick: true,
labels: {
align: 'left',
x: -22
},
title: {
text: 'Torque',
x: -15
},
height: '30%',
offset: 0,
lineWidth: 2,
resize: {
enabled: true
}
}, {
opposite: false,
labels: {
align: 'left',
x: -22
},
title: {
text: 'Speed',
x: -15
},
top: '33%',
height: '30%',
offset: 0,
lineWidth: 2
}, {
opposite: false,
labels: {
align: 'left',
x: -22
},
title: {
text: 'Power',
x: -15
},
top: '66%',
height: '30%',
offset: 0,
lineWidth: 2
}],
legend: {
enabled: true
},
tooltip: {
split: true
},
credits: {
enabled: false
},
plotOptions: {
series: {}
},
series: [{
color: '#77787b',
type: 'spline',
name: 'Torque',
id: 'Power',
zIndex: 2,
data: torque
}, {
color: '#335572',
type: 'spline',
name: 'Speed',
id: 'Speed',
data: speed,
yAxis: 1
}, {
color: '#ee4650',
type: 'spline',
name: 'Power',
id: 'Power',
data: power,
yAxis: 2
}]
});
.header {
padding: 20px 20px 10px 0px;
width: 100%;
display: flex;
font-size: 16px;
color: #5e5e5e;
font-family: 'Montserrat Medium', 'Montserrat Regular', 'Montserrat'
}
span {
width: 50%;
font-family: 'Montserrat Medium', 'Montserrat Regular', 'Montserrat'
}
span:last-child {
text-align: right;
}
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://code.highcharts.com/stock/highstock.js"></script>
<script src="https://code.highcharts.com/stock/modules/drag-panes.js"></script>
<script src="https://code.highcharts.com/stock/modules/exporting.js"></script>
<script src="https://code.highcharts.com/stock/indicators/indicators.js"></script>
<script src="https://code.highcharts.com/stock/indicators/volume-by-price.js"></script>
<div class='header'>
<span>
Date: 15/11/2018
</span>
<span>
Thrust: 3079.21 N
</span>
</div>
<div id="container" style="height: 500px; min-width: 310px"></div>
Demo:
API reference:
ADDITION
If you want to make it work with navigator enabled set the same extremes also on navigator xAxis and after that redraw the chart (chart.redraw()
). Notice, that it will work correctly if you have navigator.adaptToUpdatedData = false
.
Code:
chart: {
events: {
load: function() {
var chart = this,
offset = 15000,
multiplier,
dataLength,
x,
y,
min,
max;
setInterval(function() {
chart.series.forEach(function(series) {
multiplier = series.dataMax;
dataLength = chart.series[0].xData.length;
x = chart.series[0].xData[dataLength - 1] + 1000;
y = Math.round(Math.random() * multiplier);
series.addPoint([x, y], false, true);
});
min = chart.xAxis[0].userMin || null;
min = min < chart.xAxis[0].dataMin ? null : min;
max = x + offset;
chart.xAxis[0].setExtremes(min, max, false);
chart.navigator.xAxis.setExtremes(min, max, false);
chart.redraw();
}, 1000);
}
}
}
Demo:
API reference: