Источник данных столбца не обновляется при анализе второй функции обратного вызова - PullRequest
0 голосов
/ 30 сентября 2018

У меня есть ColumnDataSource, который обновляется с помощью «select» - в частности, регистрируется обратный вызов, который перебирает циклы for и только выдвигает совпадающие значения.Наконец, я использую change.emit () для вывода изменений.Тем не менее, не похоже, чтобы обновить базовый ColumnDataSource?

Когда позже используется второй обратный вызов (который связан с кнопкой загрузки и вызывает скрипт загрузки), он должен принять любой отфильтрованный столбец DataSource и позволить пользователю загрузить.Тем не менее, он всегда загружает инициализированный ColumnDataSource, а не тот, который должен быть обновлен на основе ввода пользователя.

Как я могу либо ...

  • Сохранить cb_obj первого обратного вызова(так что это может быть проанализировано для второго, и та же фильтрация может быть выполнена снова - кажется немного расточительным?)
  • Правильно передать отфильтрованный 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'))
}
...