Question

I have a JavaScript slider that outputs a value between 0 and 1 depending on its position. I want to convert that value to a value on another scale between say 100 and 1000, but based on the distribution of a set of data points between 100 and 1000.

The use case here is that I want the slider to be less sensitive to changes when there is a very close set of numbers. Eg... let's say the values in the scale are:

100, 200, 300, 500, 1000

The values 100-500 might take up, say, the first 80% of the slider due to their closer distribution, therefore making it easier to select between them.

There's clearly a mathematical function for calculating this, perhaps involving standard deviation and coefficients. Anyone know what it is?

Was it helpful?

Solution

Using linear interpolation between the values on the large scale, something like

var bigValues = [100, 200, 300, 500, 1000];
var input; /* will vary in the range [0.0..1.0] */
var idx; /* index of nearest entry in bigValues below input */
var frac; /* fraction [0.0..1.0) in interval in bigValues */
var output;
/* try some test values for input */
for (var i = 0; i<=20; i++) {
    input = i * 0.05;
    idx = Math.floor(input * (bigValues.length - 1));

    frac = (input - (idx) / (bigValues.length - 1)) * (bigValues.length - 1);
    if (frac == 0) { /* no need to calculate */
        output = bigValues[idx];
    }
    else {
        output = bigValues[idx] + (bigValues[idx+1] - bigValues[idx]) * frac;
    };
    document.write(input + ', ' + output + '<br />');
}

OTHER TIPS

I would think that any sort of polynomial equation, using the slider values as the independent variable would work. The specific equation would depend on your specific needs / distribution.

For example, -1 * (X^2) would give you an even inverted parabola if X = 10 * [slider value]

For arbitrary values I'd propose some sort of spline interpolation. Convert your set of values to a set of points, where the second coordinate is in the "slider scale":

    (100, 0.0), (200, 0.25), (300, 0.5), (500, 0.75), (1000, 1.0)

Now just use spline interpolation of your choice to create a smooth curve, and once you have the curve you can get values on your 100-1000 scale.

If you don't want to implement any complicated spline interpolation, you could just take a linear one, meaning that for any point of your slider between 0.0 and 0.25 you linearly interpolate between 100 and 200, between 0.25 and 0.5 interpolate between 200 and 300 and so on.

(I don't know what the etiquette is for asking the opposite to the original question in a comment, but I'll add it as an additional answer to fit the code in.)

Continuing on from my previous answer, with all the variables declared as before:

document.write('The other way round:<br />');

function findIntervalStart(n) {
    for (var i = 1; i < bigValues.length; i++) if (n < bigValues[i]) return i-1;
}
/* try some test values */
for (var i = 1; i <= 21; i++) {     
    output = i * 50;
    if (output >= bigValues[bigValues.length - 1]) {
        input = 1;
    }
    else if (output <= bigValues[0]) {
        input = 0;
    }
    else {
    idx = findIntervalStart(output);
        frac = (output - bigValues[idx]) / (bigValues[idx + 1] - bigValues[idx]);
        input = (idx + frac) / (bigValues.length - 1);
    };

    document.write(output + ', ' + input + '<br />');
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top