Plot graph points as a live stream : Highcharts - javascript

So What I have is a graph which updates particular points as once. But the problem is that the graph is not being plotted as a live stream. it just plots points at once
Here is the Code:
var chart;
function requestData() {
$.ajax({
url: 'https://api.myjson.com/bins/wmxsn',
success: function(data) {
var series = chart.series[0],
shift = series.data.length > 20, // shift if the series is
y = data;
data.forEach(function(el) {
chart.series[0].addPoint(el, false, shift);
});
chart.redraw();
setTimeout(requestData, 1000);
},
cache: false
});
}
document.addEventListener('DOMContentLoaded', function() {
chart = Highcharts.chart('container', {
chart: {
type: 'line',
events: {
load: requestData
}
},
title: {
text: 'Live random data'
},
xAxis: {
crosshair: false
},
yAxis: {
minPadding: 0.2,
maxPadding: 0.2,
title: {
text: 'Value',
margin: 80
}
},
series: [{
name: 'Random data',
data: []
}]
});
});
Here's the Fiddle Example of how data points are plotting.
http://jsfiddle.net/abnitchauhan/g86tbydj/
But what I want is the flow to be smooth as like the following example:
(It's just an example of how the data should flow irrespective of the code. Please only see the graph animation in the following code)
https://codepen.io/AbnitChauhan/pen/BaBxyMV

The problem is that you are fetching data, add points and redraw the chart when all points are added. To make it "live" and smooth add points separately in the equal interval. If the interval is very small disable the animation which makes it work better (chart.animation = false). Check demos posted below.
Example code:
function requestData() {
$.ajax({
url: 'https://api.myjson.com/bins/wmxsn',
success: function(data) {
var series = chart.series[0],
shift = series.data.length > 200, // shift if the series is
y = data,
i = 0;
var interval = setInterval(function () {
if (i < 10) {
chart.series[0].addPoint(data[i] * Math.random() * 10, true, shift);
i++
} else {
clearInterval(interval);
requestData();
}
}, 30);
},
cache: false
});
}
Demo:
http://jsfiddle.net/BlackLabel/cuxr865g/
http://jsfiddle.net/BlackLabel/jdvm4u2o/
API reference:
https://api.highcharts.com/highcharts/chart.animation

Related

Chart update everytime on Loading second array : Highcharts, Javascript

So, What I have is a condition in a MySQL to show the first 1000 data points first and then the other 2000 datapoints after that in Highcharts.
if lastindex==0:
cur.execute("SELECT data,value FROM table where id<1001")
else:
cur.execute("SELECT data,value FROM table where id>1001 and id<3000")
data = cur.fetchall()
//python Code to fetch SQL data
Now what I am doing is that I am rendering that data into the Highcharts, the data is being rendered. but the problem arises that after showing the first 1000 data points, the Highcharts value starts from 0 and then shows the other 2000 points
the data is not displaying continuously as it should plot the send array data just after the end of the first data.
I think the Highcharts is being called Twice, What can I do to append the 2nd set of data to the first set without reloading the whole chart.
Here's a snip of my Highchart's js
Highcharts.chart("chartcontainer", {
chart: {
type: 'line',
animation: Highcharts.svg, // don't animate in old IE
marginRight: 10,
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;
}())
}]
});
What I want is just to append the event data rather than loading the whole chart.
How can I reload a particular Highchart value without reloading the whole chart ?
What do you think about updating the current series with new data, which will be an array of old data merged with the new one?
chart: {
events: {
load(){
let chart = this,
currentSeries = chart.series[0],
newData;
newData = [...currentSeries.userOptions.data, ...data1]
setTimeout(()=> {
chart.series[0].update({
data: newData
})
}, 5000)
}
}
},
See the demo

How to display two dynamic spline charts on one page?

