diff --git a/holoviews/ipython/__init__.py b/holoviews/ipython/__init__.py index 90264211c4..a92c21af74 100644 --- a/holoviews/ipython/__init__.py +++ b/holoviews/ipython/__init__.py @@ -81,7 +81,7 @@ def load_hvjs(logo=False, JS=True, message='HoloViewsJS successfully loaded.'): """ # Evaluate load_notebook.html template with widgetjs code if JS: - widgetjs, widgetcss = Renderer.embed_assets() + widgetjs, widgetcss = Renderer.html_assets(extras=False, backends=[]) else: widgetjs, widgetcss = '', '' templateLoader = jinja2.FileSystemLoader(os.path.dirname(os.path.abspath(__file__))) @@ -165,8 +165,7 @@ def __call__(self, *args, **params): loaded = ', '.join(js_names[r] if r in js_names else r.capitalize()+'JS' for r in resources) - load_hvjs(logo=p.logo, - JS=('holoviews' in resources), + load_hvjs(logo=p.logo, JS=('holoviews' in resources), message = '%s successfully loaded in this cell.' % loaded) for r in [r for r in resources if r != 'holoviews']: Store.renderers[r].load_nb(inline=p.inline) diff --git a/holoviews/ipython/load_notebook.html b/holoviews/ipython/load_notebook.html index 12504ffbe0..92139da2b9 100644 --- a/holoviews/ipython/load_notebook.html +++ b/holoviews/ipython/load_notebook.html @@ -1,10 +1,6 @@ - +{{ widgetjs }} - +{{ widgetcss }} {% if logo %}
diff --git a/holoviews/plotting/bokeh/renderer.py b/holoviews/plotting/bokeh/renderer.py index b581f37785..80d8ef6c47 100644 --- a/holoviews/plotting/bokeh/renderer.py +++ b/holoviews/plotting/bokeh/renderer.py @@ -37,9 +37,7 @@ class BokehRenderer(Renderer): widgets = {'scrubber': BokehScrubberWidget, 'widgets': BokehSelectionWidget} - js_dependencies = Renderer.js_dependencies + CDN.js_files - - css_dependencies = Renderer.css_dependencies + CDN.css_files + backend_dependencies = {'js': CDN.js_files, 'css': CDN.css_files} _loaded = False diff --git a/holoviews/plotting/renderer.py b/holoviews/plotting/renderer.py index a4c16dd5ed..c3f648c317 100644 --- a/holoviews/plotting/renderer.py +++ b/holoviews/plotting/renderer.py @@ -123,10 +123,16 @@ class Renderer(Exporter): # Define appropriate widget classes widgets = {'scrubber': ScrubberWidget, 'widgets': SelectionWidget} - js_dependencies = ['https://code.jquery.com/jquery-2.1.4.min.js', - 'https://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.20/require.min.js'] + core_dependencies = {'jQueryUI': {'js': ['https://code.jquery.com/ui/1.10.4/jquery-ui.min.js'], + 'css': ['https://code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css']}} - css_dependencies = ['https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css'] + extra_dependencies = {'jQuery': {'js': ['https://code.jquery.com/jquery-2.1.4.min.js']}, + 'underscore': {'js': ['https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js']}, + 'require': {'js': ['https://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.20/require.min.js']}, + 'bootstrap': {'css': ['https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css']}} + + # Any additional JS and CSS dependencies required by a specific backend + backend_dependencies = {} def __init__(self, **params): super(Renderer, self).__init__(**params) @@ -238,18 +244,8 @@ def static_html(self, obj, fmt=None, template=None): supplied format. Allows supplying a template formatting string with fields to interpolate 'js', 'css' and the main 'html'. """ - css_html, js_html = '', '' - js, css = self.embed_assets() - for url in self.js_dependencies: - js_html += '' % url - js_html += '' % js - - for url in self.css_dependencies: - css_html += '' % url - css_html += '' % css - + js_html, css_html = self.html_assets() if template is None: template = static_template - html = self.html(obj, fmt) return template.format(js=js_html, css=css_html, html=html) @@ -340,10 +336,13 @@ class needed to render it with the current renderer. @classmethod - def embed_assets(cls): + def html_assets(cls, core=True, extras=True, backends=None): """ Returns JS and CSS and for embedding of widgets. """ + if backends is None: + backends = [cls.backend] if cls.backend else [] + # Get all the widgets and find the set of required js widget files widgets = [wdgt for r in Renderer.__subclasses__() for wdgt in r.widgets.values()] @@ -358,7 +357,26 @@ def embed_assets(cls): if f is not None ) widgetcss = '\n'.join(open(find_file(path, f), 'r').read() for f in css if f is not None) - return widgetjs, widgetcss + + dependencies = {} + if core: + dependencies.update(cls.core_dependencies) + if extras: + dependencies.update(cls.extra_dependencies) + for backend in backends: + dependencies['backend'] = Store.renderers[backend].backend_dependencies + + js_html, css_html = '', '' + for _, dep in sorted(dependencies.items(), key=lambda x: x[0]): + for js in dep.get('js', []): + js_html += '\n' % js + for css in dep.get('css', []): + css_html += '\n' % css + + js_html += '\n' % widgetjs + css_html += '\n' % widgetcss + + return js_html, css_html @classmethod diff --git a/holoviews/plotting/widgets/jsslider.css b/holoviews/plotting/widgets/jsslider.css index e6de73dfe1..25b9371e0b 100644 --- a/holoviews/plotting/widgets/jsslider.css +++ b/holoviews/plotting/widgets/jsslider.css @@ -11,6 +11,10 @@ form.holoform { padding: 0.8em; } +div.holowidgets { + padding-right: 0; +} + div.holoslider { min-height: 0 !important; height: 0.8em; @@ -24,7 +28,7 @@ div.holoformgroup { div.hologroup { padding-left: 0; - padding-right: 0.6em; + padding-right: 0; } .holoselect { diff --git a/holoviews/plotting/widgets/jsslider.jinja b/holoviews/plotting/widgets/jsslider.jinja index 6c61389fb1..b20495b411 100644 --- a/holoviews/plotting/widgets/jsslider.jinja +++ b/holoviews/plotting/widgets/jsslider.jinja @@ -24,7 +24,7 @@
{% elif widget_data['type']=='dropdown' %}