Highchart Callback Refactoring not working, and how to display multiple series using multiple Ajax data - highcharts

I am working on a project utilizing highcharts and highstocks. I ran into 2 problems that I like to ask for your help on.
How do I code a highchart with a multiple series with each series getting its data source from a distinct Ajax call? The example on the Highcharts website only shows either a single Ajax source or a multiple series chart with pre-populated dummy data.
I am trying to separate the draw of highchart from the ajax call function, since the embedded callback method used to draw the chart can get a little hard to read. But when I factored out the highcharts drawing code from the call back section, the highchart display no longer works, ie the highcharts call does not return anything. For example:
this work:
$.getJSON(myUrl, function(data){
$('#ajax-panel').highcharts('chart', {
rangeSelector : {
selected : 1
},
title : {
text : 'analysis chart'
},
series : [
{
name : 'dataseries',
data : data,
id : 'dataseries',
tooltip: {
valueDecimals: 2
}
}
]
});
this does not work, although syntax wise I don't see anything wrong.
$.getJSON(myUrl, function(data){
drawChart(data);
});
function drawChart(data){
$('#ajax-panel').highcharts('chart', {
rangeSelector : {
selected : 1
},
title : {
text : 'analysis chart'
},
series : [
{
name : 'dataseries',
data : data,
id : 'dataseries',
tooltip: {
valueDecimals: 2
}
}
]
});
};
Thanks!

1) You need to get all series and push into one array, then in highcharts refer to it. What is important, chart should be initialised in the callback of last ajax.
When / then() jquery functions should be also helpful.
2) Syntax seems to be correct, please check your console (click F12 / developer tools) and observe if you get any errors.

Related

Drilldown event in Highcharts column chart

In this Highcharts column chart the user can drill down by clicking on the column.
This works fine, however all the data, including the data of the drilled column, needs to be available when the chart is firstly created.
What I need is to capture the drilldown event click and populate the chart with that information, sending the data only when the user clicked on a specific column. Is this possible?
Yes, it is possible and simple. You need to use drilldown event callback function, call API request in it and use addSeriesAsDrilldown method - as in the example below:
chart: {
type: 'column',
events: {
drilldown: function(e) {
if (!e.seriesOptions) {
var chart = this,
drilldowns = {
...
},
series = drilldowns[e.point.name];
// Show the loading label
chart.showLoading('Simulating Ajax ...');
setTimeout(function() {
chart.hideLoading();
chart.addSeriesAsDrilldown(e.point, series);
}, 1000);
}
}
}
}
Live demo: https://jsfiddle.net/BlackLabel/e9m74kgp/
API Reference:
https://api.highcharts.com/highcharts/chart.events.drilldown
https://api.highcharts.com/class-reference/Highcharts.Chart#addSeriesAsDrilldown

Call addSeries() from within addSeries event

I want to add a reference series to my charts (i.e. a reference price). Axis.addPlotLine() does it, but I want to be able to toggle this series from the legend; a plain plotLine does not show up in the graph's legend.
Another reason why plotLine does not seem like a good solution is that it does not get accounted for by the viewport calculations. Which means that toggling other series might lead to the plotLine appearing outside the viewport due to zooming.
The simplest way to accomplish what I want would be, to add a dynamic series via chart.addSeries. But it's impossible to call this method from within a triggered addSeries event because chart.addSeries is set to null while in the event handler.
Tying in to the redraw event creates a whole lot of difficulties as well, because render() can't be called anymore.
How would you go about it?
Update:
As per the comment of Pawel Fus, I unsuccessfully tried the following:
[…]
events: {
load: function (event) {
foo = this;
},
addSeries: function(event) {
console.log(foo) // returns chart object as expected
console.log(foo.addSeries) // undefined
}
}
Solution is to store addSeries on load event, and use stored function when adding series. Live example: http://jsfiddle.net/3bQne/808/
events: {
load: function (event) {
foo = this.addSeries;
},
addSeries: function (event) {
if (iterator) {
iterator--;
foo.call(this, {
data: [100, 200, 100, 100, 200, 300]
});
}
}
},
Still you can stick with plotLine only.
If the position of the line is static that is the best way.
If the position is dynamic then you can still go with plotLine.
There are events for adding and removing plotLine on the fly.
API link
removePLotLine() : http://api.highcharts.com/highcharts#Axis.removePlotLine
addPlotLine() : http://api.highcharts.com/highcharts#Axis.addPlotLine
I hope this will help you.

One label for multiple series