I just learned about creating dynamic charts using highcharts. I need help, i'm trying to make a dynamic spline chart with data from php like this (number 2). Then I try to create a dynamic spline chart under it (different div) by varying the data in php. But the results only show the chart below (chart B), on chart A does not display data as before B chart added. I asked, how to make two dynamic spline charts on one page? thank you
This is the code that I use
<?php //PHP for Chart A
// Set the JSON header
header("Content-type: text/json");
// The x value is the current JavaScript time, which is the Unix time multiplied
// by 1000.
$x = time() * 1000;
// The y value is a random number
$y = rand(0, 100);
// Create a PHP array and echo it as JSON
$ret = array($x, $y);
echo json_encode($ret);
?>
<?php //PHP for Chart B
// Set the JSON header
header("Content-type: text/json");
// The x value is the current JavaScript time, which is the Unix time multiplied
// by 1000.
$x = time() * 1000;
// The y value is a random number
$y = rand(100, 200);
// Create a PHP array and echo it as JSON
$ret = array($x, $y);
echo json_encode($ret);
?>
this is javascript code:
//JS of Chart A
var chart;
function requestData() {
$.ajax({
url: 'dataChartA.php',
success: function(point) {
var series = chart.series[0],
shift = series.data.length > 20; // shift if the series is
// longer than 20
// add the point
chart.series[0].addPoint(point, true, shift);
// call it again after one second
setTimeout(requestData, 1000);
},
cache: false
});
}
document.addEventListener('DOMContentLoaded', function() {
chart = Highcharts.chart('chartA', {
chart: {
type: 'spline',
events: {
load: requestData
}
},
title: {
text: 'Chart A'
},
xAxis: {
type: 'datetime',
tickPixelInterval: 150,
maxZoom: 20 * 1000
},
yAxis: {
minPadding: 0.2,
maxPadding: 0.2,
title: {
text: 'Value',
margin: 80
}
},
series: [{
name: 'Chart A',
data: []
}]
});
});
//JS for Chart B
var chart;
function requestData() {
$.ajax({
url: 'dataChartB.php',
success: function(point) {
var series = chart.series[0],
shift = series.data.length > 20; // shift if the series is
// longer than 20
// add the point
chart.series[0].addPoint(point, true, shift);
// call it again after one second
setTimeout(requestData, 1000);
},
cache: false
});
}
document.addEventListener('DOMContentLoaded', function() {
chart = Highcharts.chart('chartB', {
chart: {
type: 'spline',
events: {
load: requestData
}
},
title: {
text: 'Chart B'
},
xAxis: {
type: 'datetime',
tickPixelInterval: 150,
maxZoom: 20 * 1000
},
yAxis: {
minPadding: 0.2,
maxPadding: 0.2,
title: {
text: 'Value B',
margin: 80
}
},
series: [{
name: 'Chart B',
data: []
}]
});
});
</head>
<body>
<div id="chartA"></div>
<div id="chartB"></div>
</body>
Results in the browser : https://imgur.com/kAVGQUk

HighCharts with Dynamic Data not working

