如何通过MultiChoice调整Bokeh DataTable的显示列
Bokeh DataTable 动态显示选中列解决方案
问题原因
空列问题根源是:仅更新了ColumnDataSource的数据源,但DataTable的columns属性还是初始化时传入的全量列配置,未选中的列没有被移除。
核心改动点
- 给
CustomJS回调新增入参,传入data_table实例和预先定义好的全量列配置all_columns - 回调中先根据选中的字段过滤出需要显示的列,直接赋值给
data_table.columns实现列的动态增减 - 修复原数据源更新逻辑的bug:原代码直接用数组作为字段名操作数据源,会导致字段赋值错误,改为遍历增删的字段逐个处理
完整可运行代码
from bokeh.io import output_file, show from bokeh.layouts import column from bokeh.models import ColumnDataSource, CustomJS, MultiChoice from bokeh.models.widgets import DataTable, TableColumn import pandas as pd data = pd.DataFrame({'Name': ['A', 'B', 'C', 'D'], 'Age': [10, 20, 30, 40], 'Sex': ['M', 'F', 'X', 'Y']}) vars = list(data.columns) initial_vars = vars[:1] original_data = ColumnDataSource(data) source = ColumnDataSource(data[initial_vars]) all_columns = [TableColumn(field=Ci, title=Ci) for Ci in vars] # 全量列配置 # 初始化只展示选中的初始列 data_table = DataTable(columns=[col for col in all_columns if col.field in initial_vars], source=source) var_selector_callback = CustomJS(args=dict(original_data=original_data, all_columns=all_columns, source=source, data_table=data_table), code=""" const original = original_data.data; const data = source.data; const data_keys = Object.keys(data) const selected_vars = cb_obj.value; // 1. 同步更新显示的列 data_table.columns = all_columns.filter(col => selected_vars.includes(col.field)) // 2. 更新数据源 // 新增选中的字段 selected_vars.forEach(field => { if (!data_keys.includes(field)) { data[field] = original[field] } }) // 删除未选中的字段,保留Bokeh默认生成的index字段避免报错 data_keys.forEach(field => { if (!selected_vars.includes(field) && field !== 'index') { delete data[field] } }) source.change.emit(); data_table.change.emit(); """) var_selector = MultiChoice(value=initial_vars, options=vars) var_selector.js_on_change('value', var_selector_callback) output_file("var_selector.html") show(column(var_selector, data_table))
内容的提问来源于stack exchange,提问作者dropout
相关产品推荐
相关产品推荐

