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

Hello,

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'
)
p.add_layout(hover_info_label)

hover_cb = CustomJS(
    code = """
    const hover_info = plot.select('hover_info_label')[0];
    const tap = plot.select('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]) {
        return;
      } else {
        hover_info.visible = false;
        return;
      }
    }
    // 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:

Hello,
I think you can implement a solution using CustomJS callbacks. First, define a CustomJS callback function that manages the tooltip’s visibility based on hover events. This function should be set up to update the tooltip display status to remain visible when clicked. Utilize Bokeh’s tools such as HoverTool to customize the tooltip behavior and ensure it remains visible upon interaction. Ensure your Bokeh plot settings and JavaScript callbacks are synchronized to maintain smooth functionality throughout the user experience.