I have a ASP.NET MVC project with SignalR.
I have a page with a HighChart and the script looks like this:
$(function () {
window.Highcharts.setOptions({
global: {
useUTC: false
}
});
var chart;
$(document).ready(function () {
chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'line',
marginRight: 10
},
title: {
text: 'GMAS Queues'
},
xAxis: {
type: 'datetime',
tickInterval: 500,
labels: {
enabled: false
}
},
yAxis: {
title: {
text: 'Queue Count'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
legend: {
enabled: false
},
exporting: {
enabled: false
},
series: [{
name: 'Processing Queues'
}]
});
});
$.connection.hub.logging = true;
// Reference the auto-generated proxy for the hub.
var chartData = $.connection.processingQueuesHub;
// Create a function that the hub can call back to display messages.
chartData.client.updateQueueCounts = function (data) {
//$.each(data, function(i, item) {
// // Add the message to the page.
// $('#chartDataLog').append('<li><strong>' + htmlEncode(item.QueueName)
// + '</strong>: ' + htmlEncode(item.Length) + '</li>');
//});
// set up the updating of the chart.
var series = chart.series[0];
$.each(data, function (i, item) {
if (item.QueueName == "Queue A") {
var x = Date.parse(item.Date),
y = item.Length;
series.addPoint([x, y], true, false);
}
});
};
However, I see the graph but not the points.
The strange part is the series data points are there:
Anyone know why HighCharts is not rendering the points?
Thanks, Bill N
I have to thank my good friend and co developer for figuring this out. He is a smarter and braver man than me. :) He went to the highcharts source and found that the highcharts breaks if you add to the graph series before the initial animation is completed. The animation is why the clip-rect is zero-width (it animates from zero to full width over 1s when you first create the chart). You end up adding a point to the series before this animation even really starts. This kills the animation but it doesn’t fix the width of the clip-rect. The fix is to add animation is false for the series.
series: [{ name: 'Processing Queues', data: [], animation: false }]
It looks like you are not defining what your chart.series is until it is created. The line in your ajax is as follows and its not waiting for DOM ready:
var series = chart.series[0];
But you do not define chart until $(document).ready(function () {.... Try keeping your chart object in scope of your ajax.

HighCharts - dynamic graph & no tick mark on the right hand side dual axis

I'm new to high charts.
I'm dynamically making 2 ajax calls(inside getData() Function) and plotting the high chart with 2 series(with 2 y axis).
each ajax call with return the json data.
1st json data (sample)
[{"dt":"May 15, 2000","index":"2,007.030850"},{"dt":"May 16, 2000","index":"2,025.956108"}]
2nd json data (sample)
[{"dt":"May 15, 2000","nav":"145.236000"},{"dt":"May 16, 2000","nav":"146.602974"}]
I'm creating two series with 2 ajax calls. in the 2nd ajax call, i'm dynamically adding a y-axis for the 2nd series data.
$(document).ready(function() {
function getData() {
var chart = Highcharts.charts[0];
/* 1st Ajax Call to get the json data to plot the first series */
$.ajax({
type: 'POST',
dataType: 'json',
url: '/Six/TSServlet?file=ivv-sixIshareFundsHistoryIndex.json',
data: '',
async: false,
success: function(data) {
var categories1 = [];
var seriesData1 = [];
var yaxis;
$.each(data, function(i, e) {
categories1.push(e.dt);
/* below step to remove , is not important, done for my program */
yaxis = parseFloat(e.index.replace(/,/g, ''));
seriesData1.push(yaxis);
})
// add x-axis catagories
chart.xAxis[0].update({
categories: categories1,
tickInterval: 150
}, true);
// add the 1st series
chart.series[0].setData(seriesData1);
}
});
/* 2nd Ajax Call to get the json data to plot the second series */
$.ajax({
type: 'POST',
dataType: 'json',
url: '/Six/TSServlet?file=ivv-sixIshareFundsHistoryNav.json',
data: '',
async: false,
success: function(data) {
var categories2 = [];
var seriesData2 = [];
var yaxis;
$.each(data, function(i, e) {
categories2.push(e.dt);
/* below step to remove , is not important, done for my program */
yaxis = parseFloat(e.nav.replace(/,/g, ''));
seriesData2.push(yaxis);
})
/* This is the problem area, dynamically adding a dual y axis for the 2nd series */
chart.addAxis({ // Secondary yAxis
id: 'NAV-Series-Axis',
title: {
text: 'NAV Series'
},
lineWidth: 2,
lineColor: '#08F',
opposite: true
});
// add the 2nd series
chart.addSeries({name: "NAV Series",yAxis: 'NAV-Series-Axis',data: seriesData2});
}
});
} //getdata function ends here .............
Highcharts.setOptions({
global: {
useUTC: false
}
});
var chart;
$('#container').highcharts({
chart: {
type: 'spline',
animation: Highcharts.svg, // don't animate in old IE
marginRight: 10,
renderTo: 'container',
events: {
load: function() {
var series = this.series[0];
getData();
}
}
},
title: {
text: 'Six Share Funds History'
},
labels: {
formatter: function() {
return this.value + ' %';
}
},
xAxis: {
tickLength: 10
},
tooltip: {
formatter: function() {
return '<b>' + this.series.name + '</b><br/>' + this.x + '<br/>' + Highcharts.numberFormat(this.y, 2);
}
},
legend: {
enabled: false
},
exporting: {
enabled: false
},
series: [{
"Name": []
}]
});
});
});
My issue is i'm getting 2 axis for 2 series graph, but no tick marks on the right hand side y-axis. how to solve this issue? ideally i should see 100(one tick mark), 200 (one tick mark) etc on the right hand side blue bar(just like left hand side y-axis has 500,1000 etc)
Please see the screen shot, i dont see the tick marks on the right hand side blue bar (for the 2nd series graph)
Edited to add jsp:
<div id='TimeSeriesId'>
<div id="container" style="width: 100%; height: 600px;"></div>
</div>
You can add several Y-axes simply by making yAxis an array with more than 1 element. Each can have all of the usual axis attributes (see highcharts API).
yAxis: [{ // Primary yAxis
labels: { ...
},
title: { ...
},
opposite: true
}, { // Secondary yAxis
title: { ...
},
labels: { ...
}
}, { // Tertiary yAxis
title: { ...
},
labels: { ...
},
opposite: true
}],
...
To dynamically add them, use chart.yAxis = new Array(); chart.yAxis[1].title = ... etc.

