如何结合散景小部件和HTML标签?

问题描述 投票:0回答:1

我用bokeh制作了一个简单的表格,如下所示:

Form made by bokeh

我想为用户创建一个可下载的链接,当用户点击该按钮时,可以下载excel表。我尝试在散景表单中添加一个html标签,并将其href属性设置为服务器上Excel表格的地址。但我明白它导致了SyntaxError。

代码如下:

from bokeh.io import output_file, show
from bokeh.layouts import widgetbox
from bokeh.models.widgets import TextInput, Button, Div
from bokeh.layouts import layout, column, row
from bokeh.io import curdoc ## to assign callback to widget

from bokeh import events    ## for event handling
from bokeh.models import CustomJS

import numpy as np
import pandas as pd

text_input_mean = TextInput(value="0.0", title="Enter mean:")
text_input_vaiance = TextInput(value="0.0", title="Enter variance:")
text_input_rows = TextInput(value="5", title="Enter num rows:")
text_input_columns = TextInput(value="5", title="Enter num columns:")

button = Button(label = "Generate Dataframe", button_type = "success")

text_output = TextInput(title = 'Python result is shown here: ')

div = Div(text="""Making a form with bokeh mainly to handle events.""",
width=500, height=50)

layout = column(div, row(text_input_mean, text_input_vaiance),   row(text_input_rows, text_input_columns),
            button, text_output)


def my_text_input_handler(attr, old, new):
    print("Previous label: " + old)
    print("Updated label: " + new)
text_input_mean.on_change("value", my_text_input_handler)

def button_click_handler():
    text_output.__setattr__('value', str(text_input_mean.value))
    text_output.value = str(text_input_mean.value)


def generate_normal_df():
    mean = text_input_mean.value
    variance = text_input_vaiance.value
    row_num = x
    col_num = y
    return pd.DataFrame(np.random.normal(loc = mean, scale = variance,  size=(row_num, col_num)))

button.on_click(button_click_handler)
curdoc().add_root(layout)

# this part causes error!
<html>
<b> End of page </b>
# a tag goes here
<\html>

我还没有实现如何获取生成的excel表的地址。我的想法是将数据框保存为Excel工作表;通过使用os库获取其地址,并设置标记的href属性。但是.python形式的html部分会导致错误。

能否请你提一下解决方案应该是什么?有没有办法用散景形式写html?例如,标签不可用作窗口小部件。感谢您的关注。

python bokeh
1个回答
1
投票

您可以为按钮创建纯JS回调,并将数据作为JSON下载而不涉及服务器,如下所示:

from bokeh.io import show
from bokeh.plotting import figure
from bokeh import events
from bokeh.models import CustomJS, Div, Button, RadioButtonGroup
from bokeh.layouts import column, row
import numpy as np

data = {'mean': np.arange(10), 'variance': np.random.random(10) }
button = Button(label = "Download JSON", button_type = "success")

js_download = """
var filename = 'results.json';
var blob = new Blob([JSON.stringify(data)], { type: 'text/json;charset=utf-8;' });
if (navigator.msSaveBlob) { // IE 10+
navigator.msSaveBlob(blob, filename);
} else {
var link = document.createElement("a");
if (link.download !== undefined) { // feature detection
    // Browsers that support HTML5 download attribute
    var url = URL.createObjectURL(blob);
    link.setAttribute("href", url);
    link.setAttribute("download", filename);
    link.style.visibility = 'hidden';
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link); } }"""

button.callback = CustomJS(args = dict(data = data), code = js_download)
show(button)

只需将正确的对象传递给回调即可从(例如您的数据帧)中提取数据。如果您更喜欢从服务器获取数据,那么最简单的方法是在回调中使用JS fetch()方法,就像在this example中一样。在这种情况下,您需要将代码运行为:bokeh serve --show my_app_directory,您需要一个/static目录,您可以在其中保存文件并将其从返回浏览器提供。或者你可以在JS回调中使用类似AjaxDataSource或纯AJAX的东西从服务器获取json并让用户下载它,如上例所示(在Bokeh v1.0.4上测试)。

© www.soinside.com 2019 - 2024. All rights reserved.