Shifting Issue In Navigator Series in HighCharts - highcharts

There is a peculiar issue i am facing when drawing live chart.
I am adding point to a series every 1 sec and shifting after 14 min.(Added shift condition (14 * 60 + 1)).
Navigator gets points from 1st series and shifts but becomes straight line beyond 14 min.
Navigator series data length also becomes 0.
But Navigator series option data displays right length.
Please find the image in below url
http://postimg.org/image/5xxxq65cn/
Could anyone provide any input on the same ?
function updateChart(data) {
var i, dateTime = new Date(data[0].TimeStamp), signalSeries, shift;
for (i = 0; i < data.length; i += 1) {
signalSeries = chart.get(data[i].Key);
if (signalSeries) {
shift = signalSeries.options.data.length > (14 * 60 + 1);
chart.get(data[i].Key).addPoint([dateTime.getTime(), data[i].Value], false, shift);
}
}
chart.redraw();
}
With Regards,
Tripati Patra

Related

Calculate sum of row but its initial row number and row count

Let's say I have a column of numbers:
1
2
3
4
5
6
7
8
Is there a formula that can calculate sum of numbers starting from n-th row and adding to the sum k numbers, for example start from 4th row and add 3 numbers down the row, i.e. PartialSum(4, 3) would be 4 + 5 + 6 = 15
BTW I can't use App Script as now it has some type of error Error code RESOURCE_EXHAUSTED. and in general I have had issue of stabile work with App Script before too.
As Tanaike mentioned, the error code when using Google Apps Script was just a temporary bug that seems to be solved at this moment.
Now, I can think of 2 possible solutions for this using custom functions:
Solution 1
If your data follows a specific numeric order one by one just like the example provided in the post, you may want to consider using the following code:
function PartialSum(n, k) {
let sum = n;
for(let i=1; i<k; i++)
{
sum = sum + n + i;
}
return sum;
}
Solution 2
If your data does not follow any particular order and you just want to sum a specific number of rows that follow the row you select, then you can use:
function PartialSum(n, k) {
let ss = SpreadsheetApp.getActiveSheet();
let r = ss.getRange(n, 1); // Set column 1 as default (change it as needed)
let sum = n;
for(let i=1; i<k; i++)
{
let val = ss.getRange(n + i, 1).getValue();
sum = sum + val;
}
return sum;
}
Result:
References:
Custom Functions in Google Sheets
Formula:
= SUM( OFFSEET( initialCellName, 0, 0, numberOfElementsInColumn, 0) )
Example add 7 elements starting from A5 cell:
= SUM( OFFSEET( A5, 0, 0, 7, 0) )

Generating random data at 1 minute intervals: Highcharts

I have created a spline real time chart where I want to show points at regular intervals.
Every point is an event taking place after one minute. However I am having a hard time trying to understand all the moving pieces:
the interval function on the highchart demo I referred updated every 1 second, I have made that 6000.
the dummy updating in the javascript just takes the latest time and appends it, is there supposed to be some delay introduced there?
the dummy initialization data in series has a for loop which again I could not understand. I understand that javascript produces a UNIX timestamp and its millisecond manipulation however the default code (again slightly modified from a highchart demo) runs from -9999 to 0 and multiples by a number.
I want to understand these parts and make sure that every time my x axis 'ticks' towards the right, I have a one minute gap and only one point on the graph.
PS: Please forgive any missing brackets, they might have been missed while posting the question, but I assure you that it isnt a problem.
Here is my code for series:
series: [{
type: 'spline',
name: 'Random data',
data: (function () {
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;
for (i = -9999; i <= 0; i += 1) {
data.push([
time + i * 60000,
Math.round(Math.random() * 100) + 10
]);
}
return data;
}())
}]
Here is my code for the chart:
chart: {
events: {
load: function () {
// Set up the updating
var series = this.series[0];
setInterval(function () {
var x = (new Date()).getTime(), // current time
y = Math.round(Math.random() * 100) + 10
series.addPoint([x, y], true, true);
}, 6000);
}
}
}
As to your questions:
If you want to have 1 minute data interval, you need to use 60000 value (60 * 1000), 6000 milliseconds is 6 seconds.
Current date in the interval function is taking every 6000 milliseconds, which causes gaps in the data every 6000 milliseconds.
That data initialization depends on subtracting multiples of six seconds from the current timestamp:
data: (function() {
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;
for (i = -9999; i <= 0; i += 1) {
if (i === -500) {
console.log(time, i, 60000); // 1560941909847 + (-500 * 60000)
console.log(time + i * 60000); // 1560911909847
} else if (i === -499) {
console.log(time, i, 60000); // 1560941909847 + (-499 * 60000)
console.log(time + i * 60000); // 1560911969847
} else if (i === 0) {
console.log(time, i, 60000); // 1560941909847 + (0 * 60000)
console.log(time + i * 60000); // 1560941909847 = actual time
}
data.push([
time + i * 60000,
Math.round(Math.random() * 100) + 10
]);
}
return data;
}())

