Highcharts: dynamically updating chart per click of a button - javascript

Note: I have already read this question: Highcharts - Dyanmic graph with no initial data
And the effect I want to achieve is similar to this: http://jsfiddle.net/7vZ5a/40/. However, instead of updating every second, I would like it to update per click of a button. This is what I get so far:
http://jsfiddle.net/7vZ5a/49/
$(function() {
var chartData = [50, 60, 70, 100, 120, 200];
var timeStamps = [];
var index = 1;
$('#b').click(function() {
timeStamps.push(new Date());
var buttonB = document.getElementById('b');
buttonB.disabled = true;
if (index < chartData.length) {
setTimeout(function() {
if (index == 1) {
$('#container').highcharts().series[0].addPoint([0, chartData[0]], true, false);
$('#container').highcharts().series[0].addPoint([index, chartData[index]], true, false);
} else {
$('#container').highcharts().series[0].addPoint([index, chartData[index]], true, true);
index++;
}
}, 1000);
}
if (index < chartData.length - 1) {
setTimeout(function() {
buttonB.disabled = false;
}, 1500);
} else {
setTimeout(function() {
buttonB.style.visibility = "hidden";
}, 1500);
}
if (index == chartData.length - 2) {
setTimeout(function() {
document.getElementById('b').innerHTML = 'Letzte Ziehung';
}, 1000);
}
console.log(timeStamps);
})
Highcharts.setOptions({
lang: {
decimalPoint: ','
},
});
$('#container').highcharts({
chart: {
type: 'line',
marginBottom: 60
},
colors: [
'#0000ff',
],
title: {
text: ''
},
xAxis: {
title: {
text: 'Time',
offset: 23
},
min: 0,
max: 1,
tickInterval: 1,
gridLineWidth: 1
},
yAxis: {
title: {
text: 'Value'
},
min: 0,
max: 200
},
plotOptions: {
line: {
marker: {
enabled: false
}
}
},
tooltip: {
formatter: function() {
return Highcharts.numberFormat(this.y, 2) + 'GE';
}
},
legend: {
enabled: false
},
exporting: {
enabled: false
},
credits: {
enabled: false
},
series: [{
name: '',
data: []
}]
});
});
Why (almost) the same code could work on the case when the chart update automatically but not on the case when the update is triggered by click?
(I also tried the function with the code controlling update not in "setTimeout" block, it also did not work.)

What you want to do is create a function that adds data to a series, like:
function addData(series, data) {
series.addPoint([series.length, data], true, false);
}
This for example adds a new point with value data to the end of series (indexed series.length, which is one index higher than the last index of the series).
Then you can bind this function to the click event of your button:
$('#add-random-data').on('click', function () {
addData(chart.series[0], Math.random());
});
This adds a random value between 0 and 1 to the series. It is assumed that the chart is stored in a variable named chart, and series[0] is the series of that chart that you want to add the data to.
This fiddle shows this on the given example chart.
The reason why your code doesn't work is that you set min and max of your x-axis, as pointed out in the comments. That way the chart won't plot data that is indexed outside of your limits. You can just let the chart auto-scale its axes by removing the min and max properties. If you want the values to always be between 0 and 1 on the x-axis, you have to overwrite the points with index 0 and 1 in your series.

Related

Render chart only once with multiple events : Highcharts

