Not possible to add CustomJS callbacks to annotations?

I can’t seem to attach a custom js_on_event callback to a BoxAnnotation model. Is that not possible in principle? The docs describe it as if callbacks can be attached to any model and js_event_callbacks is listed among BoxAnnotation class properties.

A minimal example would be something like:

from bokeh.io import show
from bokeh.models import CustomJS, BoxAnnotation
from bokeh.plotting import figure

p = figure(plot_width=400, plot_height=250)

callback = CustomJS(code="""
console.log(cb_obj);
""")

box = BoxAnnotation(top_units="screen", bottom_units="screen", left_units="screen", right_units="screen",
    top=80, bottom=100, left=10, right=30, fill_alpha=1, fill_color='red')

box.js_on_event("tap", callback)

p.add_layout(box)
show(p)

I dug into the code a bit and it seems like annotations just don’t support BokehJS events. I’ve created https://github.com/bokeh/bokeh/issues/10490

1 Like

@gherka At the risk of being pedantic, I just want to clarify the situation fully

I can’t seem to attach a custom js_on_event callback to a BoxAnnotation model.

It’s not the case that you can’t attach the event handler. You can use js_on_event to attach a handler to any Bokeh model at all, but that’s only ever going to be useful when the model happens to emit the event you specify. That is not the case here. Annotations don’t currently emit a “tap” event (or any events, AFAIK) so in this case the handler will never be invoked.

Thanks, Bryan. The context for this is a SO post asking for a custom legend.

I thought it would be possible to create a bunch of “free floating” rects + text labels in screen coordinates and attach a CustomJS callback on click to toggle visibility. This would avoid having a “ghost” renderer and a custom legend. Although, when I tried a custom legend in this way, the js_on_event also didn’t work. A long time ago (around 0.12.x) you could specify glyphs in screen coordinates, but this was removed (discussion here and here). Are there any other ways using existing functionality to achieve the custom legend along the lines described in the SO question?