Highcharts strange grouping behaviour - javascript

I am using the lazy loading method to load OHLC data. On the server side I use Python + MySQL and have 4 tables with OHLC data and time intervals of 5min, 1hour, 1day, 1month. Actually it works well, but unfortunately Highcharts displays the candlesticks in a strange way. Especially at the initial loading and when I switch between the zooms. Here are some examples:
1. Grouping on chart initialization
On initial Loading 6h, 24h & 3d is disabled and the candlesticks are wide apart.
Only after clicking then the first time 1w the chart displays as follows, which is correct and also the zoom buttons 6h, 24h & 3d are enabled now.
2. Grouping when clicking between the rangeSelector buttons
If I click then All inside the Range Selector I get the following display (this is wrong):
Only after clicking 1m and then back on AllI get the right display:
Does anybody know whats going on? Many thanks in advance! Here is the code:
<script>
$(function () {
function afterSetExtremes(e) {
var chart = Highcharts.charts[0];
$.getJSON('http://ipaddress/data3?start=' + Math.round(e.min / 1000) +
'&end=' + Math.round(e.max / 1000), function (data) {
chart.series[0].setData(data);
chart.hideLoading();
});
}
//Initially load the biggest data range
$.getJSON('http://ipaddress/data3?start=1481897400&end=1486910100', function (data) {
// Add a null value for the end date
//data = [].concat(data, [[Date.UTC(2011, 9, 14, 19, 59), null, null, null, null]]);
// create the chart
Highcharts.stockChart('container', {
chart: {
type: 'candlestick',
zoomType: 'x'
},
navigator: {
adaptToUpdatedData: false,
series: {
data: data
}
},
scrollbar: {
liveRedraw: false
},
rangeSelector: {
buttons: [{
type: 'hour',
count: 6,
text: '6h',
dataGrouping: {
forced: false,
units: [['minute', [15]]]
}
}, {
type: 'hour',
count: 24,
text: '24h',
dataGrouping: {
forced: false,
units: [['minute', [30]]]
}
}, {
type: 'day',
count: 3,
text: '3d',
dataGrouping: {
forced: false,
units: [['hour', [2]]]
}
}, {
type: 'day',
count: 7,
text: '1w',
dataGrouping: {
forced: false,
units: [['hour', [4]]]
}
}, {
type: 'day',
count: 30,
text: '1m',
dataGrouping: {
forced: false,
units: [['day', [1]]]
}
}, {
type: 'all',
text: 'All'
}],
inputEnabled: false,
selected: 3 // Init loading button
},
xAxis: {
events: {
afterSetExtremes: afterSetExtremes
},
//minRange: 3600 * 1000 // one hour
},
yAxis: {
floor: 0
},
series: [{
data: data,
dataGrouping: {
enabled: true
}
}]
});
});
});

Here is the solution:
1. No grouping on chart init
To solve the grouping problem at the initialization stage, use the following lines:
Highcharts.stockChart('container', {
//.... your code ...
}, function(chart){
chart.rangeSelector.clickButton(1);
});
The problem here was that the selected button from chart options was not triggering afterSetExtremes event for xAxis.
1. No grouping when clicking the rangeSelector
To avoid Highcharts grouping the data when clicking between the rangeSelector buttons, set the chart as follows:
rangeSelector: {
buttons: [{
dataGrouping: {
forced: false }
}] }

Related

Highcharts Initialize Zoom & Grouping [duplicate]

