Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support link_selections on dynamic overlays #4683

Merged
merged 3 commits into from
Nov 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions holoviews/selection.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,12 @@ def _selection_transform(self, hvobj, operations=()):
self._selection_streams, hvobj, operations,
self._selection_expr_streams.get(hvobj, None), cache=self._cache
)
elif (issubclass(hvobj.type, Overlay) and
getattr(hvobj.callback, "name", None) == "dynamic_mul"):
return Overlay([
self._selection_transform(el, operations=operations)
for el in callback.inputs
]).collate()
else:
# This is a DynamicMap that we don't know how to recurse into.
return hvobj
Expand Down
4 changes: 3 additions & 1 deletion holoviews/streams.py
Original file line number Diff line number Diff line change
Expand Up @@ -1020,7 +1020,7 @@ def transform_function(cls, stream_values, constants):
return

selection_expr, bbox, region_element = selection

if selection_expr is not None:
break

Expand Down Expand Up @@ -1107,6 +1107,8 @@ def transform_function(cls, stream_values, constants):
combined_region_element = None

for selection_contents in stream_values[0]["values"]:
if selection_contents is None:
continue
selection_expr = selection_contents['selection_expr']
if not selection_expr:
continue
Expand Down
65 changes: 65 additions & 0 deletions holoviews/tests/testselection.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,71 @@ def test_datashade_selection(self):
)[()]
)

@ds_skip
def test_datashade_in_overlay_selection(self):
points = Points(self.data)
layout = points * dynspread(datashade(points))

lnk_sel = link_selections.instance(unselected_color='#ff0000')
linked = lnk_sel(layout)
current_obj = linked[()]

# Check base points layer
self.check_base_points_like(current_obj[()].Points.I, lnk_sel)

# Check selection layer
self.check_overlay_points_like(current_obj[()].Points.II, lnk_sel, self.data)

# Check RGB base layer
self.assertEqual(
current_obj[()].RGB.I,
dynspread(
datashade(points, cmap=lnk_sel.unselected_cmap, alpha=255)
)[()]
)

# Check RGB selection layer
self.assertEqual(
current_obj[()].RGB.II,
dynspread(
datashade(points, cmap=lnk_sel.selected_cmap, alpha=255)
)[()]
)

# Perform selection of second and third point
selectionxy = TestLinkSelections.get_value_with_key_type(
lnk_sel._selection_expr_streams, hv.Points
).input_streams[0].input_stream.input_streams[0]

self.assertIsInstance(selectionxy, SelectionXY)
selectionxy.event(bounds=(0, 1, 5, 5))
current_obj = linked[()]

# Check that base points layer is unchanged
self.check_base_points_like(current_obj[()].Points.I, lnk_sel)

# Check points selection layer
self.check_overlay_points_like(current_obj[()].Points.II, lnk_sel,
self.data.iloc[1:])

# Check that base RGB layer is unchanged
self.assertEqual(
current_obj[()].RGB.I,
dynspread(
datashade(points, cmap=lnk_sel.unselected_cmap, alpha=255)
)[()]
)

# Check selection RGB layer
self.assertEqual(
current_obj[()].RGB.II,
dynspread(
datashade(
points.iloc[1:], cmap=lnk_sel.selected_cmap, alpha=255
)
)[()]
)

def test_points_selection_streaming(self):
buffer = hv.streams.Buffer(self.data.iloc[:2], index=False)
points = hv.DynamicMap(Points, streams=[buffer])
Expand Down