I am trying to update my Highstock candlestick chart with new data points but I can not make it work - and I don't know where is the problem. Everything looks good for me, but chart is not updating.
the updatepoint.php gives this as result
{"time":"1546978140000", "open":"4112.89677", "high":"4112.9", "low":"4112.8", "close":"4112.9"}
when executing the code, the charts updates every minute, but it just clears last candlestick at first update and that's it, no change on next updates
chart: {
events: {
load: function() {
addPopupEvents(this);
var series = this.series[0];
setInterval(function() {
$.ajax({
url: 'http://www.chart.blue/chart/Highstock/updatepoint.php',
dataType: 'json',
success: function(point) {
series.addPoint([point.time, point.open, point.high, point.low, point.close], true, true);
},
});
}, 60000);
}
}
},
You need to convert string values to numbers:
chart: {
events: {
load: function() {
var series = this.series[0];
setInterval(function() {
$.ajax({
url: 'https://www.chart.blue/chart/Highstock/updatepoint.php',
dataType: 'json',
success: function(point) {
series.addPoint([+point.time, +point.open, +point.high, +point.low, +point.close], true, true);
},
});
}, 60000);
}
}
},
Live demo: https://jsfiddle.net/BlackLabel/suj7zaf2/
Related
currentDateIndicator seems to only show time of loading the chart. Also currentDateIndicator.label.formatter is called only once (on load).
Highcharts.chart('container', {
xAxis: [{
id: 'bottom-datetime-axis',
currentDateIndicator: {
label: {
format: '%Y-%M-%d, %H:%M:%S',
formatter: function(indicator) {
console.log("currentDateIndicator"); // this is called just once (on load)
return indicator;
},
}
},
How to make currentDateIndicator dynamic showing the current time passing by?
https://jsfiddle.net/ft2ubchk/
The simplest way is to update x-axis every second, for example:
chart: {
events: {
load: function(){
var xAxis = this.xAxis[0];
setInterval(function(){
xAxis.update({});
}, 1000);
}
}
}
Live demo: https://jsfiddle.net/BlackLabel/eh5zp36o/
API Reference: https://api.highcharts.com/class-reference/Highcharts.Axis#update
Can we disable zoom on highchart graph while graph is loading.
I have multiple graphs therfore would like to disable the zoom option until all graphs gets loaded.
It is possible to change zoomType of a chart dynamically, but it is not a part of official API. That way after all charts are loaded you will be able to change their zoomType from none to some.
$(function () {
$('#container').highcharts({
chart: {
zoomType: ''
},
xAxis: {
minRange: 1
},
series: [{
data: [1,2,3,4,5,6,7]
}]
});
function enableZoom(zoomType) {
var chart = $('#container').highcharts(),
zoomX = /x/.test(zoomType),
zoomY = /y/.test(zoomType);
chart.options.zoomType = zoomType;
chart.pointer.zoomX = zoomX;
chart.pointer.zoomY = zoomY;
chart.pointer.zoomHor = zoomX;
chart.pointer.zoomVert = zoomY;
}
$('#zoomX').click(function () {
enableZoom('x');
});
$('#zoomY').click(function () {
enableZoom('y');
});
$('#zoomXY').click(function () {
enableZoom('xy');
});
$('#noZoom').click(function () {
enableZoom('');
});
});
JSFiddle: http://jsfiddle.net/pearp126/
you can do so by simple setting zoomType as null in your chart config
zoomType: null
See the documentation here for more details
Basically the only thing you need to get done is removing the chart and replacing it with one with the settings you like.
See the code below:
var chart = $('#container').highcharts();
function renderChart(){
chart = new Highcharts.Chart(chart.options);
chart.render();
}
Once you want to enable zooming (or any other setting):
$('#container').highcharts().options.chart.zoomType = 'xy';
renderChart();
To be honest I'm not sure what happens to the old chart. Hopefully it's just overwritten and doesn't it impose a big memory issue.
I created a fiddle you can find here
Basically you can stop the "selection" event (zoom), when the loading label of the chart is displayed.
Using the default Highcharts function .showLoading() for show the loading label, and the default variable loadingShown, for verify is the loading label is displayed or not.
So, by using the function .showLoading(), let's say before doing an AJAX request, and validating with the variable loadingShown if the loading label is displayed or not, we can stop the selection event.
Another way, is to use a thirdparty loading mask, and add it to the chart's container.
In the next example you'll find how to cancel the zoom using the .showLoading() function and how to use jQuery plugin: pLoading https://github.com/joseshiru/p-loading (for show the loading mask)
$(function () {
var setEvents;
var chart;
$.getJSON('https://www.highcharts.com/samples/data/jsonp.php?filename=usdeur.json&callback=?', function (data) {
chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
zoomType: 'x',
events: {
selection: function () {
//Quit the selection event, while the loading spinner is displayed.
if (chart.loadingShown) {
return false;
}
}
}
},
title: {
text: 'USD to EUR exchange rate over time'
},
subtitle: {
text: document.ontouchstart === undefined ?
'Click and drag in the plot area to zoom in' : 'Pinch the chart to zoom in'
},
xAxis: {
type: 'datetime'
},
yAxis: {
title: {
text: 'Exchange rate'
}
},
legend: {
enabled: false
},
plotOptions: {
area: {
fillColor: {
linearGradient: {
x1: 0,
y1: 0,
x2: 0,
y2: 1
},
stops: [
[0, Highcharts.getOptions().colors[0]],
[1, Highcharts.Color(Highcharts.getOptions().colors[0]).setOpacity(0).get('rgba')]
]
},
marker: {
radius: 2
},
lineWidth: 1,
states: {
hover: {
lineWidth: 1
}
},
threshold: null
}
},
series: [{
type: 'area',
name: 'USD to EUR',
data: data
}]
});
});
setEvents = function () {
var $showLoadingBtn = $('.show-loading');
var $hideLoadingBtn = $('.hide-loading');
var $showExternalMask = $('.show-toggle-mask');
var $hideExternalMask = $('.hide-toggle-mask');
$showLoadingBtn.on('click.showLoading', function () {
chart.showLoading();
});
$hideLoadingBtn.on('click.hideLoading', function () {
chart.hideLoading();
});
$showExternalMask.on('click.toggleMask', function () {
$('#container').ploading({action: 'show'});
});
$hideExternalMask.on('click.toggleMask', function () {
$('#container').ploading({action: 'hide'});
});
}();
});
Example in jsfiddle: http://jsfiddle.net/8p2fzbxw/3/
Following is the code that I have developed:
<body>
<div id="container"></div>
</body>
$(function(){
var options = {
chart: {
renderTo: 'container',
type: 'line'
},
xAxis: {
categories: [],
labels: {
y: 20,
rotation: -45,
align: 'right'
}
},
series: []
};
var oDataUrlEntity = serviceUrl;
$.ajax({
type: "GET",
dataType: "json",
url: oDataUrlEntity,
username: "xxxx",
password: "xxxx",
async: false,
cache: false,
timeout: 5000,
error: function(jqXHR, textStatus, errorThrown) {
debugger;
},
success: function(data, textStatus, jqXHR) {
debugger;
data_poRequest = {
rootNode: []
};
for (var i = 0; i < data.d.results.length; i++) {
var obj = data.d.results[i];
data_poRequest.rootNode.push({
key1: obj.fieldName1,
key2: obj.fieldName2
});
}
for (var i = 0; i < data_poRequest.rootNode.length; i++) {
debugger;
options.xAxis.categories.push(data_poRequest.rootNode[i]['fieldName']);
series = {
data: []
};
series.data.push(data_poRequest.rootNode[0]);
options.series.push(series);
//
}
debugger;
chart = new Highcharts.Chart(options);
}
});
});
The problem is now on the highcharts I am getting only one value out of the 24 values in the cateogies array.Also only the legend is coming with 24 series.
Also,in the debugger i can see values inside options.xAxis.categories & also inside series.data,But they are not getting reflected on the Highcharts.
Could anyone help me with this.Thanks in advance.
The problem is that you are creating every time new series. Won't you have instead one series?
So change:
for (var i = 0; i < data_poRequest.rootNode.length; i++) {
debugger;
options.xAxis.categories.push(data_poRequest.rootNode[i]['fieldName']);
series = {
data: []
};
series.data.push(data_poRequest.rootNode[0]);
options.series.push(series);
//
}
To:
series = {
data: []
};
for (var i = 0; i < data_poRequest.rootNode.length; i++) {
options.xAxis.categories.push(data_poRequest.rootNode[i]['fieldName']);
series.data.push(data_poRequest.rootNode[0]);
}
options.series.push(series);
I am using the highcharts library to collect data from a csv file every 2 minutes and dispaly it in the graph.
Instead of refreshing the data, the function just duplicates the data and my browser ends up crashing. Can some one help ? i am running out of ideas. Below is my code. I have removed all the xAxis,Yaxis,legend from the code to make it shorter
<script type="text/javascript">
var chart;
var options = {
chart: {
renderTo: 'container',
defaultSeriesType: 'spline',
events: {
load: function() {
setInterval(function(){
refresh('file.csv');
}, 120000);
}
}
},
tooltip: {
valueSuffix: ' Views'
},
legend: {
layout: 'left'
},
series : []
};
function refresh(file) {
if(chart) chart.destroy();
$.get(file, function(data) {
var lines = data.split('\n');
$.each(lines, function(lineNo, line) {
var items = line.split(',');
var series = {
data: []
};
$.each(items, function(itemNo, item) {
if (itemNo == 0) {
series.name = item;
} else {
series.data.push(parseFloat(item));
}
});
options.series.push(series);
});
chart = new Highcharts.Chart(options);
});
}
$(document).ready(function() {
refresh('file.csv');
});
</script>
<div id="container"></div>
Instead of destroy chart, you can use setData / addSeries function which allows to manipulate data. http://api.highcharts.com/highcharts#Chart.addSeries
http://api.highcharts.com/highcharts#Series.setData
I am trying to output JSON data on to Highstock chart. Initially I struggled with the JSON formatted date which I resolved by following instruction on other answer on stackoverflow by re-formatting dates. But I'm still unable to get the graph plotted on view page -
<script src="http://code.highcharts.com/stock/highstock.js"></script>
<script type="text/javascript">
$(document).ready(function () {
var mydata =[];
chartOjb = new Object();
$.ajax({
type: "GET",
url: "/ReportIntance/DummyCall/2",
data: '{ }',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
$.each(data, function (index, item) {
chartOjb.name = new Date(parseInt(item.DayDate.replace("/Date(", "").replace(")/", ""), 10));
chartOjb.data = item.Series1;
mydata.push({
x: new Date(parseInt(item.DayDate.replace("/Date(", "").replace(")/", ""), 10)),
y: item.Series1
});
})
},
failure: function (response) {
alert(response);
}
});
chart1 = new Highcharts.Chart({
chart: {
renderTo: 'Chart1'
},
title: {
text: 'Delivery Price example using Chart'
},
xAxis: {
type: 'datetime'
},
yAxis: {
title: {
text: 'Price'
}
},
series: [ { data: mydata }]
});
});
</script>
<div id="Chart1" style="height: 500px; min-width: 500px"></div>
My JSON string is -
[{"DayDate":"\/Date(1334704500000)\/","Series1":4.01,"Series2":0,"Series3":0,"Series4":0,"Series5":0},
{"DayDate":"\/Date(1334705400000)\/","Series1":5.01,"Series2":0,"Series3":0,"Series4":0,"Series5":0},
{"DayDate":"\/Date(1334706300000)\/","Series1":4.51,"Series2":0,"Series3":0,"Series4":0,"Series5":0},
{"DayDate":"\/Date(1334707200000)\/","Series1":6.01,"Series2":0,"Series3":0,"Series4":0,"Series5":0},
{"DayDate":"\/Date(1334708100000)\/","Series1":4.71,"Series2":0,"Series3":0,"Series4":0,"Series5":0},
{"DayDate":"\/Date(1334709000000)\/","Series1":7.01,"Series2":0,"Series3":0,"Series4":0,"Series5":0},
{"DayDate":"\/Date(1334709900000)\/","Series1":7.01,"Series2":0,"Series3":0,"Series4":0,"Series5":0}]
Currently I'm trying to output simple line chart and using only DayDate (X-axis) and 'Series1' as Y-axis.
Highstock chart shows just 'x axis' but no line graph or y axis is shown.
Can someone point me what I'm doing wrong? Any help will be appreciated.
Edit:
After setting turboThresold field I can now see the X Axis on my highstock chart. However values from y axis are still missing.
This is how graph looks without any y axis lines. The data seems to be correct
Here's my updated code -
$(function () {
var mydata = [];
chartOjb = new Object();
// See source code from the JSONP handler at https://github.com/highslide-software/highcharts.com/blob/master/samples/data/from-sql.php
$.getJSON('/ReportIntance/DummyCall/2', function (data) {
// Add a null value for the end date
//data = [].concat(data, [[Date.UTC(2013, 9, 14, 19, 59), null, null, null, null]]);
$.each(data, function (index, item) {
chartOjb.name = new Date(parseInt(item.DayDate.replace("/Date(", "").replace(")/", ""), 10));
chartOjb.data = item.Series1;
mydata.push({ x: chartOjb.name, y: parseFloat(chartOjb.data) });
//alert(chartOjb.name + "/" + chartOjb.data);
});
// create the chart
$('#container').highcharts('StockChart', {
chart: {
//type: 'candlestick',
zoomType: 'x'
},
navigator: {
adaptToUpdatedData: false,
series: {
data: mydata
}
},
scrollbar: {
liveRedraw: false
},
title: {
text: 'Historical prices from June 2012'
},
subtitle: {
text: 'Displaying 20K records using Highcharts Stock by using JSON'
},
plotOptions: {
line: {
turboThreshold: 20450
}
},
xAxis: {
type: 'datetime',
title: 'Time',
minRange: 3600 * 1000/15 // one hour
},
yAxis:{
title: {
text: 'Prices',
style: {
color: '#89A54E'
}
},
lineWidth: 1,
opposite: false,
showEmpty: false //hides empty data series
},
series: [{
data: data,
pointStart: Date.UTC(2012, 6, 1), // first of June
pointInterval: 3600 * 1000/15,
dataGrouping: {
enabled: false
}
}]
});
});
});
Thanks to Sebastian, I can now see the graphs. Only issue I had was that I wasn't pointing to correct 'data' Your suggestion to not convert to datetime improved the performance