js_on_event (original) (raw)
Demonstration of how to register event callbacks using an adaptation of the color_scatter example from the bokeh gallery
from future import annotations
import numpy as np
from bokeh import events from bokeh.io import curdoc, show from bokeh.layouts import column, row from bokeh.models import Button, CustomJS, Div, TextInput from bokeh.plotting import figure
def display_event(div: Div, attributes: list[str] = []) -> CustomJS: """ Function to build a suitable CustomJS to display the current event in the div model. """ style = 'float: left; clear: left; font-size: 13px' return CustomJS(args=dict(div=div), code=f""" const attrs = {attributes}; const args = []; for (let i = 0; i < attrs.length; i++) {{ const val = JSON.stringify(cb_obj[attrs[i]], function(key, val) {{ return val.toFixed ? Number(val.toFixed(2)) : val; }}) args.push(attrs[i] + '=' + val) }} const line = "" + cb_obj.event_name + "(" + args.join(", ") + ")\n"; const text = div.text.concat(line); const lines = text.split("\n") if (lines.length > 35) lines.shift(); div.text = lines.join("\n"); """)
N = 4000 x = np.random.random(size=N) * 100 y = np.random.random(size=N) * 100 radii = np.random.random(size=N) * 1.5 colors = np.array([(r, g, 150) for r, g in zip(50+2x, 30+2y)], dtype="uint8")
p = figure(tools="pan,wheel_zoom,zoom_in,zoom_out,reset,tap,lasso_select,box_select,box_zoom,undo,redo")
p.circle(x, y, radius=radii, fill_color=colors, fill_alpha=0.6, line_color=None)
Add a div to display events and a button to trigger button click events
div = Div(width=1000) button = Button(label="Button", button_type="success", width=300) text_input = TextInput(placeholder="Input a value and press Enter ...", width=300) layout = column(button, text_input, row(p, div))
Register event callbacks
Button events
button.js_on_event(events.ButtonClick, display_event(div))
TextInput events
text_input.js_on_event(events.ValueSubmit, display_event(div, ["value"]))
AxisClick events
p.xaxis[0].js_on_event(events.AxisClick, display_event(div, ["value"])) p.yaxis[0].js_on_event(events.AxisClick, display_event(div, ["value"]))
LOD events
p.js_on_event(events.LODStart, display_event(div)) p.js_on_event(events.LODEnd, display_event(div))
Point events
point_attributes = ['x','y','sx','sy'] p.js_on_event(events.Tap, display_event(div, attributes=point_attributes)) p.js_on_event(events.DoubleTap, display_event(div, attributes=point_attributes)) p.js_on_event(events.Press, display_event(div, attributes=point_attributes)) p.js_on_event(events.PressUp, display_event(div, attributes=point_attributes))
Mouse wheel event
p.js_on_event(events.MouseWheel, display_event(div,attributes=[*point_attributes, 'delta']))
Mouse move, enter and leave
p.js_on_event(events.MouseMove, display_event(div, attributes=point_attributes))
p.js_on_event(events.MouseEnter, display_event(div, attributes=point_attributes)) p.js_on_event(events.MouseLeave, display_event(div, attributes=point_attributes))
Pan events
pan_attributes = [*point_attributes, 'delta_x', 'delta_y'] p.js_on_event(events.Pan, display_event(div, attributes=pan_attributes)) p.js_on_event(events.PanStart, display_event(div, attributes=point_attributes)) p.js_on_event(events.PanEnd, display_event(div, attributes=point_attributes))
Pinch events
pinch_attributes = [*point_attributes, 'scale'] p.js_on_event(events.Pinch, display_event(div, attributes=pinch_attributes)) p.js_on_event(events.PinchStart, display_event(div, attributes=point_attributes)) p.js_on_event(events.PinchEnd, display_event(div, attributes=point_attributes))
Ranges Update events
p.js_on_event(events.RangesUpdate, display_event(div, attributes=['x0','x1','y0','y1']))
Selection events
p.js_on_event(events.SelectionGeometry, display_event(div, attributes=['geometry', 'final']))
curdoc().on_event(events.DocumentReady, display_event(div))
show(layout)