全息视图图表不会出现在 Django 站点中



我知道我可能做错了一些简单的事情,但我不知道还有什么地方可以得到答案。我创建了一个django网站,以下函数返回holoview html:

from django.shortcuts import render
from django.http import HttpResponseRedirect
from charts.models import Ord
from IPython.display import display_html
import pandas as pd
import holoviews as hv
hv.extension('bokeh')
renderer = hv.renderer('bokeh')
# Create your views here.
def displayChart(request):
    df = pd.DataFrame(list(Ord.objects.using('DB').all().values('ordtyp')[:500]))
    df = df.groupby([df.ordtyp]).size().reset_index(name='counts')
    bars = hv.Bars(df, kdims=[('ordtyp', 'Order Type')], vdims=[('counts', 'Count of Orders')])
    hv.Store.registry['bokeh'][hv.Bars]
    html = renderer.html(bars)
    return render(request, 'charts/charts.html', {'html': html})

我在图表.html文件中放了一个块,作为:

{

{ html |safe }}

我得到的只是一张白纸。 然后,我获取了渲染器返回的原始 html,并尝试将其直接复制并粘贴到我的 HTML 文件中,并得到了同样的东西。 HTML 如下。此外,该图表确实适用于Jupyter Notebook...你能告诉我我做错了什么吗?

图表.html:

> <!DOCTYPE html>
> <html>
> <head>
>     <title>Charts</title>
> </head>
> <body>
>     {{html|safe}}
> </body>
> </html>

渲染器返回的原始 HTML:

<div style='display: table; margin: 0 auto;'>
    <div class="bk-root">
        <div class="bk-plotdiv" id="0dd69ef6-4d30-48f5-a95a-1201437920de"></div>
    </div>
<script type="text/javascript">
  (function(root) {
    function now() {
      return new Date();
    }
    var force = false;
    if (typeof (root._bokeh_onload_callbacks) === "undefined" || force === true) {
      root._bokeh_onload_callbacks = [];
      root._bokeh_is_loading = undefined;
    }

    if (typeof (root._bokeh_timeout) === "undefined" || force === true) {
      root._bokeh_timeout = Date.now() + 0;
      root._bokeh_failed_load = false;
    }
    var NB_LOAD_WARNING = {'data': {'text/html':
       "<div style='background-color: #fdd'>n"+
       "<p>n"+
       "BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this n"+
       "may be due to a slow or bad network connection. Possible fixes:n"+
       "</p>n"+
       "<ul>n"+
       "<li>re-rerun `output_notebook()` to attempt to load from CDN again, or</li>n"+
       "<li>use INLINE resources instead, as so:</li>n"+
       "</ul>n"+
       "<code>n"+
       "from bokeh.resources import INLINEn"+
       "output_notebook(resources=INLINE)n"+
       "</code>n"+
       "</div>"}};
    function display_loaded() {
      if (root.Bokeh !== undefined) {
        var el = document.getElementById("0dd69ef6-4d30-48f5-a95a-1201437920de");
        if (el != null) {
          el.textContent = "BokehJS " + Bokeh.version + " successfully loaded.";
        }
      } else if (Date.now() < root._bokeh_timeout) {
        setTimeout(display_loaded, 100)
      }
    }

    function run_callbacks() {
      try {
        root._bokeh_onload_callbacks.forEach(function(callback) { callback() });
      }
      finally {
        delete root._bokeh_onload_callbacks
      }
      console.info("Bokeh: all callbacks have finished");
    }
    function load_libs(js_urls, callback) {
      root._bokeh_onload_callbacks.push(callback);
      if (root._bokeh_is_loading > 0) {
        console.log("Bokeh: BokehJS is being loaded, scheduling callback at", now());
        return null;
      }
      if (js_urls == null || js_urls.length === 0) {
        run_callbacks();
        return null;
      }
      console.log("Bokeh: BokehJS not loaded, scheduling load and callback at", now());
      root._bokeh_is_loading = js_urls.length;
      for (var i = 0; i < js_urls.length; i++) {
        var url = js_urls[i];
        var s = document.createElement('script');
        s.src = url;
        s.async = false;
        s.onreadystatechange = s.onload = function() {
          root._bokeh_is_loading--;
          if (root._bokeh_is_loading === 0) {
            console.log("Bokeh: all BokehJS libraries loaded");
            run_callbacks()
          }
        };
        s.onerror = function() {
          console.warn("failed to load library " + url);
        };
        console.log("Bokeh: injecting script tag for BokehJS library: ", url);
        document.getElementsByTagName("head")[0].appendChild(s);
      }
    };var element = document.getElementById("0dd69ef6-4d30-48f5-a95a-1201437920de");
    if (element == null) {
      console.log("Bokeh: ERROR: autoload.js configured with elementid '0dd69ef6-4d30-48f5-a95a-1201437920de' but no matching script tag was found. ")
      return false;
    }
    var js_urls = [];
    var inline_js = [
      function(Bokeh) {
        (function() {
          var fn = function() {
            var docs_json = {"c7d02456-4a61-46d2-8431-34face1e6c67":{"roots":{"references":[{"attributes":{"callback":null,"column_names":["ORDTYP","counts"],"data":{"ORDTYP":["CC","CD","CZ","DB","DR","ED","EI","IC","ID","IP","MC","MF","MI","MK","MP","MS","MX","PC","PM","PT","SD","TI","TX","ZLR"],"counts":[60,3,2,17,1,13,2,28,21,1,3,6,1,2,2,35,10,20,12,2,525,7,225,1]}},"id":"46c2f30a-31d4-4c3f-ade2-4de96e13a4db","type":"ColumnDataSource"},{"attributes":{"active_drag":"auto","active_inspect":"auto","active_scroll":"auto","active_tap":"auto","tools":[{"id":"16eb22e8-c448-49d7-ab20-a02f2ebb3e5c","type":"SaveTool"},{"id":"218dbf74-8190-491c-b2dc-d13097c1f9e4","type":"PanTool"},{"id":"03f67199-1622-4784-b9a2-b36b4a47477b","type":"WheelZoomTool"},{"id":"d48948b1-297b-4915-bf84-916a417b01ee","type":"BoxZoomTool"},{"id":"722ae387-76c5-48cb-a387-7090de91b014","type":"ResetTool"}]},"id":"8ce67c3d-e8dc-41a2-86a8-76685fb90fe9","type":"Toolbar"},{"attributes":{"callback":null,"end":525,"start":0},"id":"16f5dfe6-08a6-4ad8-a190-bdf67979b26c","type":"DataRange1d"},{"attributes":{},"id":"bfe7ff64-0995-43a7-8944-6d491bf93b14","type":"CategoricalTicker"},{"attributes":{"callback":null,"factors":["CC","CD","CZ","DB","DR","ED","EI","IC","ID","IP","MC","MF","MI","MK","MP","MS","MX","PC","PM","PT","SD","TI","TX","ZLR"]},"id":"36f2f454-71a9-4511-a446-2c56a015ecd0","type":"FactorRange"},{"attributes":{"axis_label":"Count of Orders","formatter":{"id":"7303c9ca-b3e1-40be-bd44-1ef7f06d8a2d","type":"BasicTickFormatter"},"plot":{"id":"c84e964a-0b0b-4d95-aa2c-3657b7811bd0","subtype":"Figure","type":"Plot"},"ticker":{"id":"95b801e5-1f32-4ff1-be0c-e64ddcb14fa3","type":"BasicTicker"}},"id":"bd1e5045-1d72-4e92-8914-13be1ee0d04f","type":"LinearAxis"},{"attributes":{},"id":"95b801e5-1f32-4ff1-be0c-e64ddcb14fa3","type":"BasicTicker"},{"attributes":{"grid_line_color":{"value":null},"plot":{"id":"c84e964a-0b0b-4d95-aa2c-3657b7811bd0","subtype":"Figure","type":"Plot"},"ticker":{"id":"bfe7ff64-0995-43a7-8944-6d491bf93b14","type":"CategoricalTicker"}},"id":"0dee56d3-b965-4d15-bf6d-93cd1ea2a20d","type":"Grid"},{"attributes":{"bottom_units":"screen","fill_alpha":{"value":0.5},"fill_color":{"value":"lightgrey"},"left_units":"screen","level":"overlay","line_alpha":{"value":1.0},"line_color":{"value":"black"},"line_dash":[4,4],"line_width":{"value":2},"plot":null,"render_mode":"css","right_units":"screen","top_units":"screen"},"id":"2a376fc3-0bcc-47df-a0e8-2389040d3254","type":"BoxAnnotation"},{"attributes":{"plot":null,"text":"","text_color":{"value":"black"},"text_font_size":{"value":"12pt"}},"id":"04310042-3ae0-4955-bd48-3d9c8e2d9be2","type":"Title"},{"attributes":{},"id":"722ae387-76c5-48cb-a387-7090de91b014","type":"ResetTool"},{"attributes":{"dimension":1,"grid_line_color":{"value":null},"plot":{"id":"c84e964a-0b0b-4d95-aa2c-3657b7811bd0","subtype":"Figure","type":"Plot"},"ticker":{"id":"95b801e5-1f32-4ff1-be0c-e64ddcb14fa3","type":"BasicTicker"}},"id":"a281b265-486f-42a3-829a-c71bfd6830d0","type":"Grid"},{"attributes":{"axis_label":"Order Type","formatter":{"id":"259e4d35-20fb-4eb4-9fbd-6068fef93c0d","type":"CategoricalTickFormatter"},"plot":{"id":"c84e964a-0b0b-4d95-aa2c-3657b7811bd0","subtype":"Figure","type":"Plot"},"ticker":{"id":"bfe7ff64-0995-43a7-8944-6d491bf93b14","type":"CategoricalTicker"}},"id":"9f673b5b-85bf-40d1-96f3-b27737ecc242","type":"CategoricalAxis"},{"attributes":{},"id":"218dbf74-8190-491c-b2dc-d13097c1f9e4","type":"PanTool"},{"attributes":{},"id":"259e4d35-20fb-4eb4-9fbd-6068fef93c0d","type":"CategoricalTickFormatter"},{"attributes":{},"id":"16eb22e8-c448-49d7-ab20-a02f2ebb3e5c","type":"SaveTool"},{"attributes":{},"id":"721998c2-dee0-4e47-9a6d-ecef76d53889","type":"LinearScale"},{"attributes":{},"id":"03f67199-1622-4784-b9a2-b36b4a47477b","type":"WheelZoomTool"},{"attributes":{"overlay":{"id":"2a376fc3-0bcc-47df-a0e8-2389040d3254","type":"BoxAnnotation"}},"id":"d48948b1-297b-4915-bf84-916a417b01ee","type":"BoxZoomTool"},{"attributes":{"data_source":{"id":"46c2f30a-31d4-4c3f-ade2-4de96e13a4db","type":"ColumnDataSource"},"glyph":{"id":"3ab94627-160a-4913-95e6-c25fa17a1d51","type":"VBar"},"hover_glyph":null,"muted_glyph":null,"nonselection_glyph":{"id":"f72f6dc1-7c71-4f5e-80f9-fbd1351268b3","type":"VBar"},"selection_glyph":null,"view":{"id":"9df174a0-4967-47fd-82f3-3d054eee1a12","type":"CDSView"}},"id":"897248ec-4fbd-404c-b3b3-09900b6e3560","type":"GlyphRenderer"},{"attributes":{"fill_alpha":{"value":0.1},"fill_color":{"value":"#30a2da"},"line_alpha":{"value":0.1},"line_color":{"value":"#000000"},"top":{"field":"counts"},"width":{"value":0.8},"x":{"field":"ORDTYP"}},"id":"f72f6dc1-7c71-4f5e-80f9-fbd1351268b3","type":"VBar"},{"attributes":{"fill_color":{"value":"#30a2da"},"line_color":{"value":"#000000"},"top":{"field":"counts"},"width":{"value":0.8},"x":{"field":"ORDTYP"}},"id":"3ab94627-160a-4913-95e6-c25fa17a1d51","type":"VBar"},{"attributes":{"source":{"id":"46c2f30a-31d4-4c3f-ade2-4de96e13a4db","type":"ColumnDataSource"}},"id":"9df174a0-4967-47fd-82f3-3d054eee1a12","type":"CDSView"},{"attributes":{},"id":"eb1872c1-4fa5-47b0-b5c7-43dfe9b890e3","type":"CategoricalScale"},{"attributes":{},"id":"7303c9ca-b3e1-40be-bd44-1ef7f06d8a2d","type":"BasicTickFormatter"},{"attributes":{"background_fill_color":{"value":"white"},"below":[{"id":"9f673b5b-85bf-40d1-96f3-b27737ecc242","type":"CategoricalAxis"}],"left":[{"id":"bd1e5045-1d72-4e92-8914-13be1ee0d04f","type":"LinearAxis"}],"min_border_bottom":10,"min_border_left":10,"min_border_right":10,"min_border_top":10,"plot_height":300,"plot_width":300,"renderers":[{"id":"9f673b5b-85bf-40d1-96f3-b27737ecc242","type":"CategoricalAxis"},{"id":"0dee56d3-b965-4d15-bf6d-93cd1ea2a20d","type":"Grid"},{"id":"bd1e5045-1d72-4e92-8914-13be1ee0d04f","type":"LinearAxis"},{"id":"a281b265-486f-42a3-829a-c71bfd6830d0","type":"Grid"},{"id":"2a376fc3-0bcc-47df-a0e8-2389040d3254","type":"BoxAnnotation"},{"id":"897248ec-4fbd-404c-b3b3-09900b6e3560","type":"GlyphRenderer"}],"title":{"id":"04310042-3ae0-4955-bd48-3d9c8e2d9be2","type":"Title"},"toolbar":{"id":"8ce67c3d-e8dc-41a2-86a8-76685fb90fe9","type":"Toolbar"},"x_range":{"id":"36f2f454-71a9-4511-a446-2c56a015ecd0","type":"FactorRange"},"x_scale":{"id":"eb1872c1-4fa5-47b0-b5c7-43dfe9b890e3","type":"CategoricalScale"},"y_range":{"id":"16f5dfe6-08a6-4ad8-a190-bdf67979b26c","type":"DataRange1d"},"y_scale":{"id":"721998c2-dee0-4e47-9a6d-ecef76d53889","type":"LinearScale"}},"id":"c84e964a-0b0b-4d95-aa2c-3657b7811bd0","subtype":"Figure","type":"Plot"}],"root_ids":["c84e964a-0b0b-4d95-aa2c-3657b7811bd0"]},"title":"Bokeh Application","version":"0.12.7"}};
            var render_items = [{"docid":"c7d02456-4a61-46d2-8431-34face1e6c67","elementid":"0dd69ef6-4d30-48f5-a95a-1201437920de","modelid":"c84e964a-0b0b-4d95-aa2c-3657b7811bd0"}];
            Bokeh.embed.embed_items(docs_json, render_items);
          };
          if (document.readyState != "loading") fn();
          else document.addEventListener("DOMContentLoaded", fn);
        })();
      },
      function(Bokeh) {
      }
    ];
    function run_inline_js() {
      if ((root.Bokeh !== undefined) || (force === true)) {
        for (var i = 0; i < inline_js.length; i++) {
          inline_js[i].call(root, root.Bokeh);
        }if (force === true) {
          display_loaded();
        }} else if (Date.now() < root._bokeh_timeout) {
        setTimeout(run_inline_js, 100);
      } else if (!root._bokeh_failed_load) {
        console.log("Bokeh: BokehJS failed to load within specified timeout.");
        root._bokeh_failed_load = true;
      } else if (force !== true) {
        var cell = $(document.getElementById("0dd69ef6-4d30-48f5-a95a-1201437920de")).parents('.cell').data().cell;
        cell.output_area.append_execute_result(NB_LOAD_WARNING)
      }
    }
    if (root._bokeh_is_loading === 0) {
      console.log("Bokeh: BokehJS loaded, going straight to plotting");
      run_inline_js();
    } else {
      load_libs(js_urls, function() {
        console.log("Bokeh: BokehJS plotting callback run at", now());
        run_inline_js();
      });
    }
  }(window));
</script></div>

谢谢!

您缺少呈现此输出所需的 JS 和 CSS。您可以手动包含散景JS作为脚本标签,例如,对于散景0.12.9,您可以添加以下内容:

<link
href="http://cdn.bokeh.org/bokeh/release/bokeh-0.12.9.min.css"
rel="stylesheet" type="text/css">
<link
href="http://cdn.bokeh.org/bokeh/release/bokeh-widgets-0.12.9.min.css"
rel="stylesheet" type="text/css">
<script src="http://cdn.bokeh.org/bokeh/release/bokeh-0.12.9.min.js"></script>
<script src="http://cdn.bokeh.org/bokeh/release/bokeh-widgets-0.12.6.min.js"></script>

或者,您也可以使用 renderer.static_html 方法导出包含所有必需的 JS 和 CSS 的div,例如:

hmap = hv.HoloMap({i: hv.Curve(np.random.rand(10)*i) for i in range(1,5)})
html = hv.renderer('bokeh').static_html(hmap)
with open('test.html', 'w') as f:
    f.write(html)

static_html 方法还接受一个模板来分别嵌入 JS、CSS 和 HTML:

<html>
  <head>
    {css}
    {js}
  </head>
  <body>
    {html}
  </body>
</html>

在未来的版本中,我们还将有一个components方法,允许您分别获取JS,CSS和HTML组件。

最新更新