Find points with range between two numbers - javascript

I'm trying to make a stock chart, and were looking for a way to properly split the price on the x-axis and the date (in milliseconds) on the y-axis.
if I for example have 1000 dates, I can't show them all. But would like to show 10.
so if I have two dates 1266278400000 and 1477008000000 Is there some function in javascript that can find 10 evenly spread numbers between them?
The same goes for price, but I guess that's pretty much the same.

I think it's as simple as:
(high - low) / 10
That gets your step size. Then, loop through adding that step size each iteration.

Related

Angular-nvd3: same distance between data on x scale

By default scale of x axis is calculated from values. This gives uneven distance between two adjasted points. Like for example if I have an array of values like [1,2,5], there will be different distance on x axis for point, and also x axis labels will contain some other values, like 1,2,3,4,5. In case on dates displayed on x axis there may be cases when two equal dates are printed, looks ugly.
Take a look at this plunker. If you maximize your browser window, you could see that x axis labels have duplicates (like 02/09/2015 is visible 2 times on my screen). Also the distance between point is different.
How can I:
Make so that no duplicate x axis labes are present?
Distance between points is equaly distributed based in graph's width (not scaled based on values)?
You can explicitly set tickValues() and specify what ticks you want to show.
Alternatively, ticks() is more flexible, but gives you less control.
(Search for "D3 duplicate dates". This one may be helpful for example).
The reason the dates are repeating is that they are in fact different (equally spaced) timestamps that occur on the same day, since the spacing is < 24 hours. If you want to label with distinct dates, you could select a specific time on each day for the tick to fall on.

Calculate percentile rank (Parse)

I need to calculate the percentile rank of a particular value against a large number of values filtered in various different ways. The data is all stored on Parse.com, which has a limitation of returning a maximum of 1000 rows per query. The number of values stored is likely to exceed well over 100,000.
By 'percentile rank', I mean I need to calculate the percentage of values that the provided value is greater than. I am not trying to calculate the value of a provided percentile. For example, given a list of values {20, 23, 24, 29, 30, 31, 35, 40, 40, 43} the percentile rank of the provided value 35 is 70%. The algorithm for this is simply the rank of the value / count of values * 100. Not sure if 'percentile rank' is the correct terminology for this.
I have considered a couple of different approaches to this. The first is to pull down the full list of values (into Parse Cloud) and then calculate the percentile rank from there, then filter the list and calculate again, repeating the last two steps as many times as required. The problem with this approach is it will not work once we reach 1000 values, which we can expect pretty quickly.
Another option, which is the best I can come up with so far, is to query the count of items, and the rank of the provided value. For example:
var rank_world_alltime = new Parse.Query("Values")
.lessThan("value", request.params.value) // Filters query to values less than the provided value, so counting this query will return the rank
.count();
var count_world_alltime = new Parse.Query("Values")
.count();
Parse.Promise.when(rank_world_alltime, count_world_alltime).then(function(rank, count) {
percentile = rank / count * 100;
console.log("world_alltime_percentile = " + percentile);
});
This works well for a single calculation, but I need to perform multiple calculations, and this approach very quickly becomes a lot of queries. I expect to need to run about 15 calculations per call, which is 30 queries. All calculations need to complete in under 3 seconds before Parse terminates the job, and I am limited to 30 reqs/second, so this is very quickly going to become a problem.
Does anyone have any suggestions on how else I could approach this? I've thought about somehow pre-processing some of this but can't quite work out how to do so, as the filters will be based on time and location (city and country), so there are potentially a LOT of pre-calculations that will need to be run at regular intervals. The results do not need to be 100% accurate but something close.
I don't know much about parse, but as far as I understand what you say, it is some kind of cloud database thingy that holds your hiscores, and limits you 1000 rows per query, 3 seconds per job, and 30 queries per second.
In order to have approximate calculations and divide by 2 the number of queries, I would first of all cache the total (count_world_alltime, count_region,week, whatever). If you can save them somewhere locally. For numbers of 100K just getting the order of magnitude (thus not the latest updated number) should be good enough to get a percentile.
Maybe you can get several counts per query. However my lack of expertise in parse/nosql kind of stops me from being sure of this, you'll have to check their documentation. If it is possible however, for the case where you need percentiles for a serie of values all in the same category, I would
Order the values, let's call them a,b,c,d,e (once ordered)
Get the number of values between the intervals [0,a] [a,b] [b,c] [c,d] [d,e]
Use the cached total to get the percentiles (where Nxy is the number of values in [x,y]) :
Pa = 100 * N0a / total
Pb = 100 * ( N0a + Nab ) / total
Pc = 100 * ( N0a + Nab + Nbc ) / total
and so on...
If you need a value ranked worldwide, the other per region, some per week others over all times, etc, this doesn't apply. In that case I don't think you can get below 1 query/number, with caching the totals.

Javascript - dataset too large, need to only include data up to 1000 values that's spaced out evenly

