簡體   English   中英

如何在點擊時獲取Bokeh DataTable單元格內容?

[英]How to get Bokeh DataTable cell content on click?

您是否知道如何通過點擊獲取Bokeh DataTable單元格值?

如果我使用:

data = dict(
 items=bokehItems,
    values0=bokehValues0,
    values1=bokehValues1,
    values2=bokehValues2
)

source = ColumnDataSource(data)

columns = [
    TableColumn(field="items", title="Item"),
    TableColumn(field="values0", title="Value"),
    TableColumn(field="values1", title="Cluster"),
    TableColumn(field="values2", title="Interaction"),
]



data_table_worst_cases = DataTable(source=source, columns=columns, height=280,
                                   row_headers=False, fit_columns=True)


source.callback = CustomJS(args=dict(source=source), code="""
    console.log( cb_obj.get('data'));
""")

當我點擊表格時,我總是得到完整表格的內容,而不是特定的單元格。

此版本使用Python回調(針對Bokeh v1.0.4更新)。 運行方式: bokeh serve --show app.py

from random import randint
from datetime import date
from bokeh.models import ColumnDataSource, TableColumn, DateFormatter, DataTable
from bokeh.layouts import column
from bokeh.models.widgets import TextInput
from bokeh.plotting import curdoc

data = dict(dates = [date(2014, 3, i + 1) for i in range(10)],
            downloads = [randint(0, 100) for i in range(10)],
            identities = ['id_' + str(x) for x 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 = 280, height = 280, editable = True)
table_row = TextInput(value = '', title = "Row index:")
table_cell_column_1 = TextInput(value = '', title = "Date:")
table_cell_column_2 = TextInput(value = '', title = "Downloads:")

def function_source(attr, old, new):
    try:
        selected_index = source.selected.indices[0]
        table_row.value = str(selected_index)
        table_cell_column_1.value = str(source.data["dates"][selected_index])
        table_cell_column_2.value = str(source.data["downloads"][selected_index])
    except IndexError:
        pass

source.selected.on_change('indices', function_source)
curdoc().add_root(column(data_table, table_row, table_cell_column_1, table_cell_column_2))

結果:

在此輸入圖像描述

您沒有發布整個代碼,因此很難直接回答。 但是,根據下面的示例,您應該能夠找出解決問題的方法(針對Bokeh v1.0.4更新)。

from random import randint
from datetime import date
from bokeh.models import ColumnDataSource, TableColumn, DateFormatter, DataTable, CustomJS
from bokeh.layouts import column
from bokeh.models.widgets import TextInput
from bokeh.plotting import curdoc, show

source = ColumnDataSource(dict(dates = [date(2014, 3, i + 1) for i in range(10)], downloads = [randint(0, 100) for i in range(10)]))
columns = [TableColumn(field = "dates", title = "Date", formatter = DateFormatter()), TableColumn(field = "downloads", title = "Downloads")]
data_table = DataTable(source = source, columns = columns, width = 400, height = 280, editable = True, reorderable = False)

text_row = TextInput(value = None, title = "Row index:", width = 420)
text_date = TextInput(value = None, title = "Date:", width = 420)
text_downloads = TextInput(value = None, title = "Downloads:", width = 420)

source_code = """
row = cb_obj.indices[0]
text_row.value = String(row);
text_date.value = String(new Date(source.data['dates'][row]));
text_downloads.value = String(source.data['downloads'][row]); """

callback = CustomJS(args = dict(source = source, text_row = text_row, text_date = text_date, text_downloads = text_downloads), code = source_code)
source.selected.js_on_change('indices', callback)
layout = column(data_table, text_row, text_date, text_downloads)
show(layout)

結果:

在此輸入圖像描述

以下是如何區分正在單擊的表行和列的方法。 第二個Python回調是重置索引的技巧,以便可以檢測到同一行上的單擊(為Bokeh v1.0.4更新)。 運行bokeh serve --show app.py

from random import randint
from datetime import date
from bokeh.models import ColumnDataSource, TableColumn, DateFormatter, DataTable, CustomJS
from bokeh.layouts import column
from bokeh.models.widgets import TextInput
from bokeh.plotting import curdoc

source = ColumnDataSource(dict(dates = [date(2014, 3, i + 1) for i in range(10)], downloads = [randint(0, 100) for i in range(10)]))
columns = [TableColumn(field = "dates", title = "Date", formatter = DateFormatter()), TableColumn(field = "downloads", title = "Downloads")]
data_table = DataTable(source = source, columns = columns, width = 400, height = 280, editable = True, reorderable = False)

text_row = TextInput(value = None, title = "Row index:", width = 420)
text_column = TextInput(value = None, title = "Column Index:", width = 420)
text_date = TextInput(value = None, title = "Date:", width = 420)
text_downloads = TextInput(value = None, title = "Downloads:", width = 420)
test_cell = TextInput(value = None, title = "Cell Contents:", width = 420)

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

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')) 
                { column = j }
    }
}
text_row.value = String(row);
text_column.value = String(column);
text_date.value = String(new Date(source.data['dates'][row]));
text_downloads.value = String(source.data['downloads'][row]); 
test_cell.value = column == 1 ? text_date.value : text_downloads.value; """

def py_callback(attr, old, new):
    source.selected.update(indices = [])

source.selected.on_change('indices', py_callback)
callback = CustomJS(args = dict(source = source, text_row = text_row, text_column = text_column, text_date = text_date, text_downloads = text_downloads, test_cell = test_cell), code = source_code)
source.selected.js_on_change('indices', callback)
curdoc().add_root(column(data_table, text_row, text_column, text_date, text_downloads, test_cell))

結果:

在此輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM