def find_links(root_view, root_model): """ Traverses the supplied Viewable searching for Links between any HoloViews based panes. """ if not isinstance(root_view, Panel): return hv_views = root_view.select(HoloViews) root_plots = [ plot for view in hv_views for plot, _ in view._plots.values() if getattr(plot, 'root', None) is root_model ] if not root_plots: return try: from holoviews.plotting.links import Link from holoviews.plotting.bokeh.callbacks import LinkCallback except: return plots = [ (plot, root_plot) for root_plot in root_plots for plot in root_plot.traverse(lambda x: x, [is_bokeh_element_plot]) ] potentials = [(LinkCallback.find_link(plot), root_plot) for plot, root_plot in plots] source_links = [p for p in potentials if p[0] is not None] found = [] for (plot, links), root_plot in source_links: for link in links: if link.target is None: # If link has no target don't look further found.append((link, plot, None)) continue potentials = [ LinkCallback.find_link(plot, link) for plot, inner_root in plots if inner_root is not root_plot ] tgt_links = [p for p in potentials if p is not None] if tgt_links: found.append((link, plot, tgt_links[0][0])) new_found = set(found) - root_view._found_links callbacks = [] for link, src_plot, tgt_plot in new_found: cb = Link._callbacks['bokeh'][type(link)] if src_plot is None or (getattr(link, '_requires_target', False) and tgt_plot is None): continue callbacks.append(cb(root_model, link, src_plot, tgt_plot)) root_view._found_links.update(new_found) return callbacks
def find_links(root_view, root_model): """ Traverses the supplied Viewable searching for Links between any HoloViews based panes. """ if not isinstance(root_view, Layout): return from holoviews.plotting.links import Link from holoviews.plotting.bokeh.callbacks import LinkCallback hv_views = root_view.select(HoloViews) root_plots = [ plot for view in hv_views for plot in view._plots.values() if plot.root is root_model ] plots = [ (plot, root_plot) for root_plot in root_plots for plot in root_plot.traverse(lambda x: x, [is_bokeh_element_plot]) ] potentials = [(LinkCallback.find_link(plot), root_plot) for plot, root_plot in plots] source_links = [p for p in potentials if p[0] is not None] found = [] for (plot, links), root_plot in source_links: for link in links: if link.target is None: # If link has no target don't look further found.append((link, plot, None)) continue potentials = [ LinkCallback.find_link(plot, link) for plot, inner_root in plots if inner_root is not root_plot ] tgt_links = [p for p in potentials if p is not None] if tgt_links: found.append((link, plot, tgt_links[0][0])) callbacks = [] for link, src_plot, tgt_plot in found: cb = Link._callbacks['bokeh'][type(link)] callbacks.append(cb(root_model, link, src_plot, tgt_plot)) return callbacks