@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)