Basically I can only plot 1000 values on a chart but my dataset frequently has more than 1000 values.
So... let's say I have 3000 values - that's easy, every 3rd point is plotted (if i / 3 == 1). What about when it's a number like 2106? I'm trying to plot evenly.
for(var i = 0; i < chartdata.node.length; i++){
//something in here
}
Since your may have more or less than 1000 I would go with something like this
var inc = Math.floor(chartdata.node.length / 1000);
if ( inc==0 )
inc=1;
for ( var i=0; i<chartdata.node.length; i+=inc )
{
}
Exactly 1000 points, slightly irregular spacing
Let A be the number of data points you have (i.e. 2106) and B be the number of data points you want to use (i.e. 1000). In a continuous case, you'd space your plot points at every A/B data points. With discrete data points, you can do the following: maintain a counter C, initialized to zero. For every one of the A input data points, you add B to that counter. If the resulting value is larger than A, you plot the data point and subtract A from the counter. On the whole, you'll have added the value B A times, and subtracted A B times, so you should end up with a zero counter again, having plotted exactly B data items.
You can tweak this to obtain different behaviour at the end points, e.g. to always include the first and last data point. Simply plot the first point unconditionally, then do the above scheme for the remaining points, i.e. with A=2105 and B=999. One benefit of this whole approach is that all of this works in integer arithmetic, so rounding errors will be of no concern to you.
Perfectly regular spacing, but less data points
If even spacing is more important, then you can simply compute the amount by which you want to increment your index for every plot using floor(A/B). Due to the floor function, this will be a smaller number than the fractional resoult would be. In the worst case, a number which is almost two will get rounded down to one, resulting in only slightly more than 500 data points being actually plotted. These will be evenly spaced, though.
You could try something like this (in pseudo-code):
var desired_data_length = 1000;
for (var i = 0; i < desired_data_length; i++)
{
var actual_i = int(float(i) / float(desired_data_length) * float(chartdata.length));
// do something with actual_i as the index
}
This will use desired_data_length number of indices, and will linearly interpolate from [0,desired_data_length) to [0,chartdata.length), which is what you want.
If the data is purely numerical you may try Typed Arrays.

Pie Piece Too Small

I have a dynamic data array that contains 3 ints that are used to build a pie chart. In most cases it works fine IE: [5, 10, 3]. The pie chart renders correctly and you see all the pieces.
However in some cases the numbers can be widely different. IE [1,500,250] or [400,1,2]. When this is the case you will only see the larger of the pie pieces and the smaller ones become so small they can not be seen; or clicked.
I need some way of correcting the data array for these cases. I have the ability to retain the true value while adjusting the display value so the pieces show up. What I am looking for is a check to see if it's necessary and then a relative number to adjust it by based on the other values.
Suggestions?
Well firstly I'd say you aren't so much "correcting" the data as fudging the data to meet your requirements.
Basically, there is a minimum percentage for which a slice of that proportion will be clickable and you will need to bring all pieces up to at least this size.
Of course - this can't work at the most extreme examples. If you had 1,000,000 slices all of the same value then no matter how you scaled them, some of them are going to be too small (or all of them).
You also need to be aware of how scaling certain very small slices will throw out the apparent proportions between other, larger, slices.
But - a very crude way of doing it could be something like...
var minPC = 0.5 , // the minimum %age slice visible
total; // total should be set to the sum of the values of all your slices
var minValue = total / 100 * minPC; // The smallest value visible (given the current total)
for (var slice in slices) { //assuming slices is a standard JS 'array'
if ( slices[slice] < minValue ) slices[slice] = minValue;
}
of course making the slices bigger like this will in turn increase the total - meaning that the small slices will still be less than the minimum visible percentage. You will need to make minPC sufficiently large to cope with this. And of course the more very small slices you have the worse this effect will be. You could account for this be re-scaling the larger slices.
However - I would advise you find a better way of the user interacting with the data by letting them select on/off slices - or by having slices 'explode'.
You seem to want to resize the segments of the pie if they are too small to make them visible/clickable.
May I suggest that instead of solving the problem this way (which would give an invalid
representation of the data), you could instead use labels outside of the pie chart to point at the segments? These labels could then, themselves, be made clickable.
The sum of the values in your array represent the entire "size" of the pie. The percentage of the pie each value has is the visual weight of that piece. You probably want to set a minimum threshold for the percentage size of each piece (the minimum threshold would be related to the diameter of your chart).
ie. [500, 490, 10] -> [500/1000, 490/1000, 10/1000] -> [50%, 49%, 1%]
If any value is less than your minimum threshold, you need to increase it to the minimum threshold and adjust your other values accordingly, so they all add up to 100%
It is related with fact that all points are sum and each value is calculated to pixels.

divide one value by another

I have some code from someone but wondering why they might have used a function like this.
this.viewable= 45;
getGroups: function() {
return Math.ceil( this.getList().length / this.viewable );
}
Why would they divide the list length by a number viewable.
The result is the amount of items that should be rendered on the screen.
Why not just say 45 be the number. Is it meant to be a percentage of the list. Usually I will divide a large value by a smaller value to get the percentage.
Sorry if this seems like a stupid math question but my Math skills are crap :) And just trying to understand and learn some simple Math skills.
It's returning the number of groups (pages) that are required to display the list. The reason it's declared as a variable (vs. using the constant in the formula) is so that it can be modified easily in one place. And likely this is part of a plugin for which the view length can be modified from outside, so this declaration provides a handle to it, with 45 being the default.
That will give the number of pages required to view them all.
I would guess you can fit 45 items on a page and this is calculating the number of pages.
Or something similar to that?
This would return the total number of pages.
Total items = 100 (for example)
Viewable = 45
100 / 45 = 2.22222....
Math.ceil(2.2222) = 3
Therefore 3 pages
judging by the function name "getGroups", viewable is the capacity to show items (probably some interface list size).
By doing that division we know how many pages the data is to be divided (grouped) in order to be viewed on the interface. The ceil functions guarantees that we don't left out partial pages, if we had come records left that don't fill a complete page, we still want to show them and therefor make them count for a page.

Categories