Creating highstock zoom-in/out button

I have the following problem - I'm trying to create highstock graphic with zoom-in/zoom-out buttons, but something is wrong with the zooming. When i press the button most of the times the chart zooms to the correct time interval, however, after I press the button a couple more times, the chart starts to behave weird - the animations aren't correct or it doesn't zoom or it zooms to the wrong interval.
This is the zooming function:
var xAxis = graphic.xAxis[0];
var minimum = xAxis.dataMin;
var maximum = xAxis.dataMax;
var newMin = 0;
var newMax = 0;
//when zooming out
newMin = xAxis.min - 360000;
newMax = xAxis.max + 360000;
//when zooming in
//newMin = xAxis.min - 360000;
//newMax = xAxis.max + 360000;
if (newMin < minimum)
newMin = minimum;
if (newMax > maximum)
newMax = maximum;
if (newMin > newMax) {
alert("min bigger than max");
}
console.log("newMin: " + newMin + " newMax: " + newMax);
xAxis.setExtremes(newMin, newMax);
Here's a fiddle: http://jsfiddle.net/E5kth/3/
jquery - 1.6.4
jquery mousewheel - 3.1.6
highstock - 1.3.7
Thanks in advance ;]
EDIT:
Here is a NEW video with better explanations of the problem: https://www.dropbox.com/s/5x1k5b0lbtqw81u/highstock_ordinal-false_bug_converted.avi
for better quality - download the video, dropbox streaming is with low quality.
I prepared simple example how it should be done, http://jsfiddle.net/3vB5B/. It get range from chart and then reduce range on 24 hours.
$('#btn').click(function(){
var min = chart.xAxis[0].getExtremes().min,
max = chart.xAxis[0].getExtremes().max;
chart.xAxis[0].setExtremes((min + 12 * 3600 * 1000),(max - 12 * 3600 * 1000)); //12 hrs on min and 12hrs on max, summarised it is one day.
});

Plotting line in linechart according to specific math formula

