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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 17:55:20