如何为Bokeh图表添加层级复选框以批量控制子项
Bokeh层级复选框批量控制实现
要实现“curves”主复选框批量控制子复选框的功能,需要添加单个主复选框,并通过CustomJS实现主、子复选框的双向联动逻辑,具体修改如下:
修改步骤
- 添加单个
Checkbox作为主控制开关(命名为“curves”) - 调整布局,将主复选框放在子复选框上方
- 编写两个回调函数:
- 主复选框触发时,批量设置子复选框的选中状态和线条可见性
- 子复选框触发时,更新主复选框的状态(全选/全不选时同步,部分选中时保持主复选框状态)
完整修改代码
import numpy as np from bokeh.layouts import column, row from bokeh.models import CustomJS, Checkbox, CheckboxGroup from bokeh.plotting import ColumnDataSource, figure, show # 初始数据 x = np.linspace(0, 10, 500) y = np.sin(x) z = np.cos(x) name_lst = ['sin', 'cos'] source = ColumnDataSource(data=dict(x=x, y=y, z=z)) # 创建绘图对象 fig = figure(width=200, height=200) line_renderer = [ fig.line('x', 'y', source=source, name=name_lst[0]), fig.line('x', 'z', source=source, name=name_lst[1]) ] # 初始状态:sin线隐藏,cos线显示 line_renderer[0].visible = False # 子复选框(控制单条曲线) sub_checkbox = CheckboxGroup( labels=name_lst, active=[1], # 修正原代码重复索引错误,初始仅cos选中 width=100 ) # 主复选框(批量控制所有曲线) main_checkbox = Checkbox(label="curves", active=True) # 初始选中,对应子项至少有一个选中 # 主复选框回调:批量控制子复选框和线条 main_callback = CustomJS(args=dict(lines=line_renderer, sub_cb=sub_checkbox, main_cb=main_checkbox), code=""" const all_indices = Array.from({length: sub_cb.labels.length}, (_, i) => i); if (main_cb.active) { // 主复选框选中:全选子复选框,显示所有线条 sub_cb.active = all_indices; lines.forEach(line => line.visible = true); } else { // 主复选框取消:清空子复选框,隐藏所有线条 sub_cb.active = []; lines.forEach(line => line.visible = false); } """) # 子复选框回调:控制单条线条显示,并同步主复选框状态 sub_callback = CustomJS(args=dict(lines=line_renderer, sub_cb=sub_checkbox, main_cb=main_checkbox), code=""" // 更新每条线条的可见性 lines.forEach((line, idx) => { line.visible = sub_cb.active.includes(idx); }); // 同步主复选框状态:子项全选则主框选中,全不选则取消,部分选中保持原状态 const all_count = sub_cb.labels.length; if (sub_cb.active.length === all_count) { main_cb.active = true; } else if (sub_cb.active.length === 0) { main_cb.active = false; } """) # 绑定回调事件 main_checkbox.js_on_change('active', main_callback) sub_checkbox.js_on_change('active', sub_callback) # 布局调整:主复选框在上,子复选框在下 control_layout = column(main_checkbox, sub_checkbox) layout = row(fig, control_layout) show(layout)
关键说明
- 修正了原代码中
CheckboxGroup的active=[1,1]错误(该参数是选中项的索引数组,重复索引无效,修正为[1]对应初始仅cos线显示) - 主复选框选中时自动全选所有子复选框并显示全部曲线,取消时清空子复选框并隐藏所有曲线
- 子复选框变化时,会自动同步主复选框的状态:当所有子项都选中时主复选框自动勾选,所有子项都取消时主复选框自动取消,部分选中时主复选框保持当前状态
内容的提问来源于stack exchange,提问作者Nic
相关产品推荐
相关产品推荐