I am using the lazy loading method to load OHLC data. On the server side I use Python + MySQL and have 4 tables with OHLC data and time intervals of 5min, 1hour, 1day, 1month. Actually it works well, but unfortunately Highcharts displays the candlesticks in a strange way. Especially at the initial loading and when I switch between the zooms. Here are some examples:
1. Grouping on chart initialization
On initial Loading 6h, 24h & 3d is disabled and the candlesticks are wide apart.
Only after clicking then the first time 1w the chart displays as follows, which is correct and also the zoom buttons 6h, 24h & 3d are enabled now.
2. Grouping when clicking between the rangeSelector buttons
If I click then All inside the Range Selector I get the following display (this is wrong):
Only after clicking 1m and then back on AllI get the right display:
Does anybody know whats going on? Many thanks in advance! Here is the code:
<script>
$(function () {
function afterSetExtremes(e) {
var chart = Highcharts.charts[0];
$.getJSON('http://ipaddress/data3?start=' + Math.round(e.min / 1000) +
'&end=' + Math.round(e.max / 1000), function (data) {
chart.series[0].setData(data);
chart.hideLoading();
});
}
//Initially load the biggest data range
$.getJSON('http://ipaddress/data3?start=1481897400&end=1486910100', function (data) {
// Add a null value for the end date
//data = [].concat(data, [[Date.UTC(2011, 9, 14, 19, 59), null, null, null, null]]);
// create the chart
Highcharts.stockChart('container', {
chart: {
type: 'candlestick',
zoomType: 'x'
},
navigator: {
adaptToUpdatedData: false,
series: {
data: data
}
},
scrollbar: {
liveRedraw: false
},
rangeSelector: {
buttons: [{
type: 'hour',
count: 6,
text: '6h',
dataGrouping: {
forced: false,
units: [['minute', [15]]]
}
}, {
type: 'hour',
count: 24,
text: '24h',
dataGrouping: {
forced: false,
units: [['minute', [30]]]
}
}, {
type: 'day',
count: 3,
text: '3d',
dataGrouping: {
forced: false,
units: [['hour', [2]]]
}
}, {
type: 'day',
count: 7,
text: '1w',
dataGrouping: {
forced: false,
units: [['hour', [4]]]
}
}, {
type: 'day',
count: 30,
text: '1m',
dataGrouping: {
forced: false,
units: [['day', [1]]]
}
}, {
type: 'all',
text: 'All'
}],
inputEnabled: false,
selected: 3 // Init loading button
},
xAxis: {
events: {
afterSetExtremes: afterSetExtremes
},
//minRange: 3600 * 1000 // one hour
},
yAxis: {
floor: 0
},
series: [{
data: data,
dataGrouping: {
enabled: true
}
}]
});
});
});
Here is the solution:
1. No grouping on chart init
To solve the grouping problem at the initialization stage, use the following lines:
Highcharts.stockChart('container', {
//.... your code ...
}, function(chart){
chart.rangeSelector.clickButton(1);
});
The problem here was that the selected button from chart options was not triggering afterSetExtremes event for xAxis.
1. No grouping when clicking the rangeSelector
To avoid Highcharts grouping the data when clicking between the rangeSelector buttons, set the chart as follows:
rangeSelector: {
buttons: [{
dataGrouping: {
forced: false }
}] }

highcharts - 2 date picker questions

