Open deisi opened 7 years ago
Great question. The underlying slider (jqueryui slider) doesn't have an option for that, but perhaps you could do it for now by listening to changes on the value, and reset that value to enforce your minimum distance.
from ipywidgets import IntRangeSlider
x = IntRangeSlider()
def enforce_gap(change):
gap = 10
min, max = change.new
oldmin, oldmax = change.old
if (max-min) < gap:
if oldmin == min:
# max changed
max = min + gap
else:
min = max - gap
x.value = (min, max)
x.observe(enforce_gap, 'value')
x
Another way is making a new class with a validator:
from traitlets import validate
class IntRangeSliderGap(IntRangeSlider):
@validate('value')
def enforce_gap(self, proposal):
gap=10
min, max = proposal.value
oldmin, oldmax = self.value
if (max-min) < gap:
if oldmin == min:
# max changed
max = min + gap
else:
min = max - gap
return (min, max)
Does that help?
I will try, but looks promising. Thx
Am 26.04.2017 15:30 schrieb "Jason Grout" notifications@github.com:
Does that help?
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/jupyter-widgets/ipywidgets/issues/1312#issuecomment-297408437, or mute the thread https://github.com/notifications/unsubscribe-auth/AFL2NNx8cwnNrcltLoIlwkEEti8GQgsiks5rz0bfgaJpZM4NInrA .
We are almost there. The only problem with the validated class is, that it can get out of bounds, when you move the lower slider up until its end. It will then push the upper one out of the max value. I tried fixing it like this:
from traitlets import validate
class IntRangeSliderGap(widgets.IntRangeSlider):
@validate('value')
def enforce_gap(self, proposal):
gap=1
min, max = proposal.value
oldmin, oldmax = self.value
if min == proposal.max:
min -= 1
if (max-min) < gap:
if oldmin == min:
# max changed
max = min + gap
else:
min = max - gap
return (min, max)
but proposal.max
doesn't exist.
Never minde, got it with:
from traitlets import validate
class IntRangeSliderGap(widgets.IntRangeSlider):
@validate('value')
def enforce_gap(self, proposal):
gap=1
min, max = proposal.value
oldmin, oldmax = self.value
if min == self.max:
min -= 1
if (max-min) < gap:
if oldmin == min:
# max changed
max = min + gap
else:
min = max - gap
return (min, max)
Okay, now there is some interference with the continuous_update=False
option. If you set it, the slider gui can get stuck in an overlapping position, while the value of the slider is just fine. To get the slider into that position,you have to move the lower value against the upper. It then gets not pushed up right away.
Any ideas how to circumvent that?
Any ideas how to circumvent that?
That's because the python side doesn't see the slider value change until after you release if continuous_update is false. In order to fix that, we have to do something with the javascript code.
We could support a new attribute, say "min_gap" or something better named, that would propagated over to the javascript, and the javascript could check that value anytime the slider value changed. Would you like to put in a pull request for that? Basically, you'd add one attribute to the slider, copying and modifying one of the other ones (like 'max'). Then you'd probably add validation in both python and javascript. Each side, on the value changing, would make sure the correct gap size existed.
Would you like to put in a pull request for that?
In principle yes, but I cant promise it will happen any soon. My Javascript skills are very basic, but I think I can work my way through. I have to give it a try and we will see if I can transform your suggestion into a pull request.
Awesome!
To help you get started, the code that is triggered when the slider values change is at https://github.com/jupyter-widgets/ipywidgets/blob/c3e7ee6a8d7fee9519c6faeb048628e44dd1389b/jupyter-js-widgets/src/widget_int.ts#L337. We use the jquery ui slider (http://api.jqueryui.com/slider/, https://jqueryui.com/slider/#range).
And feel free to ask questions.
I'll take a look at this one
Hi is this available?
Hey, I have a need for ranged sliders, that can not be overlapped, so that the values are never the same. Can this be achieved somehow?
Cheers