Not sure why because I have done it in the past, but I have a Highcharts bar chart and it won't animate. This is the declaration of the chart,
function initializeData() {
$http.get(url).success(function(ret) {
$scope.jsondata = ret;
var newdata = [];
for (x = 0; x < 5; x++) {
newdata.push({
name: setName($scope.jsondata[x].name),
y: $scope.jsondata[x].data[0],
color: getColor($scope.jsondata[x].data[0])
});
}
$scope.chart.series[0].setData(newdata);
});
mainInterval = $interval(updateData, 5000);
}
function updateData() {
$http.get(url).success(function(ret) {
$scope.jsondata = ret;
console.debug("here");
for (x = 0; x < 5; x++) {
$scope.chart.series[0].data[x].update({
y: $scope.jsondata[x].data[0],
color: getColor($scope.jsondata[x].data[0])
});
}
});
}
$scope.chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'bar',
animation: true,
events: {
load: initializeData
}
},
title: {
text: ''
},
xAxis: {
type: 'category',
labels: {
style: {
fontSize: '11px'
}
}
},
yAxis: {
min: 0,
max: 100,
title: {
text: 'Total Score',
align: 'high'
}
},
legend: {
enabled: false
},
tooltip: {
pointFormat: 'Total Score <b>{point.y:.3f}</b>'
},
series: [{
name: 'Active Users',
data: [],
dataLabels: {
enabled: true,
rotation: 30,
style: {
fontSize: '10px',
fontFamily: 'Verdana, sans-serif'
},
format: '{point.y:.3f}', // one decimal
}
}]
});
And as you can see I have animate : true, so I am not sure what is the problem here. I have this older plunker where all of the data is in separate series, but it animates fine. But this is the plunker I am working on and having trouble with. They are like identical basically. In the newer one I broke out the initialization of data into its own method, but that is the only real main difference.
Some edits:
So as I was saying, I have done things this way with an areaspline chart (I know it was said they work a bit different but they are set up identically).
function initializeData() {
$interval.cancel(mainInterval);
$scope.previousPackets = '';
$http.get("https://api.myjson.com/bins/nodx").success(function(returnedData) {
var newdata = [];
var x = (new Date()).getTime();
for (var step = 9; step >= 0; step--) {
newdata.push([x - 1000 * step, 0]);
}
$scope.chart.series[0].setData(newdata);
});
mainInterval = $interval(updateData, 2000);
}
function updateData() {
$http.get(url + acronym + '/latest').success(function(returnedData) {
var x = (new Date()).getTime();
if ($scope.previousPackets != returnedData[0].numPackets) {
$scope.chart.series[0].addPoint([x, returnedData[0].numPackets], true, true);
$scope.previousPackets = returnedData[0].numPackets;
} else {
$scope.chart.series[0].addPoint([x, 0], true, true);
}
});
}
$scope.chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'areaspline',
animation: Highcharts.svg, // don't animate in old IE
marginRight: 10,
events: {
load: initializeData
}
},
title: {
text: ''
},
xAxis: {
type: 'datetime',
tickPixelInterval: 150
},
yAxis: {
title: {
text: 'Packets'
},
plotLines: [{
value: 0,
width: 1,
color: '#d9534f'
}]
},
tooltip: {
formatter: function() {
return Highcharts.numberFormat(this.y) + ' packets<b> | </b>' + Highcharts.dateFormat('%H:%M:%S', this.x);
}
},
legend: {
enabled: false
},
exporting: {
enabled: false
},
series: [{
name: 'Packets',
data: []
}]
});
I also updated the first chunk of code with the initializeData() method and updateData() method which are seemingly identical in both different charts.
It looks like it plays an important role if you provide your data at chart initialization or after. For simplicity I refactored your code a little
function initializeChart(initialData, onload) {
$scope.chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'bar',
animation: true,
events: {
load: onload
}
....
series: [{
name: 'Active Users',
data: initialData,
dataLabels: {
enabled: true,
format: '{point.y:.3f}', // one decimal
}
}]
});
}
function getData(callback) {
$http.get(url).success(function(ret) {
$scope.jsondata = ret;
var newdata = [];
for (x = 0; x < 5; x++) {
newdata.push([setName(ret[x].name), ret[x].data]);
}
callback(newdata);
});
}
As a result your two planks are in essense reduced to two methods below. The first initializes chart with preloaded data and the second updates data in existing chart.
function readDataFirst() {
getData(function(newdata) {
initializeChart(newdata);
});
}
function initializeChartFirst() {
initializeChart([], function() {
getData(function(newdata) {
$scope.chart.series[0].setData(newdata);
})
});
}
The first one animates fine while the second does not. It looks like highcharts skips animation if dataset is not initial and is treated incompatible.
However if you really want to have animation in your current plant (chart first workflow) you can achieve that by initializing first serie with zeros and then with the real data. This case it will be treated as update
function forceAnimationByDoubleInitialization() {
getData(function(newdata) {
initializeChart([]);
var zerodata = newdata.map(function(item) {
return [item[0], 0]
});
$scope.chart.series[0].setData(zerodata);
$scope.chart.series[0].setData(newdata);
});
All these options are available at http://plnkr.co/edit/pZhBJoV7PmjDNRNOj2Uc
Related
So I have a project where I am trying to update chart. in which 100 points to be displayed in each second.
For that I am trying this example from the Highcharts.
But the chart stops responding to such event.
The code:
jsfiddle
Highcharts.chart('container', {
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);
}, 10);
}
}
},
time: {
useUTC: false
},
title: {
text: 'Live random data'
},
xAxis: {
type: 'datetime',
tickPixelInterval: 150
},
yAxis: {
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: [{
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;
}())
}]
});
You can set redraw parameter in addPoint method to false and call chart.redraw() at longer intervals:
chart: {
...,
events: {
load: function() {
// set up the updating of the chart each second
var series = this.series[0],
chart = this;
setInterval(function() {
var x = (new Date()).getTime(), // current time
y = Math.random();
series.addPoint([x, y], false, true);
}, 10);
setInterval(function() {
chart.redraw();
}, 500);
}
}
}
Live demo: https://jsfiddle.net/BlackLabel/s3gh6q5j/
API Reference:
https://api.highcharts.com/class-reference/Highcharts.Series#addPoint
https://api.highcharts.com/class-reference/Highcharts.Chart#redraw
We are using Spline Graph for our game in which we are facing issue with x and y axis value which we need to put 0,0 and save the values from initially till end as we need to all plotting from start till end of the value.
Check Live Demo Here
JavaScript Code
<script>
var a = 1;
var b = 1;
var factor = 1.2;
$(document).ready(function () {
Highcharts.chart('container', {
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 () {
b = b*1.2;
console.log(b);
var x = a; // current time
var y = b;
a++;
series.addPoint([x, y], true, true);
}, 700);
}
}
},
title: {
text: 'Live random data'
},
xAxis: {
type: 'number',
min: 0,
tickInterval: 2
},
yAxis: {
title: {
text: 'Value'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
tooltip: {
formatter: function () {
return '<b>X: ' + this.x+', Y:'+this.y;
}
},
legend: {
enabled: false
},
exporting: {
enabled: false
},
series: [{
name: 'Random data',
data: (function () {
// generate an array of random data
var data = [],i;
for (i = 1; i <= 19; i++) {
b = b*factor;
data.push({
x: a,
y: b
});
a++;
}
return data;
}())
}]
});
});
The following code draws a curve line from the origin (0,0) to the end point which gets updated on the interval. You needed to make the shift variable false in the addPoint call. Higchart docs
$(document).ready(function () {
var a = 1;
var b = 1;
var factor = 1.2;
Highcharts.chart('container', {
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 () {
b = b*1.2;
var x = a; // current time
var y = b;
a++;
// Add new end point
series.addPoint([x, y], true, false);
}, 700);
}
}
},
title: {
text: 'Live random data'
},
xAxis: {
type: 'number',
min: 0,
tickInterval: 2
},
yAxis: {
title: {
text: 'Value'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
tooltip: {
formatter: function () {
return '<b>X: ' + this.x+', Y:'+this.y;
}
},
legend: {
enabled: false
},
exporting: {
enabled: false
},
series: [{
name: 'Random data',
data: (function () {
// generate an array of random data
// Add point at origin and last point of series
var data = [{x:0,y:0}],i;
for (i = 1; i <= 19; i++) {
b = b*factor;
a++
data.push({
x: a,
y: b
});
}
return data;
}())
}]
});
});
Updated JsFiddle
I want to use Highcharts graph and update y axis dynamically. Actually I want to update nsw, Tas, ACT every 5 sec. How do I do it ?
Here is my code.
$(function () {
$('#container').highcharts({
title: {
text: 'Histogram',
x: -20 // center
},
subtitle: {
text: 'Source: www.trove.com',
x: -20
},
xAxis: {
categories: ['NSW', 'Tas', 'ACT','QLD','VIC','SA','WA']
},
yAxis: {
title: {
text: 'Hits'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
tooltip: {
valueSuffix: '°C'
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'middle',
borderWidth: 0
},
series: [{
name: 'States',
data: [nsw, Tas, ACT,qld,vic,sa,wa]
}]
});
});
});
In the Documentation you can find an example from Highcharts in jsfiddle. Check it out http://jsfiddle.net/gh/get/jquery/1.9.1/highslide-software/highcharts.com/tree/master/samples/highcharts/demo/dynamic-update/. In the example every second a new point will be added. Here comes the relevant code part:
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);
}
}
},
`
The easiest way to do it would be to use the javascript function "setInterval()" to call it.
Here is a link where you can find a way to do it :
http://www.w3schools.com/js/js_timing.asp
If you are not really good at javascript, you might need this declaration of functions : var functionName = function() {} vs function functionName() {}
Use:
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(),
l = series.data.length;
for(var i = 0; i < l; i++) {
series.data[i].update({
y: getHits(i) // or something else
});
}
}, 5000); // 5 seconds
}
}
Where index is index (count from 0) of nsw/Tas/ACT in data array. (for nsw = 0, for Tas = 1 etc.)
my task is to add series dynamically and keep updating their data, which is received by ajax calls.
i know series can be added dynamically by declaring highchart funciton global. and using series.addseries() function , and also data can be updated by using settimout request to ajax call and updating points by using series.addpoint() function.
i have done both the work separably. but when i combine both the technique, data is not added to highchart. i have done lot of research on this, and i am not finding reason for not adding the data. infact script hang the browser.
i have checked the series object, which show x-data and y-data are processed. only difference i find is isDirty field and isDirtydata field are set to true. dont know the reason.
here is the full code
var serverUrl = 'http://'+window.location.hostname+':8000'
Highcharts.setOptions({
global: {
useUTC: false
}
});
data={}
$(document).ready(function(){
$(function () {
console.log("highcharts")
$('#first').highcharts({
chart: {
type: 'spline',
//marginRight: 150,
marginBottom: 5,
events: {
load: requestData(data)
}
},
title: {
text: 'Server Monitroting Tool'
},
subtitle: {
text: 'Cpu usage, Memory Usage,Disk Usage,Mongo Usage'
},
xAxis: {
type: 'datetime',
categories: ['TIME'],
dateTimeLabelFormats : {
hour: '%I %p',
minute: '%I:%M %p'
}
},
yAxis:{
showEmpty:false
},
legend:
{
backgroundColor: '#F5F5F5',
layout: 'horizontal',
floating: true,
align: 'left',
verticalAlign: 'bottom',
x: 60,
y: 9,
shadow: false,
border: 0,
borderRadius: 0,
borderWidth: 0
},
series: {}
});
});
from_date=new Date().getTime()-60000;
function requestData(data)
{
if(!data)
{
console.log("default ")
}
else
{
console.log("requesting")
$.ajax({
url:serverUrl+'/api/fetch_params/',
type:'GET',
data:data,
success:function(response)
{
console.log("in success")
//data = {'type':TypeOfParameter,'hostname':hostname,'sub-type':sub_type,'param':sub_type_parameter,'from-date':from_date}
var id=data['sub-type']+data['param']
var series = chart.get(id)
shift = series.data.length > 100; // shift if the series is longer than 300 (drop oldest point)
response= $.parseJSON(response)
var x=data['sub-type']
all_data=response.response.data[x]
// console.log(new Date(from_date),'latest timestamp')
console.log(series)
console.log("data",all_data)
from_date=all_data[all_data.length-1][0]
// console.log(from_date)
// series.isDirty=false
// series.isDirtyData=false
for (var i = 0; i < all_data.length; i++)
{
series.addPoint({ x: all_data[i][0],y: all_data[i][1],id: i},false,shift);
}
console.log("series object",series)
// chart.redraw();
console.log(" parameter",data)
data['from-date']=from_date
console.log("data",series.data)
// console.log(chart)
setTimeout(requestData(data), 10000);
console.log("out of success")
},
cache:false,
error:function()
{
console.log("err")
}
});
}
}
$.ajax({
url:serverUrl+'/api/fetch_all_servers/',
type:'GET',
success:function(response){
response = $.parseJSON(response)
sd = response.response.all_servers
$('input[name=select_menue]').optionTree(sd)
},
error:function(){
console.log('error')
}
});
$('.param-button').live('click',function(e){
e.stopPropagation()
})
$('param-select').live('hover',function(){
$(this).find('.type-select').show()
});
$('.final_value').live('change',function(){
select_name = 'select_menue_'
param_list = []
var param=$('select[name="'+select_name+'"] option:selected').attr('value')
while(param){
param_list.push(param)
select_name += '_'
var param=$('select[name="'+select_name+'"] option:selected').attr('value')
}
console.log(param_list,"param_list")
from_date=new Date().getTime()-300000 //5 minute data
hostname=param_list[0]
TypeOfParameter= param_list[1]
sub_type_parameter=param_list[param_list.length-1]
data = {'type':TypeOfParameter,'hostname':hostname,'param':sub_type_parameter,'from-date':from_date}
var sub_type;
if(param_list.length==4){
sub_type=param_list[2]
data['sub-type'] = sub_type
}
else
{
sub_type=sub_type_parameter
}
// console.log(hostname,TypeOfParameter,sub_type,sub_type_parameter)
data = {'type':TypeOfParameter,'hostname':hostname,'sub-type':sub_type,'param':sub_type_parameter,'from-date':from_date}
requestData(data)
$('#loadingmessage').show(); // show the loading message.
chart = $('#first').highcharts();
if(TypeOfParameter=='cpu')
{
console.log("adding axis")
chart.addAxis({ // Primary yAxis
id:'Cpu_axis'+sub_type_parameter,
labels: {
formatter: function() {
return this.value;
},
style: {
color: '#89A54E'
}
},
title: {
text: "core "+ sub_type+ " "+sub_type_parameter,
style: {
color: '#89A54E'
}
},
lineWidth: 1,
lineColor: '#08F'
});
console.log("adding series")
chart.addSeries({
id:sub_type+sub_type_parameter,
name: "core "+sub_type+" "+sub_type_parameter,
data :[],
tooltip : {
valueSuffix: ' %'
},
yAxis:'Cpu_axis'+sub_type_parameter
})
console.log("series out")
}
if(TypeOfParameter=='memory')
{
chart.addAxis ({
id:'memory'+sub_type_parameter,
labels:{
formatter: function() {
return this.value +'%';
},
style: {
color: '#89C54F'
}
},
title: {
text:sub_type+" "+sub_type_parameter
},
lineWidth: .5,
lineColor: '#08F',
opposite: true
});
chart.addSeries({
id:sub_type+sub_type_parameter,
name: sub_type+'memory usage',
data: [],
tooltip: {
valueSuffix: '%'
},
yAxis:'memory'+sub_type_parameter
});
}
if(TypeOfParameter=='disk')
{
chart = new Highcharts.Chart({
chart: {
renderTo: 'second',
defaultSeriesType: 'spline',
events: {
load: requestData
}
},
title: {
text: 'disk Usage'
},
xAxis: {
type: 'datetime',
tickPixelInterval: 150,
maxZoom: 20 * 1000
},
yAxis: {
minPadding: 0.2,
maxPadding: 0.2,
title: {
text: 'disk',
margin: 80
}
},
series: [{
id:sub_type+sub_type_parameter,
name: 'disk',
data: []
}]
});
}
if(TypeOfParameter=='db')
{
chart = new Highcharts.Chart({
chart: {
renderTo: 'second',
defaultSeriesType: 'spline',
events: {
load: requestData
}
},
title: {
text: 'mongo Usage'
},
xAxis: {
type: 'datetime',
tickPixelInterval: 150,
maxZoom: 20 * 1000
},
yAxis: {
minPadding: 0.2,
maxPadding: 0.2,
title: {
text: 'mmongo',
margin: 80
}
},
series: [{
id:sub_type+sub_type_parameter,
name: 'mongo',
data: []
}]
});
}
if(TypeOfParameter=='redis')
{
chart = new Highcharts.Chart({
chart: {
renderTo: 'second',
defaultSeriesType: 'spline',
events: {
load: requestData
}
},
title: {
text: 'redis Usage'
},
xAxis: {
type: 'datetime',
tickPixelInterval: 150,
maxZoom: 20 * 1000
},
yAxis: {
minPadding: 0.2,
maxPadding: 0.2,
title: {
text: 'redis',
margin: 80
}
},
series: [{
id:sub_type+sub_type_parameter,
name: 'redis',
data: []
}]
});
}
$('#loadingmessage').hide(); // hide the loading message
}
)
});
i am stuck on this problem for quite a while. and still not able to figure out the solution.
here is the full code link
someone please please help. feeling frustrated ..:-(
As you know the addPoint method is bit dangerous when dealing with quite lots points. It is recommended to disable redraw per point when dealing with many new points - more info http://api.highcharts.com/highcharts#Series.addPoint() , I notice you are doing that already in the loop statement, but why did you commented out? have you tried enabling again. Make sure chart.redraw works by adding a new redraw chart event, and set an alert or console log.
Also you may try using, below as part of ajax, instead of cache:false. I had some problems in past.
headers: { 'Cache-Control': 'no-cache' }
Cheers
I have started working with highcharts.js, but fails to add new points my bar graph:
Every time it goes into addPoint, Firefox freezes :(
I am using Firebug, and when it tries to addPoint, it always freeze :(
// if no graph
if (! charts[0])
{
// make chart table
var round_ids = [];
var total_players = [];
var total_bets = [];
$.each(last_rounds_cache.last_rounds_data, function(index, value)
{
round_ids.push(Number(value[0]));
total_players.push(Number(value[2]));
total_bets.push(Number(value[3]));
}
)
charts[0] = new Highcharts.Chart({
chart: {
renderTo: 'players_per_round',
type: 'column',
events: {
click: function(e) {
// find the clicked values and the series
var x = e.xAxis[0].value,
y = e.yAxis[0].value,
series = this.series[0];
// Add it
series.addPoint([x, y]);
}
}
},
title: {
text: 'Players/Bets per Round'
},
xAxis: {
categories: round_ids,
},
yAxis: {
min: 0,
title: {
text: 'Rainfall (mm)'
}
},
legend: {
layout: 'vertical',
backgroundColor: '#FFFFFF',
align: 'left',
verticalAlign: 'top',
x: 10,
y: 10,
floating: false,
shadow: true
},
tooltip: {
formatter: function() {
return ''+
this.x +': '+ this.y;
}
},
plotOptions: {
column: {
pointPadding: 0.2,
borderWidth: 0
}
},
series: [{
name: 'Players',
data: total_players
}, {
name: 'Bets',
data: total_bets
}]
});
}
else
{
if (newChartsPoints.length > 0)
{
$.each(newChartsPoints, function(index, value)
{
// retreive data
var temp_round_id = value[0];
var temp_total_players = value[1][0];
var temp_total_bets = value[1][1];
// add points
var series = charts[0].series;
series[0].addPoint([temp_round_id, temp_total_players], false);
series[1].addPoint([temp_round_id, temp_total_bets], false);
// add categories
categories = charts[0].xAxis[0].categories;
categories.push(temp_round_id);
charts[0].xAxis[0].setCategories(categories, false);
charts[0].redraw();
});
}
}