bokeh: custom callback for hovertool for figure.line

207 Views Asked by At

I'm trying to write a code which adds hovertool performing customer js-code over figure.line object. In order to do it I used userguide code as example (https://docs.bokeh.org/en/latest/docs/user_guide/interaction/callbacks.html#customjs-for-hover) but simplified and modified (see below). I've found that it works over figure.segment however doesn't work over figure.line.

Here is complete example:

from bokeh.models import CustomJS, HoverTool
from bokeh.plotting import figure, output_file, show

output_file("hover_callback.html")

# define some points and a little graph between them
x = [2, 3, 5, 6, 8, 7]
y = [6, 4, 3, 8, 7, 5]

p = figure(plot_width=400, plot_height=400, tools="", toolbar_location=None)

lines = p.line(x, y, line_color='blue', line_width=5)
seg = p.segment(x[0:3], y[0:3], x1=x[3:], y1=y[3:], color='olive', alpha=0.6, line_width=3)

code = """
const indices = cb_data.index.indices
if (indices.length > 0) {
    console.log('Hello!')
}
"""

callback = CustomJS(code=code)
p.add_tools(HoverTool(tooltips=None, callback=callback, renderers=[lines, seg]))

show(p)

cb_data.index.indices is not empty when I put pointer over segment (olive-color) but not over line (blue). enter image description here

Is it sort of expected behaviour? If so I would appreciate reference to some doc where it's explained. THanks!

1

There are 1 best solutions below

2
On BEST ANSWER

You can activate the HoverTool for lines, too. But you have to adapt your JavaScript quite a bit. Lines return the information of the index a bit different, you have to ask for const line_indices = cb_data.index.line_indices.

Here is your complete example:

from bokeh.models import CustomJS, HoverTool
from bokeh.plotting import figure, output_file, show

output_file("hover_callback.html")

# define some points and a little graph between them
x = [2, 3, 5, 6, 8, 7]
y = [6, 4, 3, 8, 7, 5]

p = figure(plot_width=400, plot_height=400, tools="", toolbar_location=None)

lines = p.line(x, y, line_color='blue', line_width=5)
seg = p.segment(x[0:3], y[0:3], x1=x[3:], y1=y[3:], color='olive', alpha=0.6, line_width=3)

code = """
const indices = cb_data.index.indices
const line_indices = cb_data.index.line_indices
if (indices.length +  line_indices.length > 0) {
    console.log('Hello!')
}
"""

callback = CustomJS(code=code)
p.add_tools(HoverTool(tooltips=None, callback=callback, renderers=[lines, seg]))

show(p)