繁体   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