You'll have to forgive the phrasing of this question, I'm sure there's a better, more succinct way to ask it, but I don't know it.
Let's say I have a graph, and all the y-axis values are
[0,4,5,3,2,5,6]
The maximum value is six. So I would like the Y-Scale to be labeled from 0 to 10.
Given the following values
[33,26,54,23,86,23]
The maximum value is 86, so I would like the Y-Scale to go from 0 to 90.
Now let's say I have the following values
[98,253,87, 876,263]
The max is 876,so the Y-scale should go from 0 to 900
Now I have created the following function that should give me all the max y-scale values I need so far.
function padMaxValue(value){
for(var i = 1; i < 1000000000000000000; i = i * 10){
var decimalValue = value / i;
if(value === i){
return i;
}
if(decimalValue < 1 && decimalValue > 0.09){
return i;
}
}
}
However, given the following values
[99,123,82,189,45]
My function would set the y-scale max to 1000
. But the max should really be 200. I realise that what I really need is a smarter way to increase the value of i
instead of just multiplying it by 10. I need to be able to increase the value of i by 10, all the way up to 100. Then increase it by 100, all the way up to 1000. Then increase it by 1000, all the way up to 10,000 and so on.
I feel like there should be some neat and tidy mathematical way to do this. And I also feel that the 1000000000000000000
number I have in the for loop betrays my ignorance of mathematics.
Anyhoot, that's the problem. Any ideas?
There is no need to go into the land of strings, which could be awkward if you ever had a decimal value.
function RoundedMax(a) {
var mx = Math.max.apply(Math, a);
if (mx == 0) {return 0};
var size = Math.floor(Math.log(Math.abs(mx)) / Math.LN10);
var magnitude = Math.pow(10, size);
var yMax = Math.ceil(mx / magnitude) * magnitude;
return yMax;
}
function RoundedMin(a) {
var mn = Math.min.apply(Math, a);
if (mn == 0) {return 0};
var size = Math.floor(Math.log(Math.abs(mn)) / Math.LN10);
var magnitude = Math.pow(10, size);
var yMin = Math.floor(mn / magnitude) * magnitude;
return yMin;
}
var arr = [-9.9,-1.23,-8.2,-2.01,-4.5,0];
document.write(RoundedMax(arr) + " " + RoundedMin(arr));
Outputs: 0 -10
.
EDIT Updated in view of the comments. Now works even in IE8.
Now (2023) that all current browsers support ECMAScript 6:
function RoundedMax(a) {
var mx = Math.max.apply(Math, a);
if (mx == 0) {return 0};
var size = Math.floor(Math.log10(Math.abs(mx)));
var magnitude = Math.pow(10, size);
var yMax = Math.ceil(mx / magnitude) * magnitude;
return yMax;
}
function RoundedMin(a) {
var mn = Math.min.apply(Math, a);
if (mn == 0) {return 0};
var size = Math.floor(Math.log10(Math.abs(mn)));
var magnitude = Math.pow(10, size);
var yMin = Math.floor(mn / magnitude) * magnitude;
return yMin;
}