Javascript callback for a change of active tool (e.g. RangeTool) in the plot toolbar

@ori

Another option if you don’t want to get into the lower levels of making a custom tool or modification is to try a periodic callback in Javascript. Something like this as a modification to what was posted earlier in the thread as a starting point.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
"""

import numpy as np

from bokeh.io import show
from bokeh.layouts import column
from bokeh.models import ColumnDataSource, RangeTool
from bokeh.plotting import figure
from bokeh.sampledata.stocks import AAPL

from bokeh.events import MouseMove
from bokeh.models import CustomJS

dates = np.array(AAPL['date'], dtype=np.datetime64)
source = ColumnDataSource(data=dict(date=dates, close=AAPL['adj_close']))

p = figure(plot_height=300, plot_width=800, tools="xpan", toolbar_location=None,
           x_axis_type="datetime", x_axis_location="above",
           background_fill_color="#efefef", x_range=(dates[1500], dates[2500]))

p.line('date', 'close', source=source)
p.yaxis.axis_label = 'Price'

select = figure(title="Drag the middle and edges of the selection box to change the range above",
                plot_height=130, plot_width=800, y_range=p.y_range,
                x_axis_type="datetime", y_axis_type=None,
                tools="", toolbar_location='right', background_fill_color="#efefef")

range_tool = RangeTool(x_range=p.x_range)
range_tool.overlay.fill_color = "navy"
range_tool.overlay.fill_alpha = 0.2

select.line('date', 'close', source=source)
select.ygrid.grid_line_color = None
select.add_tools(range_tool)
select.toolbar.active_multi = range_tool

cb = CustomJS(args=dict(rng=range_tool), code="""
    if (!rng.name) {
        rng.name = 'range_tool';
        setInterval(function(){console.log('RANGE TOOL active state ' + rng.active);}, 1000)
    }
""")

select.js_on_event(MouseMove, cb)

show(column(p, select))