Calculate the 85th percentile for yAxis in highcharts - highcharts

I have a chart with multiple series for which I have a button that resets the yAxis to a specific amount. I would like to set this specific amount to be the 85th percentile of the yAxis values. Is there a way to calculate this?
jsfiddle example: http://jsfiddle.net/inadcod/TynwP/

Very strange that you wish to do this on the client, you could very easily sort and get the value of the 85th percentile on the server where you are actually sending the data from and use it as a max value for the y axis.
Anyway, you can access the data values using the series.points object array, this contains all the points for the given series, it has many properties of which point.y seems to be of your interest. Loop through all these and store them in another array for convenience and sort this new array. take the length of the array and multiple by the factor you wish to (0.85) and this is the index of the element a.k.a. 85th percentile. Set the min of the given yAxis using this value
var yData = [];
$.each(chart.series[0].points, function() {
yData.push(this.y);
});
var sortedY = sort(yData);
var eightyFifthPercentile = sortedY[Math.floor(sortedY.length * 0.85)];
alert(eightyFifthPercentile);
http://jsfiddle.net/jugal/HkS2Y/

You can do it this way:
var yAxis = chart.yAxis[0];
var extremes = yAxis.getExtremes();
yAxis.setExtremes(extremes.min, extremes.dataMax * 0.85);
See demo here: http://jsfiddle.net/gyavJ/

Related

Stock High Charts with Custom points on X-axis

I have a requirement where i have to show custom points on x-axis instead of dates values. Also same custom data points needs to be shown on navigator as well. In the below Js fiddle, i am converting data (Per13/2016 etc) into equivalent date values and then binding the chart using converted date values.
Below is the link of the JS fiddle:- Fiddle link
In the Js fiddle, i am showing Per1,Per2 etc.on x-axis and same has to be shown on navigator as well.
Now i am facing problem with the navigator,when i changes the range using slider ,the x-axis labels changes but not according to the range selected.Also tool-tip formatting is getting changed.
Can you please let me know how to handle this scenario and best way to do the same.
//few code lines to post fiddle link
xAxis: {
labels: {
formatter: function () {
if(fiscal13){
var perDate = new Date(this.value);
return 'Per' + (perDate.getMonth() + 1);
}
}
}
}
I am not sure if I am right, but I think you are overdoing this.
Let's keep original data, so remove fiscal13Data.Data.forEach(function(item) { .. }); function. And When creating data, use simply index of the point as x-value:
var cost = [],
usage = [],
dataLength = fiscal13Data.Data.length
i = 0;
for (i; i < dataLength; i += 1) {
// need to sum costs
cost.push([
i, // the index
fiscal13Data.Data[i]['Cost'] // cost
]);
usage.push([
i, // the index
fiscal13Data.Data[i]['Usage'] // Usage
]);
}
Now you can get to the "Per13/2016" strings in a simple way in xAxis labels' formatters:
var str = fiscal13Data.Data[this.value].Date;
In tooltip formatter, it is almost exactly the same:
var str = fiscal13Data.Data[this.x].Date;
And here is working demo: http://jsfiddle.net/qneuh4Ld/3/
Note: You data looks a bit strange - don't you want to sort it first? Also, you have twice every date (e.g. "Per13/2016" - once for "water" and once for "electric").

show only last x points on Highchart

I have a dynamic data series like this
[1,0],[2,0],[3,0],[4,0],[5,0],[6,2],[7,5],[8,6],[9,6],[10,6],[11,7],[12,8],[13,8],[14,9]
The data grows automatically, so later on, an extra data point will be added e.g. [15,13]
I have an input field in which the user can select how many points from the end he wants to show.
For example if he inputs 5, only [10,6],[11,7],[12,8],[13,8],[14,9] should be visible. But when the additional point is added, this should become [11,7],[12,8],[13,8],[14,9],[15,13] automatically.
I think I have to use chart.xAxis[0].setExtremes() but I don't know what to enter as parameters... ?
You will have to "reapply" setExtremes when adding a point. The setExtremes function takes in these parameters (API):
setExtremes (Number min, Number max, [Boolean redraw], [Mixed animation])
You would have to use min and max to show the desired number of points, and have that include the last one. For example, you could do something like this:
var chart = $('#container').highcharts();
var numberOfPointsToShow = 5;
// Add new random point
chart.series[0].addPoint(Math.random() * 25);
// Get index of last point
var lastPoint = chart.series[0].data.length - 1;
// Set extremes to go from "min" (based on last point) to last point
chart.xAxis[0].setExtremes(
lastPoint - (numberOfPointsToShow - 1), // min
lastPoint); // max
See this JSFiddle example with dynamic adding of points.

Highstocks, chart.series[0].data is empty in afterSetExtremes()

