Highcharts : Real time updating spline chart sets y-axis data to zero - javascript

I am trying to display a set of dynamic data in a spline type chart using highcharts.
My spline type line chart has 4 series of data that needs to update through a service call. Service returns an array of data such as [0.345, 0.465, 0, 0.453] and I want to update y value of each series with the respective value in the array.
But my chart does not draw the data as expected. Even if I receive different values for y, in the chart it always displays it as 0.
This is my source code. Greatly appreciate if someone could help me figure out the issue in this or a give solution to this problem.
function drawHighChart() {
hchart = Highcharts.chart('container', {
chart: {
type: 'spline',
animation: Highcharts.svg,
marginRight: 10,
},
time: {
useUTC: false
},
title: {
text: 'Audio Analytics'
},
xAxis: {
tickInterval: 1,
},
yAxis: {
title: {
text: 'Prediction'
},
min: 0,
max: 1,
tickInterval: 0.5,
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
},
/* Initially I'm setting some hardcoded values for each series.*/
series: [{
name: 'Calm',
data: [0.43934, 0.52503, 0.57177, 0.69658, 0.97031, 0.119931, 0.137133]
}, {
name: 'Happy',
data: [0.24916, 0.24064, 0.29742, 0.0000, 0.32490, 0.0000, 0.38121]
}, {
name: 'Angry',
data: [0.11744, 0.17722, 0.16005, 0.19771, 0.20185, 0.24377, 0.32147]
}, {
name: 'Disgust',
data: [0.7988, 0.15112, null, 0.22452, 0.34400, null, 0.34227]
}],
});
}
Now when I call drawHighChart() at the windows onload this is what it outputs.
Now from here, I need to update each series dynamically as service returns a data array.
This is my function that updates the chart dynamically every time the service returns a response. Every time I call this fucntion, I pass a data array constructed from the response data.
initiVal = 7; //This is a gloabl variable that increases x-axis value from 7.
function updateHighChart(dataArray) {
var series = hchart.series[0];
var series1 = hchart.series[1];
var series2 = hchart.series[2];
var series3 = hchart.series[3];
var x = initiVal;
y = dataArray[0];
y1 = dataArray[1];
y2 = dataArray[2];
y3 = dataArray[3];
console.log("dataArray: " + dataArray);
series.addPoint([x, y], true, true);
series1.addPoint([x, y1], true, true);
series2.addPoint([x, y2], true, true);
series3.addPoint([x, y3], true, true);
initiVal++;
}
But even if data is dynamically assigned to y axis values in each series, they do not update as expected in the chart. This is how the charts looks after the 6th second/instance when data needs to dynamically update in the chart.

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

Multiple series of data in Highcharts but second line graph is displayed squashed?

I'm pretty new in using Highcharts API and, just started to embark using its cool features. I have a ASP.NET MVC web application which plot a line graph from a data source. In my application a user selects a key value from a list box and, out of that key an array of values will be retrieved and used the data as series for the graph.
[Chart 1] This is the plotted highchart.
[Chart 2] This is the expected output
As you can see in the above screenshots, CDT158 series displayed the graph correctly, more similar to Chart 2. But, Series 2 in Chart 1 is squashed, it is supposed to be like in Chart 2 - SINUSOID.
This is my functions that prepares and display the chart
var myChart;
function prepareChartData(dataChart)
{
var xAxis = [];
var dataSeries = [];
var xTitle;
for (var i = 0; i < dataChart.length; i++) {
var items = dataChart[i];
var XcategoriesItem = moment(items.Time).format("DD-MMM-YYYY HH:mm:ss");
var seriesData = parseFloat(items.Value);
xAxis.push(XcategoriesItem);
dataSeries.push(seriesData);
xTitle = items.Name;
}
if (myChart == undefined)
{
plotChartData(xAxis, dataSeries, xTitle);
return;
}
myChart.addSeries({
title: xTitle,
data: dataSeries
});
};
function plotChartData(Xaxis, dataseries, xtitle)
{
myChart = new Highcharts.Chart({
chart: {
renderTo: 'svgtrendspace',
type: 'line',
zoomType: 'xy',
panning: true,
panKey: 'shift',
plotBorderWidth: 1
},
title: {
text: 'Sample Chart'
},
legend: {
layout: 'horizontal',
align: 'bottom',
horizontalAlign: 'middle',
borderWidth: 0
},
plotOptions: {
series: {
dataLabels: {
enabled: false,
format: '{y}'
},
allowPointSelect: false
}
},
xAxis: {
type: 'category',
categories: Xaxis,
labels: {
rotation: -65,
style: {
fontSize: '8px',
fontFamily: 'Verdana, sans-serif'
}
},
tickInterval: 60
},
yAxis: {
gridLineColor: '#DDDDDD',
gridLineWidth: 0.5
},
series: [{
name: xtitle,
data: dataseries,
//name: '',
//data: [],
tooltip: {
pointFormat: '{series.name}: <b>{point.y}</b><br/>',
valueDecimals: 2
}
}]
});
};
This is the div element that displays the chart
<div id="svgtrendspace" style="overflow:auto;display:table-row; height:100%;"></div>
The jquery post function that retrieves data from AE controller.
$.post("/AE/UpdateTrend", { TrendRequestData: jdata },
function (data) {
if (data.length > 4) {
var results = $.parseJSON(data);
console.log(results);
prepareChartData(results);
trendData = results;
}
else {
trendData = "";
FillNoData("#svgtrendspace");
$('#MinimumHorizontalLine').val("");
$('#MaximumHorizontalLine').val("");
}
});
What could go wrong in my highcharts configuration that made the second series line graph squashed?
Any help is greatly appreciated.
I think it's caused by using categories, but actually you want to use datetime axis. Categories for first series and the second one don't match and that's the result. In other words, I would:
Change data format for array of points:
for (var i = 0; i < dataChart.length; i++) {
var items = dataChart[i];
var xDate = +moment(items.Time);
var seriesData = parseFloat(items.Value);
dataSeries.push([xDate, seriesData]);
xTitle = items.Name;
}
Change type to "datetime" and remove categories:
xAxis: {
type: 'datetime', // type
// categories: Xaxis, // remove
labels: {
rotation: -65,
style: {
fontSize: '8px',
fontFamily: 'Verdana, sans-serif'
}
},
// tickInterval: 60 // remove that too - you don't want ticks every 60 milliseconds ;)
},