1) I am wondering how I can remove the date picker from the right side of the chart? I really only need the left rangeSelector buttons i.e. 24 hours, 6 hours...
2) is there anyway to turn off the dataLabels when you click on one of the rangeSelector options as well?
When zoomed in to show 5 minutes worth of data the dataLabels are handy, but when looking at 24 hours worth they make the chart quite unusable due to crowding. It would be nice if they could be automagically turned off when I zoomed out.
Huge thanks for your help, if this is indeed possible.
For the second option, i'm looking to toggle the visibility of
plotOptions:{series: {
dataLabels:{
enabled:true,
Fiddle Link
After customization of range selector from Highstock Example
/**
* Load new data depending on the selected min and max
*/
function afterSetExtremes(e) {
var chart = Highcharts.charts[0];
chart.showLoading('Loading data from server...');
$.getJSON('https://www.highcharts.com/samples/data/from-sql.php?start=' + Math.round(e.min) +
'&end=' + Math.round(e.max) + '&callback=?', function (data) {
chart.series[0].setData(data);
chart.hideLoading();
});
}
// See source code from the JSONP handler at https://github.com/highcharts/highcharts/blob/master/samples/data/from-sql.php
$.getJSON('https://www.highcharts.com/samples/data/from-sql.php?callback=?', function (data) {
// Add a null value for the end date
data = [].concat(data, [[Date.UTC(2011, 9, 14, 19, 59), null, null, null, null]]);
// create the chart
Highcharts.stockChart('container', {
chart: {
type: 'candlestick',
zoomType: 'x'
},
navigator: {
adaptToUpdatedData: false,
series: {
data: data
}
},
scrollbar: {
liveRedraw: false
},
title: {
text: 'AAPL history by the minute from 1998 to 2011'
},
subtitle: {
text: 'Displaying 1.7 million data points in Highcharts Stock by async server loading'
},
rangeSelector: {
buttons: [{ //customization of buttons
type: 'hour',
count: 24,
text: '24h'
}, {
type: 'hour',
count: 6,
text: '6h'
}, {
type: 'minute',
count: 5,
text: '5m'
}],
inputEnabled: false, // it remove datepicker
},
xAxis: {
events: {
afterSetExtremes: afterSetExtremes,
setExtremes: function(e) {
if(typeof(e.rangeSelectorButton)!== 'undefined')
{
if(e.rangeSelectorButton.text=='5m'){
addlables(); //function to add data label
}else{
removelables(); // function to remove data lable
}
}
}
},
minRange: 300 * 1000 // 5min * 1000
},
yAxis: {
floor: 0
},
plotOptions:{
series: {
dataLabels:{
enabled:false,
}
}
},
series: [{
data: data,
dataGrouping: {
enabled: false
}
}]
});
});
function removelables(){
var chart = $('#container').highcharts();
var opt = chart.series[0].options;
opt.dataLabels.enabled = false;
chart.series[0].update(opt);
}
function addlables(){
var chart = $('#container').highcharts();
var opt = chart.series[0].options;
opt.dataLabels.enabled = true;
chart.series[0].update(opt);
}

Loading millions of points with Highcharts

I have a json dataset with millions of points.The structure is like this:
[[1436997600000,7],[....]]
The first number is a data and second one is a value.
I want to plot this in a highchart so that it doesn't take so much time to load the chart and to navigate in it. I followed this example: http://www.highcharts.com/stock/demo/lazy-loading
but can't get it work with my data. It take so much time to load and when I zoom the message 'loading from server' doesn't disappear. Can anyone help me on this please?
JS:
$(function () {
/**
* Load new data depending on the selected min and max
*/
function afterSetExtremes(e) {
var chart = $('#container').highcharts();
chart.showLoading('Loading data from server...');
$.getJSON('http://localhost/public_html/webservice.php/re/pap/' + Math.round(e.min) + '/' + Math.round(e.max), function (data) {
chart.series[0].setData(data);
chart.hideLoading();
});
}
// See source code from the JSONP handler at https://github.com/highcharts/highcharts/blob/master/samples/data/from-sql.php
$.getJSON('http://localhost/public_html/webservice.php/re/pap', function (data) {
// Add a null value for the end date
data = [].concat(data, [[Date.UTC(2016, 9, 14, 19, 59), null]]);
// create the chart
$('#container').highcharts('StockChart', {
chart : {
type: 'scatter',
zoomType: 'x'
},
navigator : {
adaptToUpdatedData: false,
series : {
data : data
}
},
scrollbar: {
liveRedraw: false
},
title: {
text: 'AAPL history by the minute from 1998 to 2011'
},
subtitle: {
text: 'Displaying 1.7 million data points in Highcharts Stock by async server loading'
},
rangeSelector : {
buttons: [{
type: 'hour',
count: 1,
text: '1h'
}, {
type: 'day',
count: 1,
text: '1d'
}, {
type: 'month',
count: 1,
text: '1m'
}, {
type: 'year',
count: 1,
text: '1y'
}, {
type: 'all',
text: 'All'
}],
inputEnabled: false, // it supports only days
selected : 4 // all
},
xAxis : {
events : {
afterSetExtremes : afterSetExtremes
},
minRange: 3600 * 1000 // one hour
},
yAxis: {
floor: 0
},
series : [{
data : data,
dataGrouping: {
enabled: false
}
}]
});
});
});
Fiddle: http://jsfiddle.net/f0u5c4pg/
Thanks in advance!

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);

Highstock, Dynamically add Points, a definied time span at the beginning

I have the following issue:
I want to dynamically update a hightstock Chart with Points from Ajax Calls. For Example i use setInterval(addPoints,3000); How can i develope the code, that the highstock Charts display an definied time, e.g. 1 Minute, and the Chart beginn to draw from the Left without this "time poping and squeezing? For a testrun i tried to you predifned null points, but the interval is not fix.
var value1="valueNo1";
var value2="valueNo2";
var color1="green";
var color2="red";
$(function () {
$('#container').highcharts('StockChart',{
chart: {
type: 'spline',
zoomtype: 'z'
},
title: {
text: 'Live random data'
},
navigator: {
top: 500
},
legend: {
enabled: true
},
rangeSelector: {
buttons: [{
count: 30,
type: 'second',
text: '30s'
}, {
count: 1,
type: 'minute',
text: '1M'
}, {
count: 2,
type: 'minute',
text: '2M'
}, {
count: 5,
type: 'minute',
text: '5M'
}, {
type: 'all',
text: 'All'
}],
inputEnabled: false,
selected: 1
},
xAxis: {
type: 'datetime'
}
});
});
var chart = $('#container').highcharts();
var ct = (new Date()).getTime();
// addAxis
chart.addAxis({ labels: { format: '{value}' , style: {color: color1 } }, title: { text: value1 , style: {color: color1} } , lineColor: color1, lineWidth: 0, opposite:true } );
chart.addAxis({ labels: { format: '{value}', style: {color: color2 } }, title: { text: value2 , style: {color: color2} } , lineColor: color2, lineWidth: 0 } );
// addSeries
chart.addSeries({ "name": "value1","data": [], yAxis: 2, marker: {enabled:true, radius: 5 }});
// addPoint
var current_time = (new Date()).getTime();
chart.series[0].addPoint([current_time+64000, null], false);
addPoints = function(){
var current_time = (new Date()).getTime();
chart.series[0].addPoint([current_time, Math.random()*10], false);
chart.redraw();
}
setInterval(addPoints,3000);
Please see jsFiddle demo of the issue :
http://jsfiddle.net/ehonk/FLzRH/1/
Please help
The "popping" is the data being added and the line connecting the last point to the new point and the yAxis re-scaling. To minimize this I would set the yAxis.max to a value that is the maximum possible. Secondly I would look at the animation and see which kind you want to use when it adds a new point.
To handle the "sqeezing" you can set your "viewable" range and your adding of points such that when you add a new point the last point on the left falls out of the viewable area.
You can also call setExtremes to set range on the xAxis.

Categories

Resources