Bokeh可视化需求:点击Glyph将其移至显示顶层
实现Bokeh节点点击置顶的交互方案
Bokeh没有直接的"一键置顶"工具,但可以通过调整数据源的元素顺序来实现——因为Bokeh会按数据源中元素的先后顺序绘制Glyph,后绘制的元素会覆盖先绘制的,所以把点击的节点移到数据源末尾就能让它显示在顶层。
下面分两种场景给出具体实现:
纯前端场景(无需Bokeh Server)
如果你的可视化是静态HTML输出,用CustomJS编写前端回调即可:
from bokeh.models import ColumnDataSource, TapTool, CustomJS from bokeh.plotting import figure, show # 模拟节点数据 node_data = { 'x': [1, 2, 3, 4, 2.5], 'y': [1, 3, 1, 3, 2], 'id': ['供应商A', '工厂B', '仓库C', '门店D', '中转点E'], 'color': ['#2ecc71', '#3498db', '#e74c3c', '#f1c40f', '#9b59b6'], 'size': [25, 30, 25, 30, 20] } source = ColumnDataSource(data=node_data) # 创建绘图对象 p = figure(title="供应链网络流程图", tools="tap", width=600, height=400) # 绘制节点 nodes = p.circle('x', 'y', size='size', color='color', source=source, alpha=0.8) # 给TapTool绑定回调 tap_tool = p.select_one(TapTool) tap_tool.callback = CustomJS(args=dict(source=source), code=""" const selected_idx = source.selected.indices[0]; if (selected_idx === undefined) return; // 获取所有数据列,将选中节点的元素移到每列的末尾 const data = source.data; for (const key in data) { const moved_item = data[key].splice(selected_idx, 1)[0]; data[key].push(moved_item); } // 触发数据源更新,重绘图形 source.change.emit(); // 清除选中状态 source.selected.indices = []; """) show(p)
Bokeh Server场景(动态Python回调)
如果你的可视化需要后端交互,用Python编写回调逻辑:
from bokeh.models import ColumnDataSource, TapTool from bokeh.plotting import figure, curdoc # 模拟节点数据 node_data = { 'x': [1, 2, 3, 4, 2.5], 'y': [1, 3, 1, 3, 2], 'id': ['供应商A', '工厂B', '仓库C', '门店D', '中转点E'], 'color': ['#2ecc71', '#3498db', '#e74c3c', '#f1c40f', '#9b59b6'], 'size': [25, 30, 25, 30, 20] } source = ColumnDataSource(data=node_data) # 创建绘图对象 p = figure(title="供应链网络流程图", tools="tap", width=600, height=400) p.circle('x', 'y', size='size', color='color', source=source, alpha=0.8) # 定义点击回调函数 def on_node_tap(event): if not event.index: return idx = event.index data = source.data # 将选中节点的元素移到所有列的末尾 for col in data: item = data[col].pop(idx) data[col].append(item) # 更新数据源触发重绘 source.data = data # 绑定点击事件 p.on_event('tap', on_node_tap) curdoc().add_root(p)
关键原理说明
- Bokeh的Glyph渲染遵循**"后绘覆盖先绘"**的规则,数据源中靠后的元素会显示在顶层。
- 点击节点时通过修改数据源的元素顺序,把目标节点移到末尾,即可实现置顶效果。
- 如果你的节点使用了多个
GlyphRenderer,可以通过调整renderer.order属性控制层级,但单renderer的数据源顺序方案更简洁高效。
内容的提问来源于stack exchange,提问作者Lorenzo Gutiérrez
相关产品推荐
相关产品推荐