Highcharts second series name labeled to 'Series 2'?

Just started a week ago to learn and use Highcharts. In my application a user selects a key value from a list box and, out of that key an array of values will be retrieved and, used the data to create a multiple series of line graph. In the screenshot below the first series (in light blue color) has the name of CDEP158 and, on the second series (in black color), the series name shouldn't be 'Series 2', it should be CDT158. 'Series 2' for the second series is the issue here.
This is the chart data preparation code which accepts dataChart (result) from jquery post callback function called in a click event.
function prepareChartData(dataChart)
{
var dataSeries = [];
var xTitle;
for (var i = 0; i < dataChart.length; i++) {
var items = dataChart[i];
var xDate = +moment(items.Time);
var seriesData = parseFloat(items.Value);
dataSeries.push([xDate, seriesData]);
xTitle = items.Name;
}
if (aeChart === undefined || aeChart === null)
{
plotChartData(dataSeries, xTitle);
return;
}
aeChart.addSeries({
title: xTitle,
data: dataSeries
});
};
Function that creates a new instance of Highchart and its configuration:
function plotChartData(dataseries, xtitle)
{
aeChart = new Highcharts.Chart({
chart: {
renderTo: 'svgtrendspace',
type: 'line',
zoomType: 'xy',
panning: true,
panKey: 'shift',
plotBorderWidth: 1
},
title: {
text: ''
},
legend: {
layout: 'horizontal',
align: 'left',
itemDistance: 10,
borderWidth: 0,
itemMarginTop: 0,
itemMarginBottom: 0,
padding: 20
},
plotOptions: {
series: {
states: {
hover: {
enabled: false
}
},
dataLabels: {
enabled: false,
format: '{y}'
},
allowPointSelect: false
}
},
xAxis: {
type: 'datetime',
labels: {
rotation: -65,
style: {
fontSize: '9px',
fontFamily: 'Verdana, sans-serif'
}
}
},
yAxis: {
gridLineColor: '#DDDDDD',
gridLineWidth: 0.5
},
series: [{
name: xtitle,
data: dataseries,
tooltip: {
pointFormat: '{series.name}: <b>{point.y}</b><br/>',
valueDecimals: 2
}
}]
});
};
Why is that the first series gets the correct name but on the second one it did not? Is my highcharts configuration wrong? How should I properly configure or format it to address the issue?
I have googled it for similar issues related with multiple series but I couldn't find any similar questions or answers that would help me.
The fact that it works for the first series implies that the issue isn't with your code, but rather is with your init.
Can you put a console.log('Title: ' + xTitle); statement right before you call aeChart.addSeries() in the above function to check on what you are passing in? My suspicion is that the second series is not being passed a title, and that HighCharts is therefore putting in Series2 on its own.
Maybe you should not be setting the value of xTitle in every single iteration of the initial for loop?

Dynamically change startAngle value in HighCharts

