所以解决办法是:
1
将您的散景文档(整个仪表板)转换为 .json 并将其作为文件下载。
例如,您可以通过单击按钮来完成此操作。
# creating button
download_json = Button(label="Download json", width=70)
# callback
download_json_func = CustomJS(args=dict(source=source_fill_groupby),code="""
function saveText(text, filename){
var a = document.createElement('a');
a.setAttribute('href', 'data:text/plain;charset=utf-8,'+encodeURIComponent(text));
a.setAttribute('download', filename);
a.click()
}
var obj = Bokeh.documents[0].to_json_string();
saveText( JSON.stringify(obj), "filename.json" );
""")
# assigning callback to the button
download_json.js_on_event(ButtonClick, download_json_func)
2
下载文件后,您需要在 Jupyter 笔记本的下一个单元中恢复它。假设应该有 FileInput-widget,以便我们可以上传文件并且它会出现在 div 块中。
from bokeh.models.widgets import FileInput
# creating div where our saved dashboard will be shown
div = Div(text='<div id="document-container"></div>', width=500, height=500)
# adding widget
l = FileInput(accept='.json')
# callback
l.js_on_change('value', CustomJS(code="""\
const {Document} = Bokeh.require('document/document');
// uploaded .json-file
const data = JSON.parse(atob(cb_obj.value));
const doc = Document.from_json_string(data);
// dashboard to show
Bokeh.embed.add_document_standalone(doc, document.getElementById('document-container'), [], true);
cb_obj.disabled = true;
"""))
show(column(l, div))
它仍然存在一些问题 - 它不能正确显示 ciryllic,并且如果您进行新查询并创建新绘图,则在保存文档后,绘图不会从上一个绘图开始更新其范围。将绘图保存到最后一个选项卡也存在一些问题 - 它不像在 Bokeh 中那样工作。但至少你可以保存你的研究“进展”。
更新1。要正确显示西里尔文,您应该对 FileInput 使用下一个回调:
l.js_on_change('value', CustomJS(code="""
function b64DecodeUnicode(str) {
// Going backwards: from bytestream, to percent-encoding, to original string.
return decodeURIComponent(atob(str).split('').map(function(c) {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
}).join(''));
}
const {Document} = Bokeh.require('document/document');
const data = JSON.parse(b64DecodeUnicode(cb_obj.value));
const doc = Document.from_json_string(data);
Bokeh.embed.add_document_standalone(doc, document.getElementById('document-container1'), [], true);
cb_obj.disabled = true;
"""))