Skip to content

Commit

Permalink
Add support to plotly_deselect event (#1542)
Browse files Browse the repository at this point in the history
* Add trace.on_deselect() method to register callback to be executed on deselection (double click)
  • Loading branch information
denphi authored and jonmmease committed May 3, 2019
1 parent 6ced2d9 commit e426a19
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 0 deletions.
15 changes: 15 additions & 0 deletions js/src/Figure.js
Original file line number Diff line number Diff line change
Expand Up @@ -750,6 +750,10 @@ var FigureView = widgets.DOMWidgetView.extend({
function (update) {
that.handle_plotly_selected(update)
});
that.el.on("plotly_deselect",
function (update) {
that.handle_plotly_deselect(update)
});
that.el.on("plotly_doubleclick",
function (update) {
that.handle_plotly_doubleclick(update)
Expand Down Expand Up @@ -1080,6 +1084,17 @@ var FigureView = widgets.DOMWidgetView.extend({
handle_plotly_selected: function (data) {
this._send_points_callback_message(data, "plotly_selected");
},

/**
* Handle plotly_deselect events emitted by the Plotly.js library
* @param data
*/
handle_plotly_deselect: function (data) {
data = {
points : []
}
this._send_points_callback_message(data, "plotly_deselect");
},

/**
* Build and send a points callback message to the Python side
Expand Down
71 changes: 71 additions & 0 deletions plotly/basedatatypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -4120,6 +4120,9 @@ def __init__(self, plotly_name, **kwargs):
# ### Callbacks to be called on selection ###
self._select_callbacks = []

# ### Callbacks to be called on deselect ###
self._deselect_callbacks = []

# ### Trace index in figure ###
self._trace_ind = None

Expand Down Expand Up @@ -4387,6 +4390,74 @@ def _dispatch_on_selection(self,
for callback in self._select_callbacks:
callback(self, points, selector)

# deselect
# --------
def on_deselect(
self,
callback,
append=False):
"""
Register function to be called when the user deselects points
in this trace using doubleclick.
Note: Callbacks will only be triggered when the trace belongs to a
instance of plotly.graph_objs.FigureWidget and it is displayed in an
ipywidget context. Callbacks will not be triggered on figures
that are displayed using plot/iplot.
Parameters
----------
callback
Callable function that accepts 3 arguments
- this trace
- plotly.callbacks.Points object
append : bool
If False (the default), this callback replaces any previously
defined on_deselect callbacks for this trace. If True,
this callback is appended to the list of any previously defined
callbacks.
Returns
-------
None
Examples
--------
>>> from plotly.callbacks import Points
>>> points = Points()
>>> def deselect_fn(trace, points):
... inds = points.point_inds
... # Do something
>>> trace.on_deselect(deselect_fn)
Note: The creation of the `points` object is optional,
it's simply a convenience to help the text editor perform completion
on the `points` arguments inside `selection_fn`
"""
if not append:
del self._deselect_callbacks[:]

if callback:
self._deselect_callbacks.append(callback)

def _dispatch_on_deselect(self, points):
"""
Dispatch points info to deselection callbacks
"""
if 'selectedpoints' in self:
# Update the selectedpoints property, which will notify all views
# of the selection change. This is a special case because no
# restyle event is emitted by plotly.js on selection events
# even though these events update the selectedpoints property.
self.selectedpoints = None

for callback in self._deselect_callbacks:
callback(self, points)


class BaseFrameHierarchyType(BasePlotlyType):
"""
Expand Down
2 changes: 2 additions & 0 deletions plotly/basewidget.py
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,8 @@ def _handler_js2py_pointsCallback(self, change):
trace._dispatch_on_unhover(points, state)
elif event_type == 'plotly_selected':
trace._dispatch_on_selection(points, selector)
elif event_type == 'plotly_deselect':
trace._dispatch_on_deselect(points)

self._js2py_pointsCallback = None

Expand Down
15 changes: 15 additions & 0 deletions plotlywidget/static/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13409,6 +13409,10 @@ var FigureView = widgets.DOMWidgetView.extend({
function (update) {
that.handle_plotly_selected(update)
});
that.el.on("plotly_deselect",
function (update) {
that.handle_plotly_deselect(update)
});
that.el.on("plotly_doubleclick",
function (update) {
that.handle_plotly_doubleclick(update)
Expand Down Expand Up @@ -13739,6 +13743,17 @@ var FigureView = widgets.DOMWidgetView.extend({
handle_plotly_selected: function (data) {
this._send_points_callback_message(data, "plotly_selected");
},

/**
* Handle plotly_deselect events emitted by the Plotly.js library
* @param data
*/
handle_plotly_deselect: function (data) {
data = {
points : []
}
this._send_points_callback_message(data, "plotly_deselect");
},

/**
* Build and send a points callback message to the Python side
Expand Down

0 comments on commit e426a19

Please sign in to comment.