How can I make the tooltip that appears when hovering over a data point stay fixed when the data point is clicked?


I am using Bokeh 3.4.1 to create a graph. I would like to fix the tooltip that shows the data value when I hover over the data on the graph, so that it remains on the graph when I click on it.

I tried using CustomJS with document.getElementById("tooltip"); but it returns null. I’ve tried various approaches, but all have failed.

I would appreciate your help.

Thank you.

@djlee One approach is to not let the HoverTool itself display the tooltip information but use a Label instead and attach a CustomJS callback to the HoverTool. You can then also attach a CustomJS to a TapTool which controls whether the TapTool has been activated. Use that information so that the hover info stays even if the cursor is moved; the tags argument of the TapTool is used in the code below.

For example (pseudo code):

hover_info_label = Label(
    // use text properties to align label with hover x, y coordinate
    text_base_line = 'top' // maybe, you need to test
    name = 'hover_info_label'

hover_cb = CustomJS(
    code = """
    const hover_info ='hover_info_label')[0];
    const tap ='tap')[0];
    const idx = cb_data.index.indices; // I assume point data

    if (idx.length === 0) {
      // if taptool has activated hover_info
      if (tap.tags === [1]) {
      } else {
        hover_info.visible = false;
    // hover in data units
    const hover_x = cb_data.geometry.x; 
    const hover_y = cb_data.geometry.y;

    hover_info.text = 'Hello';
    hover_info.x = hover_x;
    hover_info.y = hover_y;
    hover_info.visible = true;
hover = HoverTool(
    tooltips = None,
    callback = hover_cb

tap_cb = CustomJS(
    args = {
        'source': source
    code ="""
    var tap_activated = [0];
    const idx = source.inspected.indices;
    if (idx.length > 0) {
      // tap event activated on a source data point
      tap_activated = [1];
    cb_obj.tags = tap_activated;
p.js_on_event('tap', tap_cb)

tap = TapTool(name = 'tap')

p.add_tools(hover, tap)

Currently traveling so I can’t do more than a link and run but also see: