Reputation: 274
How can I specify a 20% value and a 100% value using Javascript?
This is my current code: ${Math.floor((scooter.attributes.meter_range / 24140) * 100)}%
I want to change it so that 965 = 20% and 24140 = 100%
This is what I'm currently getting when I have it set to 965 = 20%:
The battery should be at minimum 20% and at maximum 100%
How can I do this?
Sorry for not explaining it very clearly.
Upvotes: 0
Views: 198
Reputation: 13245
Assuming you want a linear conversion, since you only specified two points, we can use some algebra to solve your problem.
First, find the slope.
or in other words,
The variable m
is used in mathematics to describe the slope. With two points, we can use this formula to find the slope:
And for this case, we will use these values for x1, x2, y1, and y2:
x1 = 965
x2 = 24140
y1 = 20 //(Using whole numbers since you're already adding the % sign)
y2 = 100
So substituting, we get:
So m
is about 0.00344976282881
(you would calculate this on the fly in code, not hardcode it)
So we have the slope now. What next? We need to find the y-intercept and the entire function.
Using the point-slope form, we can find these two last things.
The point-slope form looks like this:
And some rearranging:
And replacing:
(Note: the slope is truncated just for viewing)
So now we have a function.
To generalize it, we need to recombine all the formulas.
Converting this into a JavaScript function: (I'm using ES6 style function)
const linearRescale = (x, x1, y1, x2, y2) => ((y2 - y1)/(x2 - x1))*(x - x1) + y1;
Here's a snippet to show this working:
const linearRescale = (x, x1, y1, x2, y2) => ((y2 - y1)/(x2 - x1))*(x - x1) + y1;
console.log(linearRescale(965, 965, 20, 24140, 100)); // 20
console.log(linearRescale(24140, 965, 20, 24140, 100)); // 100
// Without flooring
console.log(linearRescale(8000, 965, 20, 24140, 100));
console.log(linearRescale(16000, 965, 20, 24140, 100));
console.log(linearRescale(20000, 965, 20, 24140, 100));
// With flooring (~~ truncates the number)
// Use Math.floor though, this is just for cleanliness here
console.log(~~linearRescale(8000, 965, 20, 24140, 100));
console.log(~~linearRescale(16000, 965, 20, 24140, 100));
console.log(~~linearRescale(20000, 965, 20, 24140, 100));
Another thing you can do, if using something like this again, but you're doing it multiple times is to use currying. In basic terms, currying returns a function.
const linearRescale = (x1, y1, x2, y2) => x => ((y2 - y1)/(x2 - x1))*(x - x1) + y1;
const linearRescale = (x1, y1, x2, y2) => x => ((y2 - y1)/(x2 - x1))*(x - x1) + y1;
const myLinear = linearRescale(965, 20, 24140, 100);
console.log(myLinear(965)); // 20
console.log(myLinear(24140)); // 100
// Without flooring
console.log(myLinear(8000));
console.log(myLinear(16000));
console.log(myLinear(20000));
// With flooring (~~ truncates the number)
// Use Math.floor though, this is just for cleanliness here
console.log(~~myLinear(8000));
console.log(~~myLinear(16000));
console.log(~~myLinear(20000));
Now that we have these results, just concatenate with "%"
and you have your battery percentage.
const linearRescale = (x1, y1, x2, y2) => x => ((y2 - y1)/(x2 - x1))*(x - x1) + y1;
const myLinear = linearRescale(965, 20, 24140, 100);
console.log(`${myLinear(965)}%`); // 20
console.log(`${myLinear(24140)}%`); // 100
// Without flooring
console.log(`${myLinear(8000)}%`);
console.log(`${myLinear(16000)}%`);
console.log(`${myLinear(20000)}%`);
// With flooring (~~ truncates the number)
// Use Math.floor though, this is just for cleanliness here
console.log(`${~~myLinear(8000)}%`);
console.log(`${~~myLinear(16000)}%`);
console.log(`${~~myLinear(20000)}%`);
Here's a Desmos link of your equation: https://www.desmos.com/calculator/xmrbpugvdx
Upvotes: 3