Hello bokeh Comunity,
This is my first post, I’m very new to Python and Bokeh. This is an amazing tools for making an interactive dashboard using python. However I need a very specific tools for interaction that I can’t find anywhere in internet.
I need to have a callback action that occur at the end PointDrawTools.
I made script that execute callback using PointDrawTool using two methods that resulting similar result, but not that I want:
-
Callback using
on_change('indices', callback)
This method allow me to callback on the beginning data source change. In relation with Point Drag, it occur on start of Point Drag. -
Callback using
on_event(Pan, callback)
This method allow me to callback upon Pan on figure and at the end Point Drag. But i need the callback executed at the end of Point Drag only, not during Panning of Figure.
1st method have a little bit of problem, I need to data synchronization at the end of Point Drag.
2nd methods work just fine, it callbacks at the end Point Drag and figure panning. I need to have data synchronize only at the end Point Drag only (or during Point Drag only), not during Panning on figure.
Is there any way for me to have Callback at the end of Point Drag?
here is the minimal code that I write:
from bokeh.models import ColumnDataSource, Column, Row, PointDrawTool, Div, CustomJS
from bokeh.models.widgets import DataTable, TableColumn
from bokeh.io import curdoc
from bokeh.plotting import figure
from bokeh.events import PanEnd
def callback_source_change(attr, old, new):
data3.data = data12.data
def callback_pan():
data3.data = data12.data
xa = [1, 3, 3, 4, 5, 1]
ya = [2, 6, 4, 5, 8, 4]
ca = ['red'] * 3 + ['green'] * 3
data12 = ColumnDataSource({'xa': xa, 'ya': ya, 'ca': ca})
data3 = ColumnDataSource({'xa': xa, 'ya': ya, 'ca': ca})
p1 = figure(title="Callback using source.selected.on_change('indices', callback)")
r1 = p1.circle(x='xa', y='ya', color='ca', size=10, source=data12)
# 1 st method
p1.add_tools(PointDrawTool(renderers=[r1], add=False))
data12.selected.on_change('indices', callback_source_change)
# 2 st method
p2 = figure(title="Callback using figure.on_event(Pan, callback)")
r2 = p2.circle(x='xa', y='ya', color='ca', size=10, source=data12)
p2.add_tools(PointDrawTool(renderers=[r2], add=False))
p2.on_event(PanEnd, callback_pan)
# Target Result
p3 = figure(title="Callback Result")
p3.circle(x='xa', y='ya', color='ca', source=data3)
p1.x_range = p2.x_range = p3.x_range
p1.y_range = p2.y_range = p3.y_range
columns = [TableColumn(field="xa", title="xa"),
TableColumn(field="ya", title="ya"),
TableColumn(field="ca", title="ca")]
data_table12 = DataTable(source=data12, columns=columns)
data_table3 = DataTable(source=data3, columns=columns)
p = Row(Column(p1, data_table12),
Column(p2, data_table12),
Column(p3, data_table3))
curdoc().add_root(p)
Note:
on 1st method, the target data source not immediately updated. It updated on on second trial on start of dragging.
on 2 method, call back also occur during figure Panning (see terminal output)
Best regards,