如何基于MultiChoice控件切换Bokeh DataTable的列显示/隐藏
基于Bokeh实现MultiChoice控制DataTable列显示隐藏
针对你的需求,分两种场景给出解决方案,你可以根据自己的应用环境选择:
方案一:服务器端回调(适合依赖Python逻辑或动态数据场景)
如果你的应用运行在Bokeh Server上,使用Python更新函数逻辑更直观,维护起来也简单。核心是监听MultiChoice的选中值变化,遍历所有表格列并设置visible属性。
from bokeh.io import curdoc from bokeh.models import ColumnDataSource, DataTable, TableColumn, MultiChoice from bokeh.layouts import layout import pandas as pd # 模拟你的40+列数据集 df = pd.DataFrame({ "Date": pd.date_range(start="2024-01-01", periods=10), **{f"Col_{i}": range(10) for i in range(1, 40)} }) # 初始化数据源与表格列 filtered_table_source = ColumnDataSource(data=df) filtered_table_cols = [ TableColumn(field=col, title=col, width=150) for col in df.columns ] filtered_table = DataTable(source=filtered_table_source, columns=filtered_table_cols) # 初始化多选控件(Date列默认显示,不加入选项列表) multi_choice = MultiChoice( value=[f"Col_{i}" for i in range(1, 5)], options=df.columns[1:].tolist(), title='选择要显示的列:' ) def update(attr, old, new): # 固定Date列显示,加上选中的列 visible_cols = ["Date"] + new # 遍历所有列设置可见性 for col in filtered_table_cols: col.visible = col.field in visible_cols # 绑定值变化回调 multi_choice.on_change("value", update) # 初始执行一次,确保列显示符合默认选中值 update(None, None, multi_choice.value) l2 = layout([multi_choice, filtered_table]) curdoc().add_root(l2)
运行方式:执行bokeh serve --show your_script.py启动Bokeh服务。
方案二:客户端CustomJS回调(适合静态HTML场景)
如果只需要生成独立的静态HTML文件,不需要Bokeh Server,就用前端JS回调处理,完全在浏览器端完成列显示控制。
from bokeh.io import show from bokeh.models import ColumnDataSource, DataTable, TableColumn, MultiChoice, CustomJS from bokeh.layouts import layout import pandas as pd # 模拟数据集 df = pd.DataFrame({ "Date": pd.date_range(start="2024-01-01", periods=10), **{f"Col_{i}": range(10) for i in range(1, 40)} }) filtered_table_source = ColumnDataSource(data=df) filtered_table_cols = [ TableColumn(field=col, title=col, width=150) for col in df.columns ] filtered_table = DataTable(source=filtered_table_source, columns=filtered_table_cols) multi_choice = MultiChoice( value=[f"Col_{i}" for i in range(1, 5)], options=df.columns[1:].tolist(), title='选择要显示的列:' ) # 编写前端回调逻辑 callback = CustomJS(args=dict(table=filtered_table, multi_choice=multi_choice), code=""" const visibleCols = ["Date", ...multi_choice.value]; table.columns.forEach(col => { col.visible = visibleCols.includes(col.field); }); """) # 绑定JS回调到多选控件 multi_choice.js_on_change("value", callback) # 初始设置列可见性 initial_visible = ["Date"] + multi_choice.value for col in filtered_table_cols: col.visible = col.field in initial_visible l2 = layout([multi_choice, filtered_table]) show(l2)
运行后直接导出HTML即可,无需额外服务器支持。
选择建议
- 若需要处理动态数据、依赖Python后端逻辑,选服务器端回调;
- 若只是静态数据,要生成可分享的独立HTML,选客户端CustomJS回调。
内容的提问来源于stack exchange,提问作者Gingerhaze
相关产品推荐
相关产品推荐