I need to make one label responsible for multiple series data.
As shown in this fiddle http://jsfiddle.net/HHqGN/ , I have two series:
test(bid) and test(ask) and two labels responsible for each of them.
What I need is one label named test instead of these two to toggle both serie 1 and serie 2 at the same time
Sample code from fiddle:
$(function() {
// Create the chart
$('#container').highcharts('StockChart', {
rangeSelector : {
enabled : false
},
legend : {
enabled : true
},
series : [{
name : 'test(bid)',
data : [[1152057600000,57.00]
}, {
name : 'test(ask)',
data : [[1152057600000,58.00]
}]
});
});
You can disable displaying second serie in legend, by showInLegend parameter and then use legendItemClick to show/hide both series
http://jsfiddle.net/HHqGN/1/
legendItemClick:function(){
$.each(this.chart.series,function(i,serie){
if(serie.visible)
serie.hide();
else
serie.show();
});
return false;
}
In case anyone is looking for linked series have a look at the linkedTo parameter of a series. As per definition:
linkedTo: StringSince 3.0
The id of another series to link to. Additionally, the value can be
":previous" to link to the previous series. When two series are
linked, only the first one appears in the legend. Toggling the
visibility of this also toggles the linked series.
Source: http://api.highcharts.com/highcharts

Determining the chart id (Highcharts)

I have three highcharts containers on the same page and want to create a function which is available to all charts, so I have defined the function in setOptions. The function is working well but I don't know which graph has triggered the event.
How do I know which chart triggered the event?
plotOptions: {
series: {
cursor: 'pointer',
allowPointSelect: true,
point: {
events: {
select: function () {
alert($(this).attr('id')); // I need this to be the chart id
}
}
},
Two ways:
use this.series.chart.options.chart.renderTo to get string you have passed when creating chart
use this.series.chart.renderTo.id to get ID's string, (will be the same as above).
You can use this.series.chart to get the chart object that was clicked. I'm not sure how you're assigning an "ID" to your chart, but presumably having a handle to the chart itself will be sufficient.

Highstocks rounding values, and range not accurate for more then two hours of viewing

I am using highcharts to perform sensor graphing for basic temperatures, or things of that nature. The issue is I have the current default view set at 3 days, but at that view it distorts the y axis data values.
For example, if the majority of the data is 1.5 but there is a value of 10 also, in the three day view the y axis is only showing a range up to 3 or 4. It shows the spike in the actual line graph however when you hover over the point the value is 3 or 4 instead of 10. However, if I shrink the view to 2 hours, the data gets displayed properly and the value then returns to 10 and the y axis accomodates the 10 value.
Also I am having issues with the data being rounded down constantly it seems, since the values should be a steady 1.5 it is constantly being rounded down to 1.
Any help will be appreciated and I will be around the computer all day to answer any questions that someone might have about this issue.
$.getJSON('mkjson.php?device=<?echo $device_name;?>&sensor=<?echo $sensor_name;?>&pin=<?echo $pin;?>&user=<?echo $_SESSION['user'];?>', function(data) {
// Create the chart
window.chart = new Highcharts.StockChart({
chart : {
renderTo : 'container',
zoomType: 'x'
},
rangeSelector : {
selected : 1
},
title : {
text : 'Device:<?echo $device_name;?>'
},
subtitle : {
text : 'Sensor:<?echo $sensor_name;?>'
},
xAxis : {
minRange: 600 * 1000 // one hour
},
yAxis : {
title : {
text : '<?echo $unit;?>'
}
},
rangeSelector : {
buttons : [{
type : 'minute',
count : 10,
text : '10m'
}, {
type : 'hour',
count : 1,
text : '1H'
}, {
type : 'day',
count : 1,
text : '1D'
},
{
type : 'day',
count : 3,
text : '3D'
}],
selected : 3,
inputEnabled : false
},
series : [{
name : 'Voltage',
data : data,
tooltip: {
valueDecimals: 2
}
}]
});
});
This is the example of how the data is skewed. The high points to the right are 10, and 13 yet they show up at only 3.
Have a look at dataGrouping as it lets you determine how to group or to have it off completely. It defaults to enabled.
Have you tried to use numberFormat() http://api.highcharts.com/highstock#highcharts.numberFormat()
I've been burned by the auto-rounding; the chart does some sort of value rounding for its internal representation of points.
I only have a workaround - I got around it by storing the data points in a separate array and referencing THAT in the tooltip function.
As of note, if you're using column data and don't turn data grouping off, the chart will round your X values too.

Resources