Выбрать столбцы (не строки) в Bokeh Table Widget? - PullRequest
0 голосов
/ 30 мая 2018

У меня есть таблица bokeh, которая связана с сюжетом и работает как задумано.Выбор строки в таблице отключает все невыбранные строки в отображении графика.

Однако, что если кто-то захочет выбрать столбец и скрыть все остальные столбцы на графике?Возможно ли это с помощью виджета боке?Или для этой функции нужно написать собственный код?Я приложил код, используемый для создания таблицы виджетов на веб-сайте bokeh, так как это самый простой пример, который я могу себе представить (и самый быстрый).

from datetime import date
from random import randint

from bokeh.io import output_file, show
from bokeh.layouts import widgetbox
from bokeh.models import ColumnDataSource
from bokeh.models.widgets import DataTable, DateFormatter, TableColumn

output_file("data_table.html")

data = dict(
        dates=[date(2014, 3, i+1) for i in range(10)],
        downloads=[randint(0, 100) for i in range(10)],
    )
source = ColumnDataSource(data)

columns = [
        TableColumn(field="dates", title="Date", formatter=DateFormatter()),
        TableColumn(field="downloads", title="Downloads"),
    ]
data_table = DataTable(source=source, columns=columns, width=400, height=280)

show(widgetbox(data_table))

Ответы [ 2 ]

0 голосов
/ 30 мая 2018

Вот код с обратным вызовом JS, который позволяет узнать выбранную строку и столбец.

from bokeh.io import show
from bokeh.layouts import widgetbox
from bokeh.models import ColumnDataSource, CustomJS
from bokeh.models.widgets import DataTable,TableColumn

column_list = ['col1','col2','col3']

source = ColumnDataSource(data = {key:range(10) for key in column_list})

columns = [TableColumn(field=col, title=col) for col in column_list]

data_table = DataTable(source=source, columns=columns, width=400, height=280,selectable=True)

source_code = """
var grid = document.getElementsByClassName('grid-canvas')[0].children;

var row = '';
var col = '';

for (var i=0,max=grid.length;i<max;i++){
    if (grid[i].outerHTML.includes('active')){
        row=i;
        for (var j=0,jmax=grid[i].children.length;j<jmax;j++){
            if(grid[i].children[j].outerHTML.includes('active')){col=j}
        }
    }
}

console.log('row',row);
console.log('col',col);

cb_obj.selected['1d'].indices = [];
"""

source.callback = CustomJS(code= source_code)

show(widgetbox(data_table))

Строка cb_obj.selected['1d'].indices = []; просто сбрасывает выбранные индексы, так что обратный вызов может сработать, даже еслищелчок по одной и той же ячейке несколько раз

Затем вы можете делать то, что вы хотите, с индексом строки / столбца

Если вам нужно, вы также можете "перенести" значения обратно в python, обновив ColumnDatasourceсо значениями строки и столбца.

Я использую bokeh 0.12.10, так что это может потребовать некоторых изменений в последней версии

EDIT: протестировано с 0.12.16 и все еще работает

РЕДАКТИРОВАТЬ: обновление для боке 1.1.0

from bokeh.io import show
from bokeh.layouts import widgetbox
from bokeh.models import ColumnDataSource, CustomJS
from bokeh.models.widgets import DataTable,TableColumn

column_list = ['col1','col2','col3']

source = ColumnDataSource(data = {key:range(20) for key in column_list})

columns = [TableColumn(field=col, title=col) for col in column_list]

data_table = DataTable(source=source, columns=columns, width=400, height=280,selectable=True)

source_code = """
var grid = document.getElementsByClassName('grid-canvas')[0];

var active_row = grid.querySelectorAll('.active')[0];

if (active_row!=undefined){

    var active_row_ID = Number(active_row.children[0].innerText);

    for (var i=1, imax=active_row.children.length; i<imax; i++){
        if (active_row.children[i].className.includes('active')){
            var active_col_ID = i-1;
        }
    }

    console.log('row',active_row_ID);
    console.log('col',active_col_ID);

    var active_cells = grid.querySelectorAll('.active');
    for (i=0, imax=active_cells.length;i<imax;i++){
        active_cells[i].classList.remove('active');
    }

    cb_obj.indices = [];
}
"""

source.selected.js_on_change('indices', CustomJS(args={'source':source},code= source_code) )

show(widgetbox(data_table))
0 голосов
/ 30 мая 2018

Начиная с Bokeh 0.12.16 встроенная DataTable не поддерживает какой-либо выбор столбцов или события щелчка.Глядя на описания Grid Events для базовой реализации SlickGrid, кажется, что onClick и onHeaderClick поддерживаются на низком уровне.Таким образом, сразу доступной опцией будет Расширение Bokeh с пользовательским DataTable подклассом.В противном случае вы можете отправить вопрос запроса функции GitHub , чтобы как-то обсудить представление этих событий во встроенной таблице.

...