2009-05-10 3 views
56

У меня есть слайдер со значениями от 0 до 100.Логарифмический слайдер

Я хочу отобразить их в диапазоне от 100 до 10 000 000.

Я видел некоторые функции, разбросанные по сети, но все они на C++. Мне это нужно в Javascript.

Любые идеи?

ответ

141

Вы можете использовать функцию следующим образом:

function logslider(position) { 
    // position will be between 0 and 100 
    var minp = 0; 
    var maxp = 100; 

    // The result should be between 100 an 10000000 
    var minv = Math.log(100); 
    var maxv = Math.log(10000000); 

    // calculate adjustment factor 
    var scale = (maxv-minv)/(maxp-minp); 

    return Math.exp(minv + scale*(position-minp)); 
} 

Полученные значения соответствовать логарифмической шкале:

js> logslider(0); 
100.00000000000004 
js> logslider(10); 
316.22776601683825 
js> logslider(20); 
1000.0000000000007 
js> logslider(40); 
10000.00000000001 
js> logslider(60); 
100000.0000000002 
js> logslider(100); 
10000000.000000006 

обратная функция будет, с теми же определениями minp, maxp , minv, maxv и scale, вычислить положение ползунка от значения, подобного этому:

function logposition(value) { 
    // set minv, ... like above 
    // ... 
    return (Math.log(value)-minv)/scale + minp; 
} 


Все вместе, завернутый в классе и в качестве функционального фрагмента кода, это будет выглядеть следующим образом:

// Generic class: 
 

 
function LogSlider(options) { 
 
    options = options || {}; 
 
    this.minpos = options.minpos || 0; 
 
    this.maxpos = options.maxpos || 100; 
 
    this.minlval = Math.log(options.minval || 1); 
 
    this.maxlval = Math.log(options.maxval || 100000); 
 

 
    this.scale = (this.maxlval - this.minlval)/(this.maxpos - this.minpos); 
 
} 
 

 
LogSlider.prototype = { 
 
    // Calculate value from a slider position 
 
    value: function(position) { 
 
     return Math.exp((position - this.minpos) * this.scale + this.minlval); 
 
    }, 
 
    // Calculate slider position from a value 
 
    position: function(value) { 
 
     return this.minpos + (Math.log(value) - this.minlval)/this.scale; 
 
    } 
 
}; 
 

 

 
// Usage: 
 

 
var logsl = new LogSlider({maxpos: 20, minval: 100, maxval: 10000000}); 
 

 
$('#slider').on('change', function() { 
 
    var val = logsl.value(+$(this).val()); 
 
    $('#value').val(val.toFixed(0)); 
 
}); 
 

 
$('#value').on('keyup', function() { 
 
    var pos = logsl.position(+$(this).val()); 
 
    $('#slider').val(pos); 
 
}); 
 

 
$('#value').val("1000").trigger("keyup");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 

 
Input value or use slider: 
 
<input id="value" /> 
 
<input id="slider" type="range" min="0" max="20" />

+4

+1: Настолько лучше, чем мой ответ. 8-) – RichieHindle

+4

Если у вас была бы противоположная функция? Учитывая значение журнала, выведите положение, в котором находится ползунок. – GeekyMonkey

+0

Блестящий не может сказать спасибо! У меня степень математики, но так давно я понял, что что-то подобное приводит к разочарованию. Благодаря SO (и вам), которые можно обойти! – Gaz

9

Чтобы получить распределение вы хотите, я думаю, вы можете использовать эту формулу:

var value = Math.floor(-900 + 1000*Math.exp(i/10.857255959)); 

Вот самодостаточная страница, которая будет печатать значения, которые вы получите за 0-100 слайдер, пропустив их через эту формулу:

<html><body><script> 
for (var i = 0; i <= 100; i++) { 
    var value = Math.floor(-900 + 1000*Math.exp(i/10.857255959)); 
    document.write(value + "<br>"); 
} 
</script></body></html> 

числа идут от 100 до 10000000 в том, что выглядит мой математически ржавый глаз, чтобы быть распределением вы хотите. 8-)

+1

Это сработало ... как вы его получили? – user103773

+2

Начинается с Math.exp (i) и настраивается вручную, пока номера не будут соответствовать. Моя математика-фу слаба, но я могу бинарную рубку для Англии. 8-) – RichieHindle

+0

Эти два ответа представляют собой способность знания в математике. Это должно выразить любому программисту о требовании обучения математике. – asyncwait

8

Не совсем ответ на вопрос, но и для тех, кто интересуется, то обратное отображение последней строки -

return (Math.log(value)-minv)/scale + min; 

только для документирования.

ПРИМЕЧАНИЕ. Значение должно быть> 0.

Смежные вопросы