I have a slightly complicated problem with my line chart.
I manage to make dynamic line chart, so when the user will input some points, they will be drawn on the graph as a line.
Now, my problem here is to add the second line on the graph automatically, according to the inputted values and specific formula that will calculate the second values for the second line.
Let me illustrate what I mean… First it’s drawn one line based on the previously inputted values. Let’s say, user input these values 1.6, 3.9, 3.3, 4.0, 2.5, 2.8…
===============================
The second line needs to be drawn according to this formula, that will loop through the inputted values...
var interestRate1 = 3.5 + inputed_value1 + 0.5 * (inputed_value1 - 3),
interestRate2 = 3.5 + inputed_value2 + 0.5 * (inputed_value2 - 3),
interestRate2 = 3.5 + inputed_value3 + 0.5 * (inputed_value3 - 3), etc…
Eventually the formula will calculate my second values (4.4, 7.85, 6.95, 8, 5.75, 6.2) and this is the outcome that I want to be achieved…
http://img191.imageshack.us/img191/9606/0sfy.png
===============================
On clicking the button “Draw the graph” it needs to be drawn 2 lines, one that is originally inputted from the user, and the second that is calculated by my formula.
Refer to my code here
http://jsfiddle.net/97SRR/4/
(I don’t know why the graph in not showing, it was fine on my index.html file…)
Please help me with this, I will appreciate any ideas about my code.. I have been struggling with this for weeks :(
Here is where you create series:
var sample = {};
sample.name = 'Inflation';
sample.data = [1.6, 3.9, 3.3, 4.0, 2.5, 2.8];
series.push(sample);
So you need just to add one more series, for example:
function calc(data) {
var l = data.length,
ret = [];
for(var i = 0; i < l; i++) {
ret[i] = 3.5 + data[i] + 0.5 * (data[i] - 3);
}
return ret;
}
var sample = {};
sample.name = 'Inflation';
sample.data = [1.6, 3.9, 3.3, 4.0, 2.5, 2.8];
series.push(sample);
var calculated = {};
calculated.name = 'Math formula';
calculated.data = calc(sample.data); // [4.4, 7.85, 6.95, 8, 5.75, 6.2]; - calculated data
series.push(calculated);

Scaling a number between two values

If I am given a floating point number but do not know beforehand what range the number will be in, is it possible to scale that number in some meaningful way to be in another range? I am thinking of checking to see if the number is in the range 0<=x<=1 and if not scale it to that range and then scale it to my final range. This previous post provides some good information, but it assumes the range of the original number is known beforehand.
You can't scale a number in a range if you don't know the range.
Maybe what you're looking for is the modulo operator. Modulo is basically the remainder of division, the operator in most languages is is %.
0 % 5 == 0
1 % 5 == 1
2 % 5 == 2
3 % 5 == 3
4 % 5 == 4
5 % 5 == 0
6 % 5 == 1
7 % 5 == 2
...
Sure it is not possible. You can define range and ignore all extrinsic values. Or, you can collect statistics to find range in run time (i.e. via histogram analysis).
Is it really about image processing? There are lots of related problems in image segmentation field.
You want to scale a single random floating point number to be between 0 and 1, but you don't know the range of the number?
What should 99.001 be scaled to? If the range of the random number was [99, 100], then our scaled-number should be pretty close to 0. If the range of the random number was [0, 100], then our scaled-number should be pretty close to 1.
In the real world, you always have some sort of information about the range (either the range itself, or how wide it is). Without further info, the answer is "No, it can't be done."
I think the best you can do is something like this:
int scale(x) {
if (x < -1) return 1 / x - 2;
if (x > 1) return 2 - 1 / x;
return x;
}
This function is monotonic, and has a range of -2 to 2, but it's not strictly a scaling.
I am assuming that you have the result of some 2-dimensional measurements and want to display them in color or grayscale. For that, I would first want to find the maximum and minimum and then scale between these two values.
static double[][] scale(double[][] in, double outMin, double outMax) {
double inMin = Double.POSITIVE_INFINITY;
double inMax = Double.NEGATIVE_INFINITY;
for (double[] inRow : in) {
for (double d : inRow) {
if (d < inMin)
inMin = d;
if (d > inMax)
inMax = d;
}
}
double inRange = inMax - inMin;
double outRange = outMax - outMin;
double[][] out = new double[in.length][in[0].length];
for (double[] inRow : in) {
double[] outRow = new double[inRow.length];
for (int j = 0; j < inRow.length; j++) {
double normalized = (inRow[j] - inMin) / inRange; // 0 .. 1
outRow[j] = outMin + normalized * outRange;
}
}
return out;
}
This code is untested and just shows the general idea. It further assumes that all your input data is in a "reasonable" range, away from infinity and NaN.

Resources