【问题标题】:Bokeh Data Table Linked to Select Widget链接到选择小部件的散景数据表
【发布时间】:2018-08-06 06:56:21
【问题描述】:

我正在尝试创建一个使用 customJS 回调链接到选择小部件的 Bokeh 数据表。这个想法是,当我更改选择时,数据表将更新以仅显示与所选选择值对应的相关行。我的代码如下:

from bokeh.io import output_file, 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


output_file("CatDog.html")




select = Select(title="Animal", options=["Cat","Dog"])

source=ColumnDataSource(data=dict(Animal=["Cat","Cat","Cat","Cat","Dog","Dog","Dog","Dog",],Breed=["Siamese","Persian","Bengal","Burmese","Lab","Golden", "Poodle","Pug"]))

filteredSource = ColumnDataSource(data=dict(Animal=[],Breed=[]))

columns = [TableColumn(field="Animal",title="Animal"),TableColumn(field="Breed",title="Breed",sortable=True)]

callback = CustomJS(args=dict(source=source,filteredSource = filteredSource), code="""
var data = source.data;
var f = cb_obj.value;
var d2 = filteredSource.data;
d2['Animal']=[]
d2['Breed']=[]


for(i = 0; i < data['Animal'].length;i++){

if(data['Animal'][i]==f){

    d2['Animal'].push(data['Animal'][i])
    d2['Breed'].push(data['Breed'][i])
}

}

alert(d2['Breed'])
filteredSource.change.emit()

""")

select.js_on_change('value',callback)

data_table=DataTable(source=filteredSource,columns=columns )
data_table_unfiltered=DataTable(source=source,columns=columns )
show(widgetbox(data_table,select,data_table_unfiltered))

警报正确显示我期望的行,具体取决于选择的类别,但“filteredSource”数据表没有更新,它保持空白。任何指导将不胜感激!

【问题讨论】:

    标签: javascript python bokeh


    【解决方案1】:

    这似乎是可行的,您需要触发数据表本身的更改。这个问题其实之前在这里问过:Bokeh DataTable won't update after trigger('change') without clicking on header

    不过,将您的代码稍微重新排列到以下可以解决问题(使用散景 0.12.14)

    from bokeh.io import output_file, 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
    
    
    output_file("CatDog.html")
    
    select = Select(title="Animal", options=["Cat","Dog"])
    
    source=ColumnDataSource(data=dict(Animal=["Cat","Cat","Cat","Cat","Dog","Dog","Dog","Dog",],Breed=["Siamese","Persian","Bengal","Burmese","Lab","Golden", "Poodle","Pug"]))
    
    filteredSource = ColumnDataSource(data=dict(Animal=[],Breed=[]))
    
    columns = [TableColumn(field="Animal",title="Animal"),
               TableColumn(field="Breed",title="Breed",sortable=True)]
    
    
    data_table=DataTable(source=filteredSource,columns=columns, width=800 )
    data_table_unfiltered=DataTable(source=source,columns=columns, width=800 )
    
    callback = CustomJS(args=dict(source=source,
                                  filteredSource=filteredSource,
                                  data_table=data_table), code="""
    var data = source.data;
    var f = cb_obj.value;
    var d2 = filteredSource.data;
    d2['Animal']=[]
    d2['Breed']=[]
    
    
    for(i = 0; i < data['Animal'].length;i++){
    
    if(data['Animal'][i]==f){
    
        d2['Animal'].push(data['Animal'][i])
        d2['Breed'].push(data['Breed'][i])
    }
    
    }
    
    filteredSource.change.emit()
    // trigger change on datatable
    data_table.change.emit()
    
    """)
    select.js_on_change('value',callback)
    show(widgetbox(data_table,select,data_table_unfiltered))
    

    【讨论】:

    • 为冗余道歉!有了这个,非常感谢这解决了这个问题。
    【解决方案2】:

    这是使用 CDSView、BooleanFilter 的更新答案。 使用 Bokeh 2.2.3 运行

    from bokeh.models import CDSView, BooleanFilter
    from bokeh.io import show, output_notebook
    from bokeh.layouts import column
    from bokeh.models.widgets import Select, DataTable, TableColumn
    from bokeh.models.sources import ColumnDataSource, CDSView
    from bokeh.models import CustomJS
    
    output_notebook()
    
    select = Select(title="Animal", options=["All","Cat","Dog"])
    
    source=ColumnDataSource(data=dict(Animal=["Cat","Cat","Cat","Cat","Dog","Dog","Dog","Dog"],
                                      Breed=["Siamese","Persian","Bengal","Burmese","Lab","Golden", "Poodle","Pug"]))
    
    booleans = [True for i in source.data['Animal']]
    view1 = CDSView(source=source, filters=[BooleanFilter(booleans)])
    
    columns = [TableColumn(field="Animal", title="Animal"),
               TableColumn(field="Breed", title="Breed", sortable=True)]
    
    data_table = DataTable(source=source, columns=columns, width=800, view=view1)
    
    callback = CustomJS(args=dict(source=source, view=view1), code="""
    var data = source.data;
    var f = cb_obj.value;
    for(var i = 0; i < data['Animal'].length; i++){
        if(data['Animal'][i] == f || f == 'All'){
            view.filters[0].booleans[i] = true;
        } else {
            view.filters[0].booleans[i] = false;
        }
    }
    source.change.emit();
    """)
    
    select.js_on_change('value',callback)
    show(column(select, data_table))```
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-22
      • 1970-01-01
      • 2018-11-09
      • 2020-11-26
      • 2017-10-19
      • 2017-01-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多