diff --git a/holoviews/plotting/bokeh/callbacks.py b/holoviews/plotting/bokeh/callbacks.py index 8b6d5938ed..a7274f1b35 100644 --- a/holoviews/plotting/bokeh/callbacks.py +++ b/holoviews/plotting/bokeh/callbacks.py @@ -272,7 +272,7 @@ def set_customjs_callback(self, js_callback, handle): if self.on_events: for event in self.on_events: handle.js_on_event(event, js_callback) - elif self.on_changes: + if self.on_changes: for change in self.on_changes: handle.js_on_change(change, js_callback) elif hasattr(handle, 'callback'): @@ -389,8 +389,11 @@ def set_server_callback(self, handle): if self.on_events: for event in self.on_events: handle.on_event(event, self.on_event) - elif self.on_changes: + if self.on_changes: for change in self.on_changes: + if change in ['patching', 'streaming']: + # Patch and stream events do not need handling on server + continue handle.on_change(change, self.on_change) @@ -912,7 +915,7 @@ class CDSCallback(Callback): attributes = {'data': 'source.data'} models = ['source'] - on_changes = ['data'] + on_changes = ['data', 'patching'] def initialize(self, plot_id=None): super(CDSCallback, self).initialize(plot_id) diff --git a/holoviews/tests/plotting/bokeh/testcallbacks.py b/holoviews/tests/plotting/bokeh/testcallbacks.py index 9a0a834900..f9cee7b2cc 100644 --- a/holoviews/tests/plotting/bokeh/testcallbacks.py +++ b/holoviews/tests/plotting/bokeh/testcallbacks.py @@ -180,8 +180,9 @@ def test_point_draw_callback_initialized_js(self): points = Points([(0, 1)]) PointDraw(source=points) plot = bokeh_renderer.get_plot(points) + cb = plot.callbacks[0].callbacks[0] self.assertEqual(plot.handles['source'].js_property_callbacks, - {'change:data': [plot.callbacks[0].callbacks[0]]}) + {'change:data': [cb], 'patching': [cb]}) def test_point_draw_callback_with_vdims_initialization(self): points = Points([(0, 1, 'A')], vdims=['A']) @@ -221,8 +222,9 @@ def test_poly_draw_callback_initialized_js(self): polys = Polygons([[(0, 0), (2, 2), (4, 0)]]) PolyDraw(source=polys) plot = bokeh_renderer.get_plot(polys) + cb = plot.callbacks[0].callbacks[0] self.assertEqual(plot.handles['source'].js_property_callbacks, - {'change:data': [plot.callbacks[0].callbacks[0]]}) + {'change:data': [cb], 'patching': [cb]}) def test_poly_draw_callback_with_vdims(self): polys = Polygons([{'x': [0, 2, 4], 'y': [0, 2, 0], 'A': 1}], vdims=['A']) @@ -272,8 +274,9 @@ def test_box_edit_callback_initialized_js(self): boxes = Polygons([Box(0, 0, 1)]) BoxEdit(source=boxes) plot = bokeh_renderer.get_plot(boxes) + cb = plot.callbacks[0].callbacks[0] self.assertEqual(plot.handles['rect_source'].js_property_callbacks, - {'change:data': [plot.callbacks[0].callbacks[0]]}) + {'change:data': [cb], 'patching': [cb]}) def test_poly_edit_callback(self): polys = Polygons([[(0, 0), (2, 2), (4, 0)]]) @@ -297,8 +300,9 @@ def test_poly_edit_callback_initialized_js(self): polys = Polygons([[(0, 0), (2, 2), (4, 0)]]) PolyEdit(source=polys) plot = bokeh_renderer.get_plot(polys) + cb = plot.callbacks[0].callbacks[0] self.assertEqual(plot.handles['source'].js_property_callbacks, - {'change:data': [plot.callbacks[0].callbacks[0]]}) + {'change:data': [cb], 'patching': [cb]}) def test_poly_edit_shared_callback(self): polys = Polygons([[(0, 0), (2, 2), (4, 0)]])