Solution - Drag and Drop for Labels and etc

Publish implementing drag&drop based Pan event for labels and etc, maybe for somebody it will be useful …

import numpy as np
from bokeh.plotting import figure
from bokeh.models import Label,Span, Column
from bokeh.io import curdoc
from bokeh import events

fig_length = 700
x = np.linspace(0, 4*np.pi, 100)
y = np.sin(x)

p = figure(title='Dragging label.', tools="xpan,xwheel_zoom,reset", width=700,height=300, y_axis_location="right")
p.line(x, y, legend_label="sin(x)")

trail_label = Label(x=fig_length-65, y=0, x_units='screen', y_units='data',
    text="drag me", render_mode='css',
    text_font_size='12px', text_color='white', text_alpha=1,
    text_baseline='middle', text_align='left',
    border_line_color='black', border_line_alpha=1.0,
    background_fill_color='red', background_fill_alpha=1)
trail_line = Span(location=0, dimension='width', line_dash='dashed', line_color='gray', line_width=1)
p.add_layout(trail_label)
p.add_layout(trail_line)

def trail_label_drag(attr):
    if attr.sx > fig_length-65 and attr.sx < fig_length+40 and attr.y >  trail_label.y-15 and attr.y <  trail_label.y+15:
        trail_label.y = attr.y
        trail_label.text = str(round(attr.y, 1))
        trail_line.location = attr.y

p.on_event(events.Pan, trail_label_drag)

layout=Column(p)
curdoc().add_root(layout)
2 Likes

This certainly seems like a reasonable way to do things now, thanks for sharing @Andromeda!