ipywidgets icon indicating copy to clipboard operation
ipywidgets copied to clipboard

range slider which can be moved around?

Open den-run-ai opened this issue 7 years ago • 9 comments
trafficstars

I'm using this example of data range slider:

https://stackoverflow.com/a/50506926/2230844

But I would like to add the scrolling capability for the slider itself, i.e. move the range right/left without changing its window size. Is this possible?

den-run-ai avatar Oct 22 '18 14:10 den-run-ai

This is what I mean:

http://ghusse.github.io/jQRangeSlider/

den-run-ai avatar Oct 22 '18 15:10 den-run-ai

Actually this one looks much closer to ipywidgets:

https://plot.ly/python/range-slider/

den-run-ai avatar Oct 22 '18 15:10 den-run-ai

The slider currently in use is a jQuery slider. I do not think that supports moving the entire range in one operation. For an earlier discussion about replacing the slider, see here: https://github.com/jupyter-widgets/ipywidgets/issues/630

As a tanget, it should be entirely possible to make an external widgets extension that implements an alternative slider UI, but that will not work with the default interact without some monkey patching.

vidartf avatar Oct 23 '18 09:10 vidartf

This is what I mean:

http://ghusse.github.io/jQRangeSlider/

I would find such an addition to ipywidgets really useful!

nvaytet avatar Dec 19 '19 08:12 nvaytet

Apparently, nouislider is now going to be the base for sliders (#2712). Looking at the "drag" example here, does this mean that this functionality would also be available in ipywidgets? I am guessing some additional options need to be added to the range sliders in ipywidgets to enable range slider dragging, as I couldn't find these options in the PR code changes.

nvaytet avatar Oct 16 '20 20:10 nvaytet

I've made some kind of workaround, which is not quite working, but maybe someone can help improving it? The idea is just to use a IntRangeSlider and make it so that when i move the left handle, the entire range moves along, while when i move the right handle, it resizes the selection range.

This would be good enough for my purposes, and here is a code example:

import ipywidgets as ipw
sl = ipw.IntRangeSlider()
setattr(sl, "lock", False)

def update(change):
    if not change["owner"].lock:
        diff = change["new"][0] - change["old"][0]
        if abs(diff) > 0:
            change["owner"].lock = True
            sl1.value = (change["new"][0], change["new"][1] + diff)
            change["owner"].lock = False

sl.observe(update, names="value")
sl

Now the issue I have is that when i move the left handle too fast, the right handle doesn't quite keep up with the pace, and my range either grows or shrinks, whether i'm moving the left handle towards the left or the right, respectively.

I have also tried a slightly different approach by assigning a delta property to the slider and then updating the right bound using the stored delta rather than a on-the-fly delta that may have changed while the left handle was moving before the right handle had time to update, but that seems to suffer from the same problem:

import ipywidgets as ipw
sl = ipw.IntRangeSlider()
setattr(sl, "lock", False)
setattr(sl, "delta", sl.value[1] - sl.value[0])

def update(change):
    if not change["owner"].lock:
        diff = change["new"][1] - change["old"][1]
        if abs(diff) > 0:
            change["owner"].delta = change["new"][1] - change["old"][0]
        else:
            change["owner"].lock = True
            change["owner"].value = (change["new"][0], change["new"][0] + change["owner"].delta)
            change["owner"].lock = False

sl.observe(update, names="value")
sl

Maybe it's the way i'm using the lock to try and prevent too many updates? Many thanks for any help/advice

nvaytet avatar Oct 17 '20 19:10 nvaytet

I was also trying to find a way to do this by linking on the client side with jslink (to possibly get rid of the lag between the two bounds), maybe by linking to a second slider which would then be hidden, but I can't seem to find a way to jslink to another widget with an offset to the value.

I also cannot find a way to jslink only one of the two numbers in the value of a RangeSlider. Maybe this is possible by creating a new widget class, inheriting from the RangeSlider, and adding a custom new traitlet that holds only the lower or upper range value and then jslink to that?

nvaytet avatar Oct 17 '20 20:10 nvaytet

This is what I mean:

http://ghusse.github.io/jQRangeSlider/

Here is another example of a range slider that can be dragged: http://docs.bokeh.org/en/latest/docs/user_guide/interaction/widgets.html#rangeslider

nvaytet avatar Apr 29 '21 09:04 nvaytet

Hasn't this been fixed in #2712 ? The range slider in ipywidgets>=8 can now be dragged.

nvaytet avatar Sep 19 '22 08:09 nvaytet