So what I have is a chart in which I have events function which loads data for multiple sets.
suppose I have data of 3000 points. The first data set renders the first 1000 points and after that second data set renders 2000 points.
for which I am calling my 'events' function .
but the problem arises that after showing the first 1000 set of data. The chart starts from the begining.
I don't want that.
That's why I need a solution so that my Highchart's chart render only once and the event function loads continuously.
Here's a snip of my Highchart's js
Highcharts.chart("chartcontainer", { // make thsi chart load only once.
chart: {
type: 'line',
animation: Highcharts.svg, // don't animate in old IE
marginRight: 10,
//Load this event function as the data updates
events: {
load: function() {
var series = this.series[0],
chart = this;
setInterval(function() {
//some logic regarding the chart
//..
v = {
y: y,
x: x
};
console.log("V value", v);
series.addSeries(v, false, true);
counter++;
localcounter++;
} else
{
oldcounter=counter;
flagToreload=1;
}
}, 1000/130);
setInterval(function() {
chart.redraw(false);
}, 100);
}
}
},
time: {
useUTC: false
},
title: {
text: 'Live random data'
},
xAxis: {
type: 'Value',
gridLineWidth: 1
},
yAxis: {
title: {
text: 'Value'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}],
gridLineWidth: 1
},
tooltip: {
headerFormat: '<b>{series.name}</b><br/>',
pointFormat: '{point.x:%Y-%m-%d %H:%M:%S}<br/>{point.y:.2f}'
},
exporting: {
enabled: false
},
series: [{
animation: false,
name: 'Random data',
data: (function() {
// generate an array of random data
var data = [],
time = counter,
i;
for (i = -1000; i <= 0; i += 1) {
data.push([
counter,
null
]);
}
return data;
}())
}]
});
You can use:
addPoint method:
chart: {
events: {
load: function() {
var newData,
chart = this,
series = chart.series[0];
setInterval(function() {
newData = getRandomData();
newData.forEach(function(el) {
series.addPoint(el, false);
});
chart.redraw();
}, 2000);
}
}
}
Live demo: http://jsfiddle.net/BlackLabel/2a8qswhf/
API Reference: https://api.highcharts.com/class-reference/Highcharts.Series#addPoint
setData method:
chart: {
events: {
load: function() {
var newData,
chart = this,
combinedData,
series = chart.series[0];
setInterval(function() {
newData = getRandomData();
combinedData = series.userOptions.data.concat(newData);
series.setData(combinedData);
}, 2000);
}
}
}
Live demo: http://jsfiddle.net/BlackLabel/Lmsk8yw9/
API Reference: https://api.highcharts.com/class-reference/Highcharts.Series#setData

Stop Highchart when end of the Array element reached