How to format Highcharts columnRange to get json data for temperature Min and Max

I'm trying to display information on Highcharts from the forecast.io api. With the help of others on this site, I have figured out how to call the data using a simple line or area chart; however, I can't figure out how to with the columnRange chart. I want to display the daily min and max temperature forecast. So the top column would display today's min and max temp, and the next column would be tomorrows, and so on.
To call the min and max for today from forecast.io:
data.daily.data[0].temperatureMin
data.daily.data[0].temperatureMax
Tomorrows would have a "1" instead of a 0. The day after would have a "2".
I haven't been able to figure out how to make a function that does this for each day. I have a jsfiddile which includes my forecast.io API key. This is needed to call from the source.
Anyways, any help would be much appreciated! http://jsfiddle.net/nn51895/gjw9m1qo/2/
(my x axis labels are really messed up as you will see..)
$(function () {
$('#container').highcharts({
chart: {
type: 'columnrange',
inverted: true
},
title: {
text: ''
},
subtitle: {
text: ''
},
xAxis: {
},
yAxis: {
title: {
text: ''
}
},
tooltip: {
valueSuffix: '°F'
},
plotOptions: {
columnrange: {
dataLabels: {
enabled: true,
formatter: function () {
return this.y + '°F';
}
}
}
},
legend: {
enabled: false
},
series: [{
name: 'Daily Min and Max',
data: 'ChartData',
pointStart: new Date().getTime(),
pointInterval:90000000,
}]
});
});
$.ajax({
url: "https://api.forecast.io/forecast/87a7dd82a91b0b765d2576872f2a3826/53.479324,-2.248485",
jsonp: "callback",
dataType: "jsonp",
success: function(chart) {
var dataArr = new Array();
var height = chart.xAxis[0].height;
var pointRange = chart.daily.data[0].temperatureMax - chart.daily.data[0].temperatureMin;
var max = chart.daily.data[0].temperatureMax;
var min = chart.daily.data[0].temperatureMin;
var pointCount = (max - min) / pointRange;
var timeint = chart.daily.data[0].time;
for(var i=0; i<chart.daily.data.length; i++)
dataArr.push(chart.daily.data[i].temperatureMin);
plotChart(dataArr, timeint)
}
});
First of all, as said in the comment:
success: function (chart) {
...
var height = chart.xAxis[0].height;
}
You are trying to get for some unknown reason height of xAxis from the chart. Meanwhile you chart variable is referring to the data from AJAX call. I hope that's clear, so remove that line or change to:
success: function (chart) {
var myChart = $('#container').highcharts();
var dataArr = new Array();
var height = myChart.xAxis[0].height;
}
Second thing, that option:
data: 'ChartData',
Is wrong, there should be an empty array, since Highcharts requires array for data, not some string:
data: [],
Now, after fixing these bugs, you should go to this demo and create the same data format. That's example for required format for Highcharts.
More about series.data can be found in API reference - you need to read this.

Categories

Resources