I have set up a fiddle which allows you to move the highstock navigator and see underneath the times selected plus a sum of the values for the selected period.
http://jsfiddle.net/o8dLh3m5/3/
The problem I am having is that when the selection contains too much data, the chart.series[0].data array is empty so I can't calculate the total.
Could someone please explain what is happening (ie where is this threshold set?), and what are my options for calculating totals when the data returned is larger than the threshold.
Thanks in advance,
xAxis:{
type: 'datetime',
events: {
afterSetExtremes:function(event){
// convert to dd/mm/yyyy hh:mm
var start_date = new Date(event.min);
var end_date = new Date(event.max);
$('#id_start_date').text( moment(start_date).format('DD/MM/YYYY HH:mm') );
$('#id_end_date').text( moment(end_date).format('DD/MM/YYYY HH:mm') );
// get totals
var sum = 0, chartOb = this;
$.each(chartOb.series, function(series_id){
$.each(chartOb.series[series_id].data, function(i,point){
// array returned is empty!
When number of points exceeds cropThreshold, then array can be empty. I think it would be better to use series.processedYData to calculate that sum. That is just an array with actually displayed y-values on a chart in one series.
Note: It's not part of official API but can be used ;)

Setting Maximum Data Points for Range Selector and Interval

I've got a chart that has a large number of data points. I'm setting the extremes right now so it only shows a smaller number - about 100 or so at a time. The issue I have is I don't want to disable the range selector or the manual input for dates, but currently the user can expand the range selector to include the entire data set. Is there any way to limit this so they can only grab, at most, X number of points?
I don't want to use data grouping either, I have different data for different data groups, so it's important the grouping does not change. Thanks in advance for any pointers on this one!
Unfortunately you can't disable range selector for such purpose, but you can overwrite extremes after user change them, see:
api.highcharts.com/highstock#xAxis.events.afterSetExtremes So for example, if user takes range for 4 days and you want max for 2 days - grab one of min or max, and add/remove two days in extremes (call chart.xAxis.setExtremes() with new extremes). Of course, it will call another afterSetExtremes, so it would be infinite loop, however now extremes will be proper (two days), so it wouldn't call another setExtremes().
Here's a working example of using afterSetExtremes (like Dexter describes) to create a maximum range from the range selector :
http://jsfiddle.net/B7vCR/3/
xAxis: {
minRange:6 * 30 * 24 * 3600 * 1000,
events: {
afterSetExtremes: function(e) {
var maxDistance = 10 * 30 * 24 * 3600 * 1000; //8 months time
var xaxis = this;
if ((e.max - e.min) > maxDistance) {
var min = e.max - maxDistance;
var max = e.max;
window.setTimeout(function() {
xaxis.setExtremes(min, max);
}, 1);
}
}
}
}
From this post
http://forum.highcharts.com/viewtopic.php?f=12&t=21741

Changing data in HighCharts series causes y-axis to blow up

I'm seeing some odd behavior in a Highcharts line chart. I have multiple series displayed, and need to let the user change what's called the "Map level" on the chart, which is a straight line across all time periods. Assuming that the correct series is
chart.series[i]
and that the new level that I want it set to is stored in var newMapLevel,
I'm changing that series' data like so:
data = chart.series[i].data;
for(j=0; j<data.length; j++){
data[j].y = newMapLevel;
}
chart.series[i].setData(data);
Calling this function has the desired effect UNLESS the new map level y_value is ONE greater than the highest y_value of all other series, in which case the y-axis scale blows up. In other words, if the y_axis scale is normally from 0 to 275,000, and the highest y_value of any of the other series is, say, 224,000, setting the new map level value to 224,001 causes the y_axis scale to become 0 to 27500M. Yes, that's 27.5 billion.
Might this be a bug in Highcharts? Or is there a better way to change the data in a series?
I've posted a fiddle: http://jsfiddle.net/earachefl/4FuNE/4/
I got my answer from the Highcharts forum:
http://highslide.com/forum/viewtopic.php?f=9&t=13594&p=59888#p59888
This doesn't work as smoothly as I'd like. When you go from 8 as your line to 2 as your line, the scale doesn't adjust back down until you enter another value. Perhaps it's a start in the right direction.
$(document).ready(function(){
$('#clickme').click(function(){
var newMapLevel = $('#newMAP').val();
if(newMapLevel){
for(i=0; i<chart.series.length; i++){
if(chart.series[i].name == 'Map Level'){
data = chart.series[i].data;
for(j=0; j<data.length; j++){
data[j].y = newMapLevel;
}
// get the extremes
var extremes = chart.yAxis[0].getExtremes();
//alert("dataMin: " + extremes.dataMin);
//alert("dataMax: " + extremes.dataMax);
// define a max YAxis value to use when setting the extremes
var myYMax = extremes.dataMax;
if (newMapLevel >= myYMax) {
myYMax = Number(newMapLevel) + 1; // number conversion required
}
if (myYMax > chart.yAxis[0].max) {
alert('cabbbie');
myYMax = chart.yAxis[0].max + 1;
}
//alert("myYMax: " + myYMax);
chart.yAxis[0].setExtremes(extremes.dataMin, myYMax)
// finally, set the line data
chart.series[i].setData(data);
}
}
}
}); });

Resources