Python Bokeh-使用两个同步的选择小部件过滤表

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

我想使用两个bokeh select小部件过滤表,请参见下面的代码结构。我定义了两个小部件,userm和location。首先,使用userm小部件选择用户(应更改表以及“位置”小部件),其次,选择具有location小部件的位置(应再次更改表)。

我的代码可以很好地根据用户筛选表,但是不会根据位置选择来更新位置小部件和表。我不确定是否可以在同一回调函数中全部实现。有任何想法吗?谢谢!

#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))
python select synchronization widget bokeh
1个回答
0
投票

可以在小部件之间共享单个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)
© www.soinside.com 2019 - 2024. All rights reserved.