So What I am trying to Create is a Chart in which around 130 points data are flowing in a single second time. Now, Suppose I Have an array of 1000 elements which I want to render in Highchart.
I am able to render the Highchart with the 1000 elements of array, but the problem is that after the end of the array, the Highchart is not stopping. it keeps running.
I just want to stop the Highchart when it reaches end of the array.
Here is the Code that I have tried
var data = [7,10,8,6,8,2,5,2,2,2,3,4,4,10,6,10,5,10,0,2,9,5,7,0,5,0,5,7,8,7,5,1,9,1,5,7,10,3,7,0,2,10,8,8,1,1,0,7,6,3,1,10,0,8,3,5,5,10,3,8,4,0,3,5,8,7,0,0,0,8,7,3,2,1,0,6,7,7,3,7,5,0,1,0,0,4,9,4,4,3,0,2,10,9,0,2,7,6,5,9,0,6,7,9,0,6,2,7,1,6,5,1,3,1,0,5,0,4,2,7,2,0,7,0,3,10,6,3,4,9,9,10,10,9,5,9,8,5,3,2,5,9,5,10,10,7,8,3,8,9,5,3,9,0,1,2,6,4,1,9,0,5,0,5,6,4,1,1,3,8,2,0,7,6,4,0,6,5,5,6,4,6,6,3,3,5,5,8,7,3,4,7,5,6,1,4,2,4,7,9,8,4,0,3,8,6,2,6,10,8,10,1,10,8,6,8,8,3,8,7,8,6,7,10,9,10,0,7,7,8,1,10,1,4,7,10,7,0,9,6,3,3,3,1,4,3,4,5,0,5,9,0,6,1,8,5,1,8,9,4,0,4,5,4,3,8,2,10,5,9,4,9,5,3,6,5,7,2,2,7,1,1,9,7,4,1,7,5,2,10,6,4,3,5,7,2,4,5,7,3,2,0,8,5,5,7,8,2,9,5,9,1,2,0,7,8,10,5,6,9,2,5,1,9,4,0,7,4,4,7,10,0,8,6,0,6,4,4,8,3,9,1,3,0,0,4,4,2,5,3,3,6,1,4,6,6,4,9,7,0,2,2,1,2,2,6,2,0,2,5,7,8,8,1,7,3,9,0,0,0,9,4,9,8,9,7,10,8,2,0,5,10,10,0,1,7,5,9,2,8,10,10,4,6,6,6,10,10,5,1,5,2,1,9,3,2,5,3,1,3,10,7,1,3,5,3,0,6,7,5,1,10,5,9,0,9,2,3,0,10,0,6,9,8,3,8,7,0,10,4,2,2,5,6,7,0,10,10,9,9,8,6,10,5,9,0,6,4,8,5,0,4,4,4,1,8,3,0,9,3,3,9,1,5,0,10,1,1,3,10,6,5,8,0,6,5,2,7,10,4,2,0,10,1,7,6,2,0,1,6,10,10,6,6,10,1,4,7,5,6,5,4,1,5,6,9,1,8,4,7,2,8,5,9,7,3,9,2,2,8,10,6,10,10,7,8,7,2,6,8,7,4,6,1,5,9,2,0,5,4,4,0,4,5,7,2,3,8,9,1,0,8,6,10,8,3,7,3,3,6,7,2,7,6,6,2,8,6,9,6,8,5,4,8,4,6,7,9,8,7,8,5,8,2,0,8,5,0,5,2,8,4,7,0,7,1,4,8,10,8,2,5,10,9,1,9,3,0,6,9,2,10,5,1,4,0,4,9,1,1,3,5,0,5,5,2,5,1,1,7,0,2,6,8,10,7,9,3,0,9,4,2,4,6,2,2,9,2,7,3,6,6,9,2,2,0,2,9,1,5,7,10,10,1,8,5,9,9,4,1,7,1,0,0,6,7,7,7,2,9,9,2,10,5,4,2,3,10,9,9,7,1,1,6,8,4,9,6,7,4,9,4,2,7,6,2,6,0,1,5,5,8,9,5,1,7,8,7,3,2,3,1,1,2,5,6,4,10,8,10,3,3,1,0,6,7,0,7,4,8,4,7,6,0,7,1,2,3,10,4,1,10,7,9,4,7,7,10,10,10,6,8,9,7,3,10,9,0,3,6,2,10,5,3,6,8,5,0,2,3,1,6,9,10,9,10,7,5,8,7,4,4,3,10,2,3,4,3,10,8,5,9,8,5,6,2,4,9,1,5,0,7,1,1,4,4,10,4,7,8,8,9,7,1,9,5,5,4,3,0,0,9,5,6,3,3,4,6,1,2,6,2,8,4,10,0,9,1,10,2,7,3,6,3,9,2,3,5,7,8,1,1,9,3,4,6,7,6,2,2,8,0,10,3,3,5,7,4,1,3,9,5,4,3,3,2,9,8,7,8,7,6,8,7,7,1,2,10,10,2,9,3,2,3,2,9,9,0,3,0,4,9,6,0,1,6,9,5,8,7,9,5,6,8,3,5,3,4,9,8,0,3,4,8,6,9,4,7,1,9,8,0,4,8,1,0,7,3,3,1,6,9,9,5,4,3,8,8,9,10,4,9,0,7,8,6,9,8,4,10,4,1,2,5,4,0,6,4,1];
var json_array = data ;
var i = 0;
function next() {
return json_array[i++];
// i++;
}
Highcharts.chart('container', {
chart: {
type: 'line',
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],
chart = this;
var count = 0 ;
setInterval(function() {
var x = (new Date()).getTime(), // current time
y =next();
console.log(y) ;
series.addPoint([x, y], false, true);
chart.redraw(false);
}, 1000/130);
}
}
},
time: {
useUTC: false
},
title: {
text: 'ECG Graph Plot From MySQl Data'
},
xAxis: {
type: 'datetime',
labels: {
enabled: false
},
tickPixelInterval: 150
},
yAxis: {
//max: 1.5,
//min: -1.5,
title: {
text: 'Value'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
tooltip: {
headerFormat: '<b>{series.name}</b><br/>',
pointFormat: '{point.x:%Y-%m-%d %H:%M:%S}<br/>{point.y:.2f}'
},
legend: {
enabled: false
},
exporting: {
enabled: false
},
series: [{
animation: false,
name: 'ECG Graph Plot From MySQl Data',
dataGrouping: {
enabled: false
},
data: (function() {
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;
for (i = -1000 ; i <= 0; i += 1) {
data.push([
time + i * 10,
null
]);
}
return data;
}())
}]
});
I Have also created a Fiddle for it as you can see below.
https://jsfiddle.net/abnitchauhan/toqaxLj7/
Just clear Interval when it reached the last element of the array. check out following code.
var draw = setInterval(function() {
var x = (new Date()).getTime(), // current time
y =next();
console.log(y) ;
if (i == data.length) {
clearInterval(draw);
return;
}
series.addPoint([x, y], false, true);
chart.redraw(false);
}, 1000/130);
here is the fiddle code link.
https://jsfiddle.net/geekcode/8nL53x01/1/

Multiple Charts not moving in sync at random times when adding value on interval

