You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Bokeh Table Widget中实现列选择而非行选择?

实现Bokeh表格列选择隐藏图表其他列的方案

好问题!Bokeh目前没有直接开箱即用的原生组件来实现「点击表格列头选中列并隐藏图表其他列」的功能,但咱们可以借助Bokeh的原生API和少量自定义代码轻松搞定——不需要从零构建全新组件。下面分两种常用场景给出实现方案:

一、静态HTML输出(用CustomJS回调)

如果你的应用是静态HTML(不需要Bokeh Server),可以通过CustomJS绑定表格列头的点击事件,动态修改图表中系列的可见性。基于你提供的示例代码,修改后的完整实现如下:

from datetime import date
from random import randint
from bokeh.io import output_file, show
from bokeh.layouts import row
from bokeh.models import ColumnDataSource, CustomJS
from bokeh.models.widgets import DataTable, DateFormatter, TableColumn
from bokeh.plotting import figure

output_file("data_table_column_select.html")

# 构造数据源
data = dict(
    dates=[date(2014, 3, i+1) for i in range(10)],
    downloads=[randint(0, 100) for i in range(10)],
    views=[randint(50, 200) for i in range(10)]  # 新增一列用于演示
)
source = ColumnDataSource(data)

# 创建表格列
columns = [
    TableColumn(field="dates", title="Date", formatter=DateFormatter()),
    TableColumn(field="downloads", title="Downloads"),
    TableColumn(field="views", title="Views"),
]
data_table = DataTable(source=source, columns=columns, width=400, height=280)

# 创建关联的折线图
p = figure(x_axis_type='datetime', width=600, height=280)
# 为每一列数据创建折线渲染器
downloads_line = p.line('dates', 'downloads', source=source, color='blue', legend_label='Downloads')
views_line = p.line('dates', 'views', source=source, color='red', legend_label='Views')

# 编写CustomJS回调:监听列头点击,切换图表系列可见性
callback = CustomJS(args=dict(renderers=[downloads_line, views_line], table=data_table), code="""
    // 获取点击的列头对应的field
    const clickedField = cb_obj.columns[cb_obj.active_cell.column].field;
    
    // 遍历所有图表渲染器,只保留与选中列匹配的系列可见
    renderers.forEach(renderer => {
        // 提取渲染器对应的y轴字段(假设是第二个参数)
        const rendererField = renderer.glyph.y.field;
        renderer.visible = (rendererField === clickedField) || clickedField === 'dates';
        // 注意:dates是x轴,始终保持可见;如果不需要可以去掉这个判断
    });
""")

# 给表格绑定点击事件:点击单元格时触发回调(这里通过active_cell变化来监听)
data_table.js_on_change('active_cell', callback)

# 布局并显示
show(row(data_table, p))

关键说明:

  • 我们通过监听DataTable的active_cell属性变化来捕获列头点击(点击列头时会选中该列的第一个单元格,触发active_cell更新)
  • 在CustomJS中,根据点击列的field值,遍历图表的所有渲染器,设置visible属性来控制显示/隐藏
  • 如果不需要x轴列(dates)始终可见,可以去掉判断条件中的clickedField === 'dates'

二、Bokeh Server应用(用Python回调)

如果你的应用基于Bokeh Server运行,用Python回调会更直观,不需要写JavaScript:

from datetime import date
from random import randint
from bokeh.io import curdoc
from bokeh.layouts import row
from bokeh.models import ColumnDataSource
from bokeh.models.widgets import DataTable, DateFormatter, TableColumn
from bokeh.plotting import figure

# 构造数据源
data = dict(
    dates=[date(2014, 3, i+1) for i in range(10)],
    downloads=[randint(0, 100) for i in range(10)],
    views=[randint(50, 200) for i in range(10)]
)
source = ColumnDataSource(data)

# 创建表格列
columns = [
    TableColumn(field="dates", title="Date", formatter=DateFormatter()),
    TableColumn(field="downloads", title="Downloads"),
    TableColumn(field="views", title="Views"),
]
data_table = DataTable(source=source, columns=columns, width=400, height=280)

# 创建关联的折线图
p = figure(x_axis_type='datetime', width=600, height=280)
downloads_line = p.line('dates', 'downloads', source=source, color='blue', legend_label='Downloads')
views_line = p.line('dates', 'views', source=source, color='red', legend_label='Views')
renderers = [downloads_line, views_line]

# Python回调函数:处理列选择逻辑
def update_plot_visibility(attr, old, new):
    if new is None:
        return
    clicked_field = data_table.columns[new.column].field
    for renderer in renderers:
        renderer_field = renderer.glyph.y.field
        renderer.visible = (renderer_field == clicked_field) or clicked_field == 'dates'

# 绑定回调到表格的active_cell属性
data_table.on_change('active_cell', update_plot_visibility)

# 添加到文档
curdoc().add_root(row(data_table, p))

关键说明:

  • 利用Bokeh Server的on_change方法,直接在Python中处理表格的active_cell变化事件
  • 逻辑和静态版本一致,但用Python编写更易维护,适合复杂的业务逻辑

总结

你不需要完全自定义组件,基于Bokeh原生的DataTable、CustomJS(或Python回调)就能实现需求。本质是通过监听表格的交互事件,动态修改图表渲染器的可见性——这属于基于Bokeh原生API的自定义逻辑开发,而非从零构建新组件。

内容的提问来源于stack exchange,提问作者Matt P.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:07:54