As described in #895, we needed a way to access streams on DynamicMaps wrapping other DynamicMaps or overlays containing one or more DynamicMaps. This PR implements a
Currently the Callable object is very straightforward, exposing a
Using two helper functions
The PR is still lacking docstrings and tests but it already works.
The best example to confirm it is working is this example of two separate selection callbacks attached to two separate data sources:
%%opts Points [tools=['box_select', 'lasso_select', 'tap']] points = hv.Points(np.random.multivariate_normal((0, 0), [[1, 0.1], [0.1, 1]], (1000,))) points2 = hv.Points(np.random.multivariate_normal((0, 0), [[1, 0.1], [0.1, 1]], (1000,))) sel1 = Selection1D() sel2 = Selection1D() hv.DynamicMap(lambda index: points, kdims=, streams=[sel1]) *\ hv.DynamicMap(lambda index: hv.HLine(points['y'][index].mean() if index else -10), kdims=, streams=[sel1]) *\ hv.DynamicMap(lambda index: points2, kdims=, streams=[sel2]) *\ hv.DynamicMap(lambda index: hv.HLine(points2['y'][index].mean() if index else -10), kdims=, streams=[sel2])
I've skimmed the PR and now I'm looking at it in detail. Overall it looks fine but I need to think about the implications for the user quite carefully.
My first thought was...could we offer a decorator that users can easily use to wrap any callable? A decorator would look nice and clean and would be very easy for the user to add at any point. In fact, couldn't this transformation be applied dynamically? For instance, the wrapped callback could be an underscore attribute in
Perhaps you have already done all this this and I'll find out once I look a bit more closely!
Ok, I feel I mostly understand it now... the most magical bit (i.e the bit I couldn't figure out!) seems to be in
I'll merge now on the understanding that we now have a plan to improve the user API side of things. This PR shows that this approach will allow nested