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

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

Related

send email on a change in a cell value with message from another cell

I am new to google scripts. I have a range where the cells in a column change. If the number of a cell from that column is above zero then the script has to send an email with the message being the content from a cell in the same row with the updated cell(that is, different column) Let's say If a value in column I changes then automatically it has to send an email with the message contained in the same row but column F for example. Please see below, I would appreciate some help.
function SendValue() {
var ss = SpreadsheetApp.getActive();
var sheet = ss.getSheetByName("Dividend");
var values = sheet.getRange("I2:I").getValues();
//var values1 = sheet.getRange("G2:G").getValues();
var results = [];
for(var i=0;i<values.length;i++){
if(values[i]>0){
results.push(sheet.getIndex([+i+2]+"G"));
// +2 because the loop start at zero and first line is the second one (I2)
}
}
MailApp.sendEmail('sxxxxxx#gmail.com', 'EX-DIVIDEND', results );
};
getValues() returns a 2 dimensional array, or more accurately an array of arrays, even if one of the dimensions is 1. values[i] is not a value but rather an array representing the i row of the range. You will need to acess that array to get at the cell at a particular column in that row.
replace if(values[i]>0) with if(values[i][0]>0)
I suspect that results.push(sheet.getIndex([+i+2]+"G")); should be results.push(sheet.getRange("G"+(i+2)).getValue()); as getIndex() doesn't take arguments and that looks like it is meant to be A1 notation.
However there is a better option than trying to construct A1Notation.
getRange() supports using numbers to refer to rows and columns. getRange(7, i+2) is a better choice.
https://developers.google.com/apps-script/reference/spreadsheet/range#getvalues
https://developers.google.com/apps-script/reference/spreadsheet/sheet#getRange(Integer,Integer)

Highcharts - Custom X axis format

I'm wondering if it's possible to define a custom ordering or format for the xAxis in highcharts. My dataset has a date time which would be used for the xAxis however my client has specified that it should show the 'Period' on the xAxis. A period is specified as a 30 minute slice - meaning there are 48 periods in a day.
The range of the data is from a period on the previous day to the current day with that period. For example 06/03/2017 Period 11 (10:00) to 07/03/2017 Period 11, the xAxis should look like so:
Currently I've attempted to do this by fiddling with the actual dateTime of each point, so that it is set to Y-m-d H:i:{Period} and then using the dateFormat to only show seconds on the xAxis. However this leaves a gap in data between 2017-03-06 23:59:{Period 48} and 2017-03-07 00:00:{Period 11}
Assuming your series-data is arranged as pairs of [<timestamp in milliseconds>, <value>] you can leave your data alone and simple do calculations and presentation of the label.
To show the labels as we want we use xAxis.labels.formatter (and possibly tickInterval to space them as we want). For example:
xAxis: {
type: 'datetime',
labels: {
formatter: function() {
return createLabelFromTimestamp(this.value);
}
},
tickInterval: 1800000
}
The calculation of the period number (as described in question) can be done for example like this:
function createLabelFromTimestamp(timestamp) {
var hms = timestamp % (1800000 * 48);
var period = hms / 1800000;
// if 0-th period, show date instead
if(period == 0) {
var date = new Date(timestamp);
return date.toDateString();
}
// otherwise show period number
else {
return period;
}
}
We simply modulo away the day and divide to find what 30-minute segment we are in.
See this JSFiddle example of it in action.

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.

Calculate the 85th percentile for yAxis in 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/

Resources