gvij
gvij

Reputation: 447

Python Bokeh: Timeout for callbacks in case of sliders with range

Currently, I have a DateRangeSlider. I want to record changes of both the lower range and the upper range of the slider. I came across an answer which explained about the 'mouseup' callback_policy. But, this restricts the change to just one of the sliders at once. So, I want to wait a certain amount of time before reading the changed values so that I can record the new lower range and upper range. How can this be achieved?

Following code changes either the lower range or the upper range at a time.

from datetime import date

from bokeh.models.widgets import DateRangeSlider
from bokeh.layouts import layout
from bokeh.models import CustomJS
from bokeh.models.sources import ColumnDataSource

from bokeh.io import curdoc

date_range_slider = DateRangeSlider(title="Date Range: ", start=date(2017, 1, 1), end=date.today(), value=(date(2017, 9, 7), date(2017, 10, 15)), step=1, callback_policy='mouseup')


def cb(attr, old, new):
    print "Callback"
    print date_range_slider.value_as_datetime[0].strftime("%Y-%m-%d"), date_range_slider.value_as_datetime[1].strftime("%Y-%m-%d")


source = ColumnDataSource(data=dict(value=[]))
source.on_change('data', cb)

date_range_slider.callback = CustomJS(args=dict(source=source), code="""
    source.data = { value: [cb_obj.value] } """)

sizing_mode = 'fixed'
l = layout(children=[[date_range_slider]],sizing_mode='fixed')
curdoc().add_root(l)
curdoc().title = "DateRangeSlider"
curdoc().add_root(source)

Upon changing the slider values on the server, I get the following output:

Callback

2017-05-05 2017-07-22

Callback

2017-05-26 2017-07-22

And, this is what I want to achieve:

Callback

2017-05-05 2017-07-22

Upvotes: 0

Views: 965

Answers (3)

CodePrinz
CodePrinz

Reputation: 497

I created a delay function to not immediately apply slider changes.

It waits a specific time, till it executes the first call. The counter will reset with every new call.

Maybe this could help you (or someone with a similar problem), too.

Upvotes: 0

Seb
Seb

Reputation: 1775

You can store the values of your range slider, and have the callback do stuff only if both values are different from the stored values, then update the stored values with the new values.

The downside of doing this compared to bigreddot suggested button is that you will NEED to change both values each time you want to select a new range. The upside is that you don't need a button.

Upvotes: 0

bigreddot
bigreddot

Reputation: 34568

Bokeh callbacks are executed immediately as a change happens, so there's not really any good way to accomplish what you want with callbacks on the range itself (they will always fire independently for the changed to the different slider handles). The best thing I can suggest offhand, is to to have callbacks on the slider at all, but instead have an "update" button that has a callback that uses the slider values, that uses can press when they are ready to apply the changes.

Upvotes: 1

Related Questions