使用on_change回调,我可以在Bokeh中获取DataTable中所选内容的数字行索引。 是否有可能: a)获取列索引 b)中获得的指标(值的列和行头)
示例代码:
from bokeh.io import curdoc
from bokeh.layouts import row, column
import pandas as pd
from bokeh.models import ColumnDataSource, ColorBar, DataTable, DateFormatter, TableColumn, HoverTool, Spacer, DatetimeTickFormatter
'''
Pandas
'''
df = pd.DataFrame(data = {'Apples': [5,10], 'Bananas': [16,15], 'Oranges': [6,4]})
df.rename(index={0:'A',1:'B'}, inplace=True)
'''
BOKEH
'''
sourceTableSummary = ColumnDataSource(df)
Columns = [TableColumn(field=colIndex, title=colIndex) for colIndex in df.columns]
data_table = DataTable(columns=Columns, source=sourceTableSummary, index_position = 0, width = 1900, height = 200, fit_columns=False)
'''
Funcs
'''
def return_value(attr, old, new):
selectionRowIndex=sourceTableSummary.selected.indices[0]
print("Selected Row Index ", str(selectionRowIndex))
selectionValue=sourceTableSummary.data['Apples'][selectionRowIndex]
print("Selected value for Apples ", str(selectionValue))
# selectionColumnIndex?
# selectionRowHeader?
# selectionColumnHeader?
sourceTableSummary.on_change('selected', return_value)
curdoc().add_root(column(children=[data_table]))
这给出了以下其可以返回行,而选择内的值。如果我总是希望返回单个列,则这是理想的。但是,选择UI(虚线)似乎表明特定的列是已知的,而不仅仅是行。 如果没有达到所选列的方式,我可以看看它同时使用行索引和单元格的值?
答案 0 :(得分:1)
以下代码使用JS回调显示行索引和列索引以及单元格内容。第二个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))
结果: