我有一个由“ select”更新的ColumnDataSource-具体来说,注册了一个回调,该回调在for循环上迭代,并且仅推送匹配的值。最后,我使用change.emit()发出更改。但是,它似乎没有更新基础的ColumnDataSource吗?
稍后使用第二个回调(链接到下载按钮并调用下载脚本)时,它应获取所有已过滤的columnDataSource并允许用户下载。但是,它总是下载初始化的ColumnDataSource,而不是根据用户输入更新的内容。
我怎么能...
非常感谢您的帮助。
编辑:我意识到这是在发生,因为我将ColumnDataSource和Button输出为不同的组件-这似乎破坏了两者之间的关系(测试是否可以将它们放入其中同一组组件)。无论如何,在保持关系的同时(我想在将它们嵌入网站的位置上具有完全的灵活性,即不使用Bokeh的预定义布局选项)是完全可以做到的?
from bokeh.io import output_file, show
from bokeh.layouts import widgetbox, row, column
from bokeh.models.widgets import Select, DataTable, TableColumn, Button
from bokeh.models.sources import ColumnDataSource, CDSView
from bokeh.models import CustomJS
from bokeh.io import show, output_file, output_notebook
select = Select(title="Animal", options=["All","Cat","Dog"])
button = Button(label="Download", button_type="success")
source=ColumnDataSource(data=dict(Animal=["Cat","Cat","Cat","Cat","Dog","Dog","Dog","Dog",],Breed=["Siamese","Persian","Bengal","Burmese","Lab","Golden", "Poodle","Pug"]))
filtered=ColumnDataSource(data=dict(Animal=["Cat","Cat","Cat","Cat","Dog","Dog","Dog","Dog",],Breed=["Siamese","Persian","Bengal","Burmese","Lab","Golden", "Poodle","Pug"]))
columns = [TableColumn(field="Animal",title="Animal"),
TableColumn(field="Breed",title="Breed",sortable=True)]
data_table_filtered=DataTable(source=filtered,columns=columns, width=800 )
dropDown=ColumnDataSource(data=dict(dropDown=[""]))
callback = CustomJS(args=dict(filtered=filtered, unfiltered=source,
data_table_filtered=data_table_filtered, dropDown=dropDown), code="""
var data = unfiltered.data;
var f = cb_obj.value;
if(f != 'All') {
var newSource = filtered.data;
newSource['Animal']=[]
newSource['Breed']=[]
for(i = 0; i < data['Animal'].length;i++){
if(data['Animal'][i]==f){
newSource['Animal'].push(data['Animal'][i])
newSource['Breed'].push(data['Breed'][i])
}
}
}
else{
var newSource = filtered.data;
newSource['Animal']=[]
newSource['Breed']=[]
for(i = 0; i < data['Animal'].length;i++){
newSource['Animal'].push(data['Animal'][i])
newSource['Breed'].push(data['Breed'][i])
}
}
filtered.change.emit()
// trigger change on datatable
data_table_filtered.change.emit()
""")
select.js_on_change('value',callback)
button.callback = CustomJS(args=dict(filtered=filtered),
code=open(join(dirname(__file__), "download.js")).read())
wg = widgetbox(select,data_table_filtered)
wg1 = widgetbox(button)
script, div = components(wg)
script1, div1 = components(wg1)
return script,div,script1,div1
download.js:
var data = filtered.data;
console.log(data)
var filetext = 'Animal,Breed\n';
for (var i = 0; i < data['Animal'].length; i++) {
var currRow = [data['Animal'][i].toString(),
data['Breed'][i].toString().concat('\n')];
var joined = currRow.join();
filetext = filetext.concat(joined);
}
var filename = 'data_result.csv';
var blob = new Blob([filetext], { type: 'text/csv;charset=utf-8;' });
//addresses IE
if (navigator.msSaveBlob) {
navigator.msSaveBlob(blob, filename);
} else {
var link = document.createElement("a");
link = document.createElement('a')
link.href = URL.createObjectURL(blob);
link.download = filename
link.target = "_blank";
link.style.visibility = 'hidden';
link.dispatchEvent(new MouseEvent('click'))
}