The problem I am encountering, is that I want to add 1 extra line (maybe more later) to this dynamic chart, but only one line is updating, that is to say I want to have two different lines updating with different random data on Y axis?
This is the example I am working on, click here.
This is the code that I have wrote, if you want to see my problem then copy and paste this code in the link above.
$(function () {
Highcharts.setOptions({
global : {
useUTC : false
}
});
// Create the chart
$('#container').highcharts('StockChart', {
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);
}
}
},
rangeSelector: {
buttons: [{
count: 1,
type: 'minute',
text: '1M'
}, {
count: 5,
type: 'minute',
text: '5M'
}, {
type: 'all',
text: 'All'
}],
inputEnabled: false,
selected: 0
},
title : {
text : 'Live random data'
},
exporting: {
enabled: false
},
series : [{
name : 'diagram1',
data : (function () {
// generate an array of random data
var data1 = [], time = (new Date()).getTime(), i;
for (i = -999; i <= 0; i += 1) {
data1.push([
time + i * 1000,
Math.round(Math.random() * 100)
]);
}
return data1;
}())
},
{
name : 'diagram2',
data : (function () {
// generate an array of random data
var data2 = [], time = (new Date()).getTime(), i;
for (i = -999; i <= 0; i += 1) {
data2.push([
time + i * 1000,
Math.round(Math.random() * 100)
]);
}
return data2;
}())
}]
});
});
In your chart load event just add another interval for second series.
To prevent code duplication you can store all your data in one object and iterate throu it.
Here is fiddle.
$(function () {
Highcharts.setOptions({
global : {
useUTC : false
}
});
// Create the chart
$('#container').highcharts('StockChart', {
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);
/* second series update code */
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);
}
}
},
rangeSelector: {
buttons: [{
count: 1,
type: 'minute',
text: '1M'
}, {
count: 5,
type: 'minute',
text: '5M'
}, {
type: 'all',
text: 'All'
}],
inputEnabled: false,
selected: 0
},
title : {
text : 'Live random data'
},
exporting: {
enabled: false
},
series : [{
name : 'diagram1',
data : (function () {
// generate an array of random data
var data1 = [], time = (new Date()).getTime(), i;
for (i = -999; i <= 0; i += 1) {
data1.push([
time + i * 1000,
Math.round(Math.random() * 100)
]);
}
return data1;
}())
},
{
name : 'diagram2',
data : (function () {
// generate an array of random data
var data2 = [], time = (new Date()).getTime(), i;
for (i = -999; i <= 0; i += 1) {
data2.push([
time + i * 1000,
Math.round(Math.random() * 100)
]);
}
return data2;
}())
}]
});
});
You can use foreach ;
$(function () {
Highcharts.setOptions({
global : {
useUTC : false
}
});
// Create the chart
$('#container').highcharts('StockChart', {
chart : {
events : {
load : function () {
// set up the updating of the chart each second
var series = this.series;
series.forEach(function(serie) {
setInterval(function () {
var x = (new Date()).getTime(), // current time
y = Math.round(Math.random() * 100);
serie.addPoint([x, y], true, true);
}, 1000);
});
}
}
},
rangeSelector: {
buttons: [{
count: 1,
type: 'minute',
text: '1M'
}, {
count: 5,
type: 'minute',
text: '5M'
}, {
type: 'all',
text: 'All'
}],
inputEnabled: false,
selected: 0
},
title : {
text : 'Live random data'
},
exporting: {
enabled: false
},
series : [{
name : 'diagram1',
data : (function () {
// generate an array of random data
var data1 = [], time = (new Date()).getTime(), i;
for (i = -999; i <= 0; i += 1) {
data1.push([
time + i * 1000,
Math.round(Math.random() * 100)
]);
}
return data1;
}())
},
{
name : 'diagram2',
data : (function () {
// generate an array of random data
var data2 = [], time = (new Date()).getTime(), i;
for (i = -999; i <= 0; i += 1) {
data2.push([
time + i * 500,
Math.round(Math.random() * 50)
]);
}
return data2;
}())
}]
});
});
This works for me, now I can have two dynamic lines. Is there a way I can add more dynamic charts without needing to dublicate setInterval etc, you can see the point below.
// 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);
/* second series update code */
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);
/* third series update code */
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);
/* fourth series update code */
var series3 = this.series[3];
setInterval(function () {
var x = (new Date()).getTime(), // current time
y = Math.round(Math.random() * 100);
series3.addPoint([x, y], true, true);
}, 1000);
Related
I have some data that I'm graphing with Highcharts, which I was able to set up by using a modified version of some demo code. The graph works fine when I graph some data from a sensor. The relevant section of my code looks like this:
<script>
Highcharts.stockChart('container', {
chart: {
backgroundColor:'transparent',
events: {
load: function() {
var series = this.series[0];
setInterval(function() {
var x = (new Date()).getTime(),
y = Number(getTemp());
series.addPoint([x, y], true, true);
}, 1000);
}
}
},
xAxis: {
type: 'datetime',
labels: {
style: {
},
},
tickPixelInterval: 200,
},
yAxis: {
type: 'linear',
labels: {
y: 5,
style: {
},
},
},
series: [{
name: 'Temperature',
data: (function () {
var data = [],
time = (new Date()).getTime(),
i;
for (i = -200; i <= 0; i += 1) {
data.push({
x: time + i * 1000,
y: 0
});
}
return data;
}())
}]
});
</script>
Now I want to add a second sensor reading using a similar function "getTemp2()" on the same graph as a second series. When I try to edit the code in the "series" data section, I get a blank graph (meaning it fails to load correctly). I believe the code in the "series" section populates the graph with zeros (for y values) across the entire chart. But I'm not sure if I need to add both something in the "events" section, the "series" section, or both? Can someone tell me how I can add a second sensor reading to this chart? Here is what I tried that failed:
events: {
load: function() {
var series = this.series[0];
setInterval(function() {
var x = (new Date()).getTime(),
y = Number(getTemp());
series.addPoint([x, y], true, true);
},
var series = this.series[0];
setInterval(function() {
var x = (new Date()).getTime(),
y = Number(getTemp2());
series.addPoint([x, y], true, true);
}, 1000);
}
First of all, you need to create two series in a chart configuration object:
Highcharts.stockChart('container', {
...,
series: [{
data: getData()
}, {
data: getData()
}]
});
Then, in load event you can use addPoint method on both of the series:
chart: {
events: {
load: function() {
var series1 = this.series[0],
series2 = this.series[1];
setInterval(function() {
var x = (new Date()).getTime(),
y1 = Number(getTemp()),
y2 = Number(getTemp2());
series1.addPoint([x, y1], false, true);
series2.addPoint([x, y2], true, true);
}, 1000);
}
}
}
Live demo: http://jsfiddle.net/BlackLabel/nk4yawzt/
API Reference: https://api.highcharts.com/class-reference/Highcharts.Series#addPoint
Docs: https://www.highcharts.com/docs/chart-concepts/series
I am using highcharts on a project, I am having trouble with the creation of multiple series of data updating dynamically generating a column chart, my aim is to keep all the series at a static position and change according to the data.
Till now i have achieved this : https://jsfiddle.net/jk05qcq4/
Highcharts.chart('container', {
chart: {
type: 'column',
backgroundColor: null,
animation: Highcharts.svg, // don't animate in old IE
marginRight: 10,
events: {
load: function() {
var iter = 0;
// set up the updating of the chart each second
var series = this.series[0];
var series2 = this.series[1];
var series3 = this.series[2];
var series4 = this.series[3];
var series5 = this.series[4];
var series6 = this.series[5];
myInterval = setInterval(function() {
var len = Object.keys(BleedEnthalpy).length;
var len2 = Object.keys(BypassRatio).length,
x = new Date().getTime();
if (iter < len) {
series.addPoint([x, BleedEnthalpy[iter]], false, true);
series2.addPoint([x, BypassRatio[iter]], false, true);
series3.addPoint([x, CorrCoreSpeed[iter]], false, true);
series4.addPoint([x, CorrFanSpeed[iter]], false, true);
series5.addPoint([x, FuelFlowRatio[iter]], false, true);
series6.addPoint([x, HPCOutletTemp[iter]], true, true);
iter++;
} else {
clearInterval(myInterval);
}
}, 1000);
}
}
},
title: {
text: null
},
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, 4);
}
},
legend: {
enabled: true
},
exporting: {
enabled: false
},
rangeSelector: {
enabled: false
},
navigator: {
enabled: false
},
scrollbar: {
enabled: false
},
series: [{
name: 'R data',
data: (function() {
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;
for (i = -19; i <= 0; i += 1) {
data.push({
x: time + i * 1000,
y: BleedEnthalpy
});
}
return data;
}())
}, {
name: 'Bypass ratio',
maxPointWidth: 90,
data: (function() {
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;
for (i = -19; i <= 0; i += 1) {
data.push({
x: time + i * 1000,
y: BypassRatio
});
}
return data;
}())
},
{
name: 'CorrCoreSpeed',
data: (function() {
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;
for (i = -19; i <= 0; i += 1) {
data.push({
x: time + i * 1000,
y: CorrCoreSpeed
});
}
return data;
}())
},
{
name: 'CorrFanSpeed',
data: (function() {
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;
for (i = -19; i <= 0; i += 1) {
data.push({
x: time + i * 1000,
y: CorrFanSpeed
});
}
return data;
}())
},
{
name: 'FuelFlowRatio',
data: (function() {
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;
for (i = -19; i <= 0; i += 1) {
data.push({
x: time + i * 1000,
y: FuelFlowRatio
});
}
return data;
}())
},
{
name: 'HPCOutletTemp',
data: (function() {
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;
for (i = -19; i <= 0; i += 1) {
data.push({
x: time + i * 1000,
y: HPCOutletTemp
});
}
return data;
}())
}
]
});
I solved the answer by reducing the size of the for loop from -19 to 0 for all the series:
{
name: 'HPCOutletTemp',
data: (function() {
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;
for (i = 0; i <= 0; i += 1) {
data.push({
x: time + i * 1000,
y: HPCOutletTemp
});
}
return data;
}())
}
check the fiddle for more understanding : https://jsfiddle.net/qkdwu3p3/
Here I'm working on Highcharts time series chart with live streaming data, based on the sample jsfiddle. In the fiddle there shows 4 lines named as input1, input2, input3, & input 4 and it is updated with live random data but in my actual project the input values are updated via MQTT. Here I am adding points to chart with series[i].addPoint() method.I want to add some markers or symbols along with line if the value exceed a particular limit.
$(function() {
$(document).ready(function() {
Highcharts.setOptions({
global: {
useUTC: false
}
});
$('#container').highcharts({
chart: {
type: 'spline',
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;
var length = series.length;
setInterval(function() {
var x = (new Date()).getTime(), // current time
a0 = Math.random();
a1 = Math.random();
a2 = Math.random();
series[0].addPoint([x, Math.random()], true, true);
for (var i = 1; i < length; i++) {
series[i].addPoint([x, Math.random()], false, true);
}
}, 1000);
}
}
},
title: {
text: 'Live random data'
},
legend: {
enabled: true
},
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);
}
},
exporting: {
enabled: false
},
series: [{
name: 'input1',
data: (function() {
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;
for (i = -19; i <= 0; i += 1) {
data.push({
x: time + i * 1000,
y: Math.random()
});
}
return data;
}())
}, {
name: 'input2',
data: (function() {
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;
for (i = -19; i <= 0; i += 1) {
data.push({
x: time + i * 1000,
y: Math.random()
});
}
return data;
}())
}, {
name: 'input3',
data: (function() {
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;
for (i = -19; i <= 0; i += 1) {
data.push({
x: time + i * 1000,
y: Math.random()
});
}
return data;
}())
}, {
name: 'input4',
data: (function() {
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;
for (i = -19; i <= 0; i += 1) {
data.push({
x: time + i * 1000,
y: Math.random()
});
}
return data;
}())
}]
});
});
});
Use setState() method and utilize the tooltip. Then you can style the tooltip or the circle that encloses a point in focus with the API for the tooltip and have the styles or the tooltip symbol/html change according to the value on the chart with conditional statements.
See this answer: Highcharts - manually trigger hover event on a point
I have done a line chart and it is working perfectly, except it does not have additional function that a stockchart has.
However I am facing an issue where by,
1) my data does not shows at all but the timing is correct.
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script src="https://code.highcharts.com/stock/highstock.js"></script>
<script src="https://code.highcharts.com/stock/modules/exporting.js"></script>
<div id="container" style="height: 400px; min-width: 310px"></div>
<script>
var numX = [];
var time = [];
var i = 0;
var url = 'ws://127.0.0.1:8080/';
var ws = new WebSocket(url, 'echo-protocol');
ws.onmessage = function(evt)
{
console.log(evt.data);
var data = evt.data;
data = JSON.parse(data);
var x = data.position_x;
numX[i] = x;
time[i] = data.timestamp;
i++;
updateChart();
};
function updateChart()
{
$(function ()
{
Highcharts.setOptions
({
global :
{
useUTC : false
}
});
// Create the chart
$('#container').highcharts('StockChart',
{
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 = 0;//Math.round(Math.random() * 100);
series.addPoint([x, y], true, true);
//}, 1000);
}
}
},
rangeSelector:
{
buttons:
[{
count: 1,
type: 'minute',
text: '1M'
},
{
count: 5,
type: 'minute',
text: '5M'
},
{
type: 'all',
text: 'All'
}],
inputEnabled: false,
selected: 0
},
title :
{
text : 'Live Coordinate X data'
},
exporting:
{
enabled: false
},
series :
[{
name : 'Random data',
data :
(function ()
{
// generate an array of random data
var data = [], time = (new Date()).getTime(), i;
for (i = -999; i <= 0; i += 1)
{
data.push
([
time,
Math.round(numX)
]);
}
return data;
}())
}]
});
});
}
</script>
I am developing a dashboard, where there are 5 buttons, and on click of each button, corresponding chart is displayed in the same div.
The structure of my code is as follows :
$(document).ready(function(){
$("button").click(function(){
function requestData() {
$.ajax({
url : ....,
success : function(){
.....
//Real Time Plotting of Data
chart.series[0].addPoint(eval(point), true, shift);
setTimeout(requestData, 2000);
}
});
}
chart = new Highcharts.Chart({
chart: {
renderTo: 'chart',
defaultSeriesType: 'spline'
},
....
....
});
});
});
The Problem : On every click of the button, a parallel requestData() starts, multiple parallel threads run at the same time. This leads in random addPoint and increase in memory consumed.
Also, when checked with Highcharts.Chart in the console, after every click, a undefined objects adds up.
How do I restructure the code for optimum performance ?
Refer the code below, your high chart implement can be like this
$(function () {
$(document).ready(function () {
$('#container').highcharts({
chart: {
type: 'spline',
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 x = (new Date()).getTime(), // current time
y = Math.random();
series.addPoint([x, y], true, true);
}, 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 += 1) {
data.push({
x: time + i * 1000,
y: Math.random()
});
}
return data;
}())
}]
});
});
});
Basically, you do not need to make your arrangement to live plotting, high chart has this option UPDATE
Refer live fiddle
http://jsfiddle.net/anilk/3u0ng35s/
Replace below data option to your ajax call
data: (function () {
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;
for (i = -19; i <= 0; i += 1) {
data.push({
x: time + i * 1000,
y: Math.random()
});
}
return data;
}