I am trying to create dynamic number of series from UI. Upon selection, backend updates one entry at the time. While the graphs are running fine at most times. At some random time the two series move out of sync as in http://jsfiddle.net/cRgUr/
and come back in sync after few seconds. I have referred following links for resolution but still see the issue.
Chart not moving fluently when adding value to two lines on interval and Updating spline chart two lines on top of eachother
Below is the code snippet :
function getInitialData(series){
var arrayOfValues=[];
$http({
mode:'cors',
method:'GET',
url: '/getData',
headers: { 'Content-Type':'application/json' },
cache: false,
}).success(function(data) {
arrayOfValues.push(/*populated by backend*/); // E.g values for y for number of series selected. If 2 series are to be drawn, at a time this array will contain arrayOfValue[0]= y value for series 1, arrayOfValue[1]=y value for series 2
}
drawgraph(series,arrayOfValues,newWidgetMetrics/*widget selected from UI*/);
} ).error(function(data) {
});
function drawgraph(series,arrayOfValues,newWidgetMetrics1){
var time = (new Date()).getTime();
for(let p=0;p<arrayOfValues.length;p++){
if(p<arrayOfValues.length-1){
series[p].addPoint([time,arrayOfValues[p]] ,false
, (series[0].data.length >= 20));// set false for all series but the last, with an animation where we want the line to start plotting after 20 seconds
}
else{
series[p].addPoint([time,arrayOfValues[p]] , true
, (series[0].data.length >= 20));// set true for only the last series, with an animation where we want the line to start plotting after 20 seconds
}
chart.redraw();
}
arrayOfValues=[];
}
dataSeries=function(){
for(var i=0;i<length;i++){
var obj={};
obj.type="line";
obj.data=getData();
obj.boostThreshold=60;
obj.name=newWidgetLegends[i];
tArray.push(obj);
}
return tArray;
}
func_plot();
function func_plot(){
$(document).ready(function() {
Highcharts.setOptions({
global: {
useUTC: false
}
});
chart=Highcharts.chart(divId, {
chart: {
height:'38%',
zoomType: 'x',
type: 'spline',
animation: Highcharts.svg, // don't animate in old IE
marginRight: 10,
events: {
load: function () {
maxSamples = 60,
counter = 0;
// set up the updating of the chart each second
var ser = this.series;
// setTimeout(function () {
setInterval(function (){
window['arr' + count]=[];
getInitialData(ser);
}, 1000);
}, 2000);
}
}
},
title: {
text: '',
style: {
display: 'none'
}
},
exporting: {
buttons: {
contextButton: {
y:screen.height*-0.02
}
}
},
plotOptions: {
line: {
marker: {
enabled: false
}
},
events: {
legendItemClick: function () {
return false;
}
}
},
xAxis: {
type: 'datetime',
ordinal:false,
labels: {
format: '{value:%M:%S}'
},
tickInterval: 10000,
title: {
text: newWidetXLabel,
marginBottom: 100
}
},
yAxis: {
title: {
text:newWidetYLabel,
min: 0,
max:10
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
legend: {
title: {
text: '',
style: {
fontStyle: 'italic'
}
},
layout: 'horizontal',
align: 'right',
verticalAlign: 'top',
x: -30,
y: -17
},
boost: {
seriesThreshold:2,
useGPUTranslations: true
},
credits: {
enabled: false
},
tooltip: {
formatter: function () {
return Highcharts.dateFormat('%M:%S', this.x) + '<br/>' +
Highcharts.numberFormat(this.y, 2);
}
},
series: dataSeries()
});
});
}
$(window).resize(function() {
height = chart.height,
width = chart.width,
chart.setSize(width, height, doAnimation = false);
});
}
}
}]);
This issue happens because both series are not being drawn at the same moment. Second argument of the addPoint function is a flag that indicates whether the chart should be redrawn immediately after the addition or not. In your code 2 redraws happen instead of one. The update of the second series breaks the animation of the first one (it has no time to finish).
The solution here is to redraw the chart only after the second call of addPoint():
series.addPoint([x, y], false, true);
series2.addPoint([x, y2], true, true);
Live demo: http://jsfiddle.net/kkulig/5y1dacxv/
API reference: https://api.highcharts.com/class-reference/Highcharts.Series#addPoint

Highchart performance slow on plotting live data

