I am trying to filter data using the RangeTool object. My plan is to trigger some custom JS to perform the selection I want when the RangeTool range is changed, however nothing I have tried seems to respond to such changes. Here is a simple example:
# Test customJS on RangeTool range change
import numpy as np
from bokeh.plotting import figure, show
from bokeh.models import RangeTool, Range1d, ColumnDataSource, CustomJS, CustomJSFilter
select = figure(title="Range selection",
height=200, width=1000)
x = np.arange(0, 10, 0.1)
y = x**2
data = ColumnDataSource(data=dict(x=x, y=y))
select.scatter('x', 'y', source=data)
x_range = Range1d(x.min(), x.max())
range_tool = RangeTool(start_gesture="pan", x_range=x_range)
custom_js = CustomJS(code="""
console.log("range changed!");
""")
x_range.js_on_change("start", custom_js)
x_range.js_on_change("end", custom_js)
select.add_tools(range_tool)
show(select)
So here my idea was to look for changes to the underlying Range1d object and trigger on those, but I get zero console messages from the above code. I have also tried e.g. range_tool.js_on_change("x_range", custom_js), and on range_tool.overlay, and various others I have forgotten already. Nothing causes the JS to trigger when changing the range overlay in the plot window.
Am I fundamentally misunderstanding something here? Does js_on_change not work how I am thinking? How can I trigger code to run when I change the RangeTool range?
There is an alternative described here: How do I get a "Range Select Tool"? - #10 by bevoorrading, however it seems parts of the solution have been deprecated in the last two years. The _clone() function in particular seems to be gone.
Well it seems that BoxSelectTool pretty much does what I want already. I just added one to my “minimap” figure with dimensions=‘width’ and it works nicely:
I can then trigger my customJS off the change in the ‘selected’ attribute of the ColumnDataSource underlying the figure, which is probably the best way to do it anyway:
@bjfar IMO your original code should work as you expected, so this seems like it might be a bug with the way the range tool updates its ranges. Notably, setting the exact same callback on select.x_range does trigger the console message.
Can you please file a bug report in a GitHub Issue with these details?