I want to dynamically change the startAngle value on my polar chart from JSON 'Wind_direction' value.
The code is below:
$(function() {
$.getJSON('wind_graph.php?callback=?', function(dataWind) {
var direction = Wind_direction;
var polarOptions = {
chart: {
polar: true,
events : {
load : function () {
setInterval(function(){
RefreshDataWind();
}, 1000);
}
}
},
title: {
text: 'Wind Direction'
},
pane: {
startAngle: direction,
},
xAxis: {
tickInterval: 15,
min: 0,
max: 360
},
plotOptions: {
series: {
pointStart: 0,
pointInterval: 30,
},
}
};
// The polar chart
$('#graph-1').highcharts(Highcharts.merge(polarOptions, {
yAxis: {
tickInterval: 5,
min: 0,
max: 25,
visible: false
},
series: [{
type: 'line',
name: 'Direction',
data: [
[0, 0],
[direction, 20]
],
}
]
}));
function RefreshDataWind()
{
var chart = $('#graph-1').highcharts();
$.getJSON('wind_graph.php?callback=?', function(dataWind)
{
var direction = Wind_direction;
chart.series[0].setData([[0,0],[direction, 20]]);
});
}
});
});
In the last function, below 'chart.series[0].setData... I was trying to add something like this:
chart.pane.setStartAngle(direction);
but this throws the error: "Cannot read property 'startAngle' of undefined"
Also was trying another one idea:
polarOptions.pane({ startAngle: direction });
but here is error: "polarOptions.pane is not a function".
So I'm stack. Please for help.
You should be able to update all chart options with Chart.update(). Unfortunately, it looks that it does not have any effect on pane - I reported the issue here.
Now you can update the pane in old-fashioned way - by destroying and creating a new chart - http://jsfiddle.net/highcharts/qhY8C/
The other possibility is trying the workaround - set options for pane, remove the pane and update the axis - it should create a new pane with new options.
const xAxis = chart.xAxis[0];
chart.options.pane.startAngle = 45;
Highcharts.erase(chart.panes, xAxis.pane);
chart.yAxis[0].update(null, false);
xAxis.update();
example: http://jsfiddle.net/v8L381Lj/

Correctly plot time series in Highcharts/Highstock

I have large collection of data in the format [1421065200000, 1.72], where the first parameter is time in milliseconds and the second parameter is the value at that specific time. I have data array consisting of such data in large size. Now I want scrollable graph containing plot of such time and value data. Here is my javascript implementation to do so,
var dataArray; //This contains my data array i.e. ([[t1, v1],[t2, v2],...])
var minDate = dataArray[0][0];
var maxDate = dataArray[dataArray.length - 1][0];
var chartOption = {
chart: {
type: graphType,
renderTo: 'graph-container',
zoomType: 'x',
useUTC: false
},
title: {
text: 'Data from last 24 hours'
},
credits : {
enabled: false
},
xAxis: {
title: {
text: null
},
type: 'datetime',
dateTimeLabelFormats: {
second: '%Y-%m-%d<br/>%H:%M:%S',
minute: '%Y-%m-%d<br/>%H:%M',
hour: '%Y-%m-%d<br/>%H:%M',
day: '%Y<br/>%m-%d',
week: '%Y<br/>%m-%d',
month: '%Y-%m',
year: '%Y'
},
allowDecimals: false,
ordinal: false,
min: minDate,
max: maxDate
},
yAxis: {
title: {
text: null
}
},
plotOptions: {
series: {
pointStart: minDate,
pointInterval: 5 * 60 *1000
}
},
series: [{
name: parameterName,
data: dataArray
}],
exporting: {
enabled: false
}
};
parameterChart = new Highcharts.Chart(chartOption);
}
The chart shows incorrect data, the time value on x-axis doesn't match the value at y-axis. What is the most correct and efficient to show such time series. Should I use Highcharts or Highstock. Please guide me through this, with suggestion or maybe with solution.
What I did was, I used HighStock instead of HighCharts (since I needed scrollbar along x-axis for large collection of data). I was passing the date in my local time zone format, whereas the chart was using UTC. So, I disabled the use of UTC (alternative: I could have provided data in UTC and drawn the graph using the same, In my case I needed my local labels). I gave the minimum and maximum range to the x-axis through x-axis min and max configuration. Here is the sample of my code,
//dataArray contains the array of data [[x1, y1], [x2, y2], ...]
//x is Date, y is temperature value (say)
var minDate = dataArray[0][0];
var maxDate = dataArray[dataArray.length - 1][0];
//Disable use of UTC
Highcharts.setOptions({
global: {
useUTC: false
}
});
//Create graph options
var chartOption = {
chart: {
type: graphType, //line, bar, column, etc
renderTo: 'graph-container', //div where my graph will be drawn
zoomType: 'x' //Making x-axis zoomable/scrollable
},
title: {
text: 'Data from last 6 hours'
},
subtitle: {
text: document.ontouchstart === undefined ?
'Click and drag in the plot area to zoom in' :
'Pinch the chart to zoom in'
},
xAxis: {
title: {
text: null
},
type: 'datetime', //For time series, x-axis labels will be time
labels: {
//You can format the label according to your need
format: '{value:%H:%m}'
},
min: minDate,
max: maxDate,
minPadding: 0.05,
maxPadding: 0.05
},
yAxis: {
title: {
text: null
}
},
scrollbar: {
enabled: true
},
series: [{
name: "Temperature", //Name of the series
data: dataArray
}],
exporting: {
enabled: false
},
credits : {
enabled: false
}
};
//Finally create the graph
var myChart = new Highcharts.Chart(chartOption);

Categories

Resources