New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Exponentially increase range #140
Comments
I'm willing to put some time into this, as it has been requested before. Could you put some thought into the API design for this? How would you define where the jump are? Are they variable? Would you provide a logarithmic formula? It would be -very- helpful if you (or anyone else interested) could provide code-samples of how you'd expect to initialize noUiSlider with these options. Thanks! |
Hello again! Thanks for your interest. Although I am not a math expert, I think an easy way to do it would be the one I just explained. You submit pairs of values: First is a percentage and sexond is the range value. I have created an image as an example: http://i.imgur.com/cygTRW9.jpg So, in the above case if you have a range from 0-200.000 and you input the 4 sets of values, the following happens: The range from 0-20% is divided in steps so that the slider changes range values from 0-10. It could also be possible to add a third value so that you define the position of these values on the actual slider. Which means for example that there could be: val1: 20, 10, 50 Thios would mean that the 20% could be in the 50% of the slider rather than the actual 20%. I hope I get the message across. What do you think? |
Ok, but would the movement still be linear? How about something like this: // API proposal
slider.noUiSlider({
range: [0, 200000]
,stops: {
// Stepping from 0% to 20% is implied...
'20%': 10
'75%': 10000
// ... as is stepping from 75% to 100%
}
}); |
Now, in all fairness, this doesn't really answer your question, and it isn't very useful for any practical implementation, but I've set up a small example of using Lagrange polynomial interpolation with noUiSlider. Stops aren't in the works yet, this is just something fun to share :) |
cool! :) Well done! Seems like in the middle of the bar it's 1/4th of the range. I am certain you can do better than this, I hope you find some time to do so :) +1 |
Would love to see this feature appear in an official release! |
To anyone interested in this: I'm looking for feedback as to how the |
A little feedback to help you decide maybe: What if you could just add values that would automatically decide the number of stops and what value each stop should be assigned to. Like this: range: [0, 100000] This would automatically create 8 steps inside the total range, dividing the whole range into 9 "pieces". Each piece would be 1/9 of the slider. Linear movement between the stops, based on the stops' individual values. I used version 3 of your slider, and there was something like that in that one. Interpolating polynomial would also be cool of course. The ultimate would be a setting to decide between these two alternatives but I might be asking too much. :) Edit: range: [0, 200000] Linear movement between stops. |
Great discussion so far. Regarding percentages, we're talking about the slider width, correct?
If the slider is 200px wide, then the value will be "10" at 40px (and "10000" at 150px). |
Yes I think percentage would be best. In my opinion that is more important, |
Yes, the percentages refer to the slide width/height. How would you expect the current |
That's a tricky one. :) Using the current step option like it works today would not be suitable if you use the stops(stepping) option to create a simulated interpolating polynomia. The steps would be too big in the beginning of the slider and too small at the end. My first thought was that the step option then specifies the percentage for each stop within the stop itself. A little hard to explain... If you have 0 as start and 100 as first stop and 10 as step, each step in that section would be 10 (units). The second part of the slider might have the values between 100 and 500, making each step 40. Another option would be to let step be 1 if you use stops(stepping), ie ignore what step is. Hard to say which would be/work the best. It probably depends on the implemantation and your personal liking I guess. |
My vote is to stick with linear movements (but make step: 1,
steps: {
'25%': {
value: 10,
step: 5
},
'50%': {
value: 1000,
step: 1
},
'75%': {
value: 10000,
step: 500
}
} Each step could be either a scalar value (e.g. Also, since |
I suggest that step can receive a function in the context of the slider. With it, the application can decide which to do, even when the value of step is fully dynamic and irregular. That's my suggestion, and it's much more simpler. =) |
@fjorgemota that sounds interesting. Could you put together a code example? I'm curious on how were you thinking of getting access to the properties (value, active handle, % dragged, etc) -- whether via |
@mgibbs189 I think that is possible to In the case that originated this issue, some thing like: $("#price").noUiSlider({
"range": [0, 2000000],
// Other options..
"step": function(){
// This function does not receive any arguments. All the data can be acessed using `this`
var max_value = this.range[1]; // We can get passed options too (this variable will not be used, its here only to demonstrate)
var values = this.val();
var handle_value = values[this.active_handle_index];
if(handle_value < 1000){
return 1;
}
else if(handle_value <10000){
return 10;
}
else if(handle_value < 100000){
return 100;
}
else if(handle_value < 1000000){
return 1000;
}
else{
return 10000;
}
}
}); Okay, maybe thats not very beautiful, but it shows the idea. This way, things like formulas can be implemented too, what can be great. =) Thinks like But that is only a suggestion. (and can be not very good) |
@fjorgemota This looks great. this.val // ['123'] or ['123', '456']
this.active_handle_index // 0 or 1
this.position // each handle's position from 0-100 ['25.2'] or ['25.2', '76.4']
this.range // same as options
this.start // same as options @leongersen Any thoughts? |
Matt, I really like your suggestion: step: 1, |
Wow, thanks for the input everyone! Implementing |
@leongersen Maybe the function that i suggested can have a context (a simple object that are passed and maintained along function calls). The library select2 uses that to allow the function to know what it doing at the last call. That allow to define correctly the |
@fjorgemota Could you elaborate? I get the idea of passing a function for step, and I like it, but I'm not sure what you mean in your last comment. |
@leongersen I think that what you say of sub-ranges is something like...in some interval, the step adruptally changes. Can be a mistake of me, anyway, can you please send a example to i elaborate correctly my comment? |
Well: range: [0, 100]
,step: 7
,stepping: {
'20%': 10
'40%': 40
'80%': 90
} If the sub-range from 10 to 40, the steps are 10, 17, 24, 32, 38, ...oops. Where does the slider now step to? With non-linear ranges, I can no longer just convert |
Yes, i get. Because these type of problem - and the exponential number of possibilities (ok, thats just a joke) - i just suggested something like a function to allow the application to decide what the step to do (i dont see these type of problem involving sub-ranges with callback functions, or these problems exists in your opinion?) Thanks for the explication 👍 |
@leongersen @fjorgemota I think the function approach would require a lookahead. E.g. for every slider movement, the function would need to run twice. Once for the current movement, and one for the next (or previous if sliding left). Assume the following:
It's similar when sliding left (see
|
And that is assuming the function returns the same value every time. |
The example above accounts for varying return values (see lines 3-4 of the first example). |
I wasn't clear enough: the same value for the same input. For fun: |
@leongersen Can we assume that |
|
I've settled on an API. Feedback welcome (I'd even say required. I want to get this right!). // When 'spread' is set, the 'step' value can only be 'true'.
// If set, the slider will step between the VALUES
// provided in spread.
step: true
// I'm looking for a better name for this setting
,spread: {
// Set a value and a 'step' for the
// sub-range that STARTS here ( so from 10% => 40% )
'10%': [ 500, 100 ]
// Omit 'step' for unstepped behaviour
// from here to the next step. ( from 50% to 100% );
,'50%': [ 4000 ]
} Additionally: spread: {
// The 'step' can be set for sub-range 0% => 10%.
// 'value' for 0% will be ignored.
'0%': [ 0, 30 ]
'10%': [ 500, 100 ]
,'50%': [ 4000 ]
// Any 'value' or 'step' for 100% will be ignored.
,'100%': [ 3, 3 ]
} |
Curious:
Thanks a lot for the work on this code. I'm looking forward to both the serialization + variable step features too (in fact, already using the github version right now in my project). |
The values allow for setting 'subranges', and custom I'll explain by example: If you want to have a 'subrange' of Be careful using the work-in-progress code in live projects. It isn't stable yet. That said: any feedback? |
To everyone: please have a look at http://refreshless.com/feedback/, and let me know your thoughts and ideas. Thanks! |
@leongersen If it helps, something like UserVoice - even to allow best suggestions - will be in someway best for the users of the library. :p GitLab is an example of project that uses it for suggestions, and it is great =) - See: http://feedback.gitlab.com/forums/176466-general By the way, i send my opinion soon. Thanks. |
@leongersen it still needs work. I agree with @vdboor - the numbers are confusing and it's clunky to require a separate variable. // Single step value
spread: 5 // multiple step values
spread: {
'0%': { step: 5 },
'20%': { step: 20, maxValue: 500 },
'60%': { step: 60, maxValue: 2500 },
'80%': { step: 200 }
} |
@mgibbs189, fair enough. The problem here is that Merging this option would overcomplicate |
@fjorgemota Uservoice seems like a good fit. I'll consider adding such a feedback option to the documentation. Thanks! |
I've taken your comments into account; here's an idea: // Range changes a ton! It now takes a
// 'min' and 'max' property, instead of an array.
// You can set subranges, but these are not required.
range: {
'min': {
value: 2000
step: 500
}
/* <Optional> */
'10%': {
value: 3000,
step: 100
},
'40%': {
value: 6000,
step: 400
},
'80%': {
value: 8000,
step: 800
},
/* </Optional> */
'max': {
value: 10000
}
}
// Enforce snapping between range values. Defaults to false.
snap: true, The minimal setup is then pretty, and it can easily be extended without introducing new options. range: {
'min': {
value: 2000
}
'max': {
value: 10000
}
} |
@leongersen I like that a lot. Given a range of // Example 1 (backwards compatibility)
$('.test').noUiSlider({
range: [1, 100],
step: 5
}); // Example 2 (accept an object OR value)
$('.test').noUiSlider({
range: {
'min': { value: 1, step: 5 },
'max': 100
}
}); |
I'm not sure about backwards compatibility. I'm replacing the entire Serialization API anyway, so adding backwards features here would risk bloating the option validation code. Example 2 makes more sense, as it writes up a lot easier. There is also still the option to replace the option/step object with an array. |
@leongersen Sounds good. |
While writing documentation, the syntax felt overly verbose, so I changed it again: Minimal setup: range: { // Value
'min': [ 2000 ]
,'max': [ 10000 ]
} Minimal setup with step. An alternative (not in range) syntax for step is available for simplicity. It is overwritten when specified within 'range'. step: 1000
,range: { // Value
'min': [ 2000 ]
,'max': [ 10000 ]
} Additional subranges can be added in between: range: { // Value
'min': [ 2000 ]
,'10%': [ 6000 ]
,'max': [ 10000 ]
} Adding stepping on subranges: range: { // Value Step
'min': [ 2000, 500 ]
,'10%': [ 6000, 1000 ]
,'max': [ 10000 ]
} I'm more happy with this, as it requires far less keywords. |
Just checking in - how's this coming along? |
Fair enough. I haven't had an time to properly finish this and other features (documentation, testing, etc.). I'm currently insanely busy (pfff). I hope to get everything up somewhere in February, when things settle down. Sorry for the delay. |
No rush - thanks for all your hard work thus far. noUiSlider is wonderful! |
Hello, I'm totally in love with your plugin but I was wondering if I can actually "hack it" for such behavior using the slide function? Maybe at least till you're done with this |
I know it took forever, but this option is new in noUiSlider 6. See the documentation on slider values for implementation details. |
Awesome ⛵ noUiSlider is great! |
Fantastic! I have been looking for a range slider with good mobile support. A non-linear slider with pips was more than I even hoped to find! |
I developed my own dynamic idea that you may find useful. Here const digits = max.toString().split(``).length;
const range = {
"min": 0,
"max": max
};
let percentage = 0;
for (let i = 1; i <= digits - 1; i++) {
percentage += 100 / (digits - 1);
range[`${percentage}%`] = Math.pow(10, i);
}
noUiSlider.create(slider, {
"start": [0, max],
"connect": true,
"step": 1,
"range": range
}); |
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
Hello and well done on your excellent work on this plugin!
It would be real nice if we could have exponential increase of the range values, meaning, if there's a huge price range for example 0-2.000.000, the first values would start in steps of 1 and as the range reaches it's end it should be in steps of 10.000.
In other words, variable steps. So, you would define multiple percentage values between which you could set a different step OR define points of range values in percentage width and give the value there.
Much like how ebay price-range works for example!
The text was updated successfully, but these errors were encountered: