Невозможно вставить JSON Bokeh Plot в шаблон Django - PullRequest
1 голос
/ 11 апреля 2019

У меня есть скрипт, который берет загруженные данные, объединяет их, превращает их в график (используя Bokeh) и затем экспортирует их в каталог как JSON.

В какой-то момент в будущем пользователь может нажать правильный URL-адрес, и соответствующий участок должен отображаться для пользователя как часть шаблона HTML.

Я могу создать сюжет. Я могу сохранить его как JSON. Я могу получить URL-адрес для его получения в формате JSON, но не могу отобразить график JSON в шаблоне.

Я копался в документации и примерах Bokeh, но все они, похоже, используют флягу для обслуживания страниц.

Я думаю, что я на правильном пути, используя views.py, чтобы найти и вернуть JSON как часть ответа render(), а затем Bokeh.embed.embed_items() выполнить работу в шаблоне, чтобы он выглядел правильно, но не получается - все, кроме сюжета отображается.

1) Создайте график и поместите его в каталог для последующего использования (app / results / 1)

создать plot.py

import os
import json
from django.conf import settings
from bokeh.embed import json_item
from bokeh.plotting import figure

x=[1,2,3,4,5]
y=[0,-1,-2,3,4]

p=figure(title="test_example")
p.line(x, y)
#json_export = json_item(p, "result")
json_export = json_item(p)
with open(os.path.join(settings.RESULTS_DIR,"1", "test.json"), 'w') as fp:
    fp.write(json.dumps(json_export))

2) Настройка URL

urls.py

urlpatterns=[
    path('result/<int:pk>', views.resultdetailview, name='result-detail'),
]

3) Возьмите запрос, используйте pk, чтобы найти график json и отобразите все это в соответствующем шаблоне.

views.py

def resultdetailview(request, pk):
    results=str(pk)
    with open(os.path.join(settings.RESULTS_DIR, results, "test.json"), 'r') as fp:
        #data=json.load(fp)
        data=json.loads(fp.read())

    #context={'result':data}
    #return render(request, 'app/sandbox_detail.html', context)
    return render(request=request,
                    context={'json_object':data, 'resources':CDN.render()})

NB: Если я вместо этого использую return JsonResponse(data, safe=False), тогда URL-адрес успешно возвращает json ...

Поэтому я думаю, что проблема в шаблоне.

4) Покажите удивительный сюжет пользователю

sandbox_detail.html

<header>
<link rel="stylesheet" href="http://cdn.pydata.org./bokeh/release/bokeh-0.11.1.min.css" type="text/css" >
<script type="text/javascript" src="http://cdn.pydata.org./bokeh/release/bokeh-0.11.1.min.js"> </script>
</header>

<h1> Title: Test </h1>
<div>Test</div>

<body>
    <div id="result"></div>
    <script>
        Bokeh.embed.embed_item({{json_object}}, "result");
    </script>
</body>

Этот шаблон отображает все, кроме div "result".

Что я пропустил?

Ответы [ 2 ]

1 голос
/ 11 апреля 2019

Вот что я вижу до сих пор:

FIRST: Вы смешиваете 2 метода для ввода данных json графика на страницу. Согласно документации вы можете сделать это одним из следующих двух способов:

1) укажите div напрямую:

Python: json_data = json.dumps(json_item(p, "myplot"))
JavaScript: Bokeh.embed.embed_item(item);

2) укажите функцию div in embed_item:

Python: json_data = json.dumps(json_item(p))
JavaScript: Bokeh.embed.embed_item(item, "myplot");

Но не оба из них одновременно. Может ли это быть проблемой?

ВТОРОЕ: Желательно не вставлять ресурсы Bokeh вручную: лучше использовать CDN.render () или INLINE.render (), чтобы автоматически включить все, что нужно вашему сценарию:

import json
from bokeh.resources import CDN

return render(request  = request, 
              template_name = 'app/sandbox_detail.html', 
              context = { json_object = json.loads(json_string), 
                          resources = CDN.render() } )

sandbox_detail.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
{{ resources }}
</head>
<body>
<div id="result"></div>
<script>
    Bokeh.embed.embed_item({{ json_object }}, "result");
</script>
</body>
</html>

THIRD: Убедитесь, что вы вставили на страницу объект json, а не строку (см. Именование переменных выше)

0 голосов
/ 23 апреля 2019

Помогает, когда вы отлаживаете отрендеренный шаблон в инструменте отладки вашего браузера.

Я попробовал очень похожий подход и обнаружил один большой недостаток: мой браузер заметил, что не может найти объект None.Причина в том, что python хранит пустое значение как None, в то время как JavaScript ожидает объект null.

Решение?Python уже переводит None в null, когда вы запускаете json.dumps.Чтобы сохранить это, прочитайте строку json как строку.Так что вместо data=json.loads(fp.read()) используйте data=fp.read().

...