I am plotting live data in Highchart's(4.2.4) Line type chart for each second data i.e. 60 points for 1 min. and requirement is to collect each second data for long duration. I am using below code to add point in series. The number of series I have is 20. And for each series I have to add point per second. The turboThreshold set for each series is also around 2000. And slicing should be done after 1000 points data.
chart.series[0].addPoint(point, false, data > 1000?shift: false, false);
I see a very low performance my browser keeps hanging and also chart is very irresponsive after some time. What can I do for better performance? I have tried below stuff:
1) Off the animation for series :
plotOptions: {
series: {
animation:false,
states: {
hover: {
lineWidthPlus: 0
}
}
}
},
2) Turn off animation and redrawing on addpoint to the chart
3) Turn off markers for series
4) Included boost.js module in application
script src="https://code.highcharts.com/modules/boost.js"
Without your actual code I can only speculate what you're doing, but my assumption is you're trying to redraw the chart every time you add a point, that would be 20 redraws per second, which is pretty excessive and will probably take more than 1 second to complete the redraws which means there will be new points added while old ones are still being drawn. Set the redraw to false on adding points and manually redraw every second or at random.
Example code:
$(function() {
var series = function(i) {
return {
name: 'Random data '+i,
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;
}())
};
};
$(document).ready(function() {
Highcharts.setOptions({
global: {
useUTC: false
}
});
$('#container').highcharts({
chart: {
type: 'line',
animation: Highcharts.svg, // don't animate in old IE
marginRight: 10,
events: {
load: function() {
var chart = this;
// set up the updating of the chart each second
setInterval(function() {
for (var i = 0; i < 20; i++) {
var series = chart.series[i];
var x = (new Date()).getTime(), // current time
y = Math.random();
series.addPoint([x, y], false, false,false);
}
chart.redraw();
}, 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);
}
},
exporting: {
enabled: true
},
plotOptions: {
series: {
marker: {
enabled: true
}
}
},
series: [series(1), series(2),series(3), series(4),series(5), series(6),series(7), series(8),series(9), series(10),series(11), series(12),series(13), series(14),series(15), series(16),series(17), series(18),series(19), series(20)]
});
});
});
Fiddle at http://jsfiddle.net/62k8sryc/1/
NOTE
Because this is JavaScript it heavily depends on browser build/version and machine specs.

Highstocks: How to define the span colors of a line instead of the individual line color

I am creating a Gantt Chart using Highstocks(compare multiple series).
1. I want to have the First span color to be Red, the second Blue and third Green.
How can I do the same?
2. how can i set the tooltip to show the values of all the points on the line instead of all points at the time.
3. How to fix y-axis and it should add scroll as values increase.
Please check the Gantt Chart Fiddle here.
var partNumber="2724070125R Planned,2724070125RActual,5511822432R Planned,5511822432RActual";
var partNum = partNumber.split(",");
var ganttData = [
[[Date.UTC(2013,11-1,07),1], [Date.UTC(2013,11-1,29),1], [Date.UTC(2013,11-1,30),1]],
[[Date.UTC(2013,11-1,20),1.25],Date.UTC(2013,11-1,21),1.25],Date.UTC(2013,12-1,21),1.25]],
[[Date.UTC(2013,11-1,13),2],[Date.UTC(2013,12-1,10),2],[Date.UTC(2014,02-1,14),2]],
[[Date.UTC(2013,11-1,21),2.25],[Date.UTC(2013,11-1,21),2.25],[Date.UTC(2013,11-1,30),2.25]]];
$( document ).ready(function(){
$(function() {
var seriesOptions = [],
yAxisOptions = [],
seriesCounter = 0,
names = partNum,
colors = Highcharts.getOptions().colors;
var data=ganttData;
$(function () {
$.each(names, function(i, name) {
seriesOptions[i] = {
// name: data[i][1],
name:name,
step:true,
data: data[i]
};
// 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++;
if (seriesCounter == names.length) {
createChart();
}
});
});
// create the chart when all data is loaded
function createChart() {
Highcharts.setOptions({
global: {
useUTC: false
}
});
$('#ganttChart').highcharts('StockChart', {
chart: {
},
title: {
text: 'PPAP Cumulative Status'
},
rangeSelector: {
selected: 4
},
xAxis: {
type: 'datetime', ordinal: false //this sets the fixed time formats
},
yAxis: {
plotLines: [{
value: 0,
width: 2,
color: 'silver'
}],
min:0 },
plotOptions: {
series: {
lineWidth: 3,
states: {
hover: {
enabled: true,
lineWidth: 3
}
}
}
},
tooltip: {
pointFormat: '<span style="color:{series.color}">{series.name}</span>: <b>{point.y}</b><br/>',
valueDecimals: 0
},
series: seriesOptions,
exporting: {
enabled: false
}
});
}
});
});
1) You can set for series only one color. Here:
$.each(names, function(i, name) {
seriesOptions[i] = {
name: name,
step: true,
data: data[i],
color: 'yourColor'
};
...
});
2) In tooltip, you have access to series via this.points[0].series.data etc. So you can get all points.
3) Scroll is not supported.

Categories