我想使用两个bokeh select小部件来筛选一个表,请参见下面的代码结构。我定义了两个小部件: userm和locations。首先,选择使用userm小部件的用户(应该更改表和' locations‘小部件),其次,选择具有位置小部件的位置(应该再次更改表)。
我的代码可以很好地根据用户过滤表,但不会根据位置选择更新位置小部件和表。我不确定是否有可能在同一个回调函数中实现所有的功能。有什么想法吗?谢谢!
#Import libraries
from bokeh.io import output_notebook, show
from bokeh.layouts import widgetbox
from bokeh.models.widgets import Select, DataTable, TableColumn
from bokeh.models.sources import ColumnDataSource, CDSView
from bokeh.models import CustomJS, Select
import pandas as pd
output_notebook()
#Create the dataframe
df = pd.DataFrame({'Index': ['9', '10', '11', '12', '13'],
'Size': ['250', '150', '283', '433', '183'],
'X': ['751', '673', '542', '762', '624'],
'Y': ['458', '316', '287', '303', '297'],
'User': ['u1', 'u1', 'u2', 'u2', 'u2'],
'Location': ['A', 'B', 'C', 'C', 'D']
})
#Create widgets
userm = Select(title = "Select user:", options=list(set(df['User'])),
value=list(set(df['User']))[0])
locations = Select(title="Select location:", options=list(set(df['Location'])),
value=list(set(df['Location']))[0])
#Create data source
source=ColumnDataSource(data=dict(User=df['User'], Location=df['Location']))
filteredSource = ColumnDataSource(data=dict(User=[],Location=[]))
#Create data table
columns = [TableColumn(field="User",title="User"),
TableColumn(field="Location",title="Location",sortable=True)]
data_table=DataTable(source=filteredSource,columns=columns, width=400 )
data_table_unfiltered=DataTable(source=source,columns=columns, width=400 )
callback = CustomJS(args=dict(source=source,
filteredSource=filteredSource,
data_table=data_table), code="""
var data = source.data;
var f = cb_obj.value;
var df2 = filteredSource.data;
df2['User']=[]
df2['Location']=[]
locations=[]
for(i = 0; i < data['User'].length;i++){
if(data['User'][i]==f){
df2['User'].push(data['User'][i])
df2['Location'].push(data['Location'][i])
}
}
filteredSource.change.emit()
data_table.change.emit()
""")
userm.js_on_change('value', callback)
show(widgetbox(userm, locations, data_table))
发布于 2020-05-26 08:36:50
可以在小部件之间共享单个CustomJS
回调,但是不能使用cb_obj
。您必须显式地传递小部件。
callback = CustomJS(args=dict(source=source,
filteredSource=filteredSource,
userm=userm, locations=locations),
code="""
const data = source.data;
const userm_value = userm.value;
const locations_value = locations.value;
const df2 = filteredSource.data;
df2['User'] = [];
df2['Location'] = [];
for (let i = 0; i < data['User'].length; i++) {
if (data['User'][i] === userm_value && data['Location'][i] === locations_value) {
df2['User'].push(data['User'][i])
df2['Location'].push(data['Location'][i])
}
}
filteredSource.change.emit()
""")
userm.js_on_change('value', callback)
locations.js_on_change('value', callback)
https://stackoverflow.com/questions/62016965
复制相似问题