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

能否使用普通HTML及Vue/React组件向Bokeh绘图传递数据实现联动?

Bokeh服务端与自定义前端组件协同的可行方案

完全可以实现你要的效果,不需要局限于Bokeh自带组件,也不用额外发HTTP请求,核心思路是复用Bokeh服务端内置的WebSocket通信通道,通过JS API直接触发服务端回调,以下是具体实现方案:

方案1:桥接数据源同步方案

这是最稳定兼容性最好的方案,核心是用一个无UI的ColumnDataSource作为前后端参数传递的中间载体:

Python端配置

在你的Bokeh服务端应用中预先定义桥接数据源和对应的服务端回调:

from bokeh.models import ColumnDataSource
from bokeh.server.server import Server
from bokeh.plotting import figure

def bokeh_app(doc):
    # 定义桥接数据源,添加唯一name方便前端定位
    bridge_ds = ColumnDataSource(
        data={"selected_val": [""], "extra_payload": [{}]},
        name="vue_bokeh_bridge"
    )
    # 你的绘图逻辑示例
    p = figure(title="动态更新图表", width=600, height=400)
    line_render = p.line(x=[1,2,3,4], y=[1,2,3,4])

    # 服务端更新回调,数据源变化时自动触发
    def update_chart(attr, old, new):
        # 直接获取前端传递过来的参数
        current_val = bridge_ds.data["selected_val"][0]
        extra_params = bridge_ds.data["extra_payload"][0]
        # 这里写你的图表更新逻辑,比如修改渲染器的数据源
        new_y = [i*int(current_val) for i in [1,2,3,4]]
        line_render.data_source.data["y"] = new_y

    # 监听桥接数据源的变化
    bridge_ds.on_change("data", update_chart)
    # 把图表和桥接数据源都加入文档
    doc.add_root(p)
    doc.add_root(bridge_ds)

# 启动服务的逻辑你可以保留原有配置
server = Server({'/': bokeh_app}, port=5006)
server.start()

Vue/React端配置

在你的前端组件事件中,直接调用Bokeh暴露在全局的JS API修改桥接数据源即可,Bokeh会自动把变更同步到服务端触发回调:

// Vue组件选择事件示例
const handleSelect = async (selectedValue) => {
  // 获取当前页面加载的Bokeh文档实例
  const bokehDoc = window.Bokeh.documents[0]
  // 定位到我们预先定义的桥接数据源
  const bridgeDS = bokehDoc.get_model_by_name("vue_bokeh_bridge")
  // 修改数据源,自动触发服务端回调
  bridgeDS.data = {
    selected_val: [selectedValue],
    extra_payload: [{ user_id: "123", filter: "xxx" }]
  }
}

方案2:自定义事件触发方案

如果你不想额外维护桥接数据源,可以用Bokeh的自定义事件机制实现更轻量的调用:

Python端配置

from bokeh.events import Event
from bokeh.server.server import Server
from bokeh.plotting import figure

# 定义自定义事件
class VueTriggerEvent(Event):
    event_name = "vue_trigger"
    def __init__(self, selected_val, extra_payload):
        self.selected_val = selected_val
        self.extra_payload = extra_payload

def bokeh_app(doc):
    p = figure(title="动态更新图表", width=600, height=400)
    line_render = p.line(x=[1,2,3,4], y=[1,2,3,4])

    # 自定义事件处理回调
    def handle_vue_event(event):
        current_val = event.selected_val
        extra_params = event.extra_payload
        new_y = [i*int(current_val) for i in [1,2,3,4]]
        line_render.data_source.data["y"] = new_y

    # 注册事件监听
    doc.on_event(VueTriggerEvent, handle_vue_event)
    doc.add_root(p)

前端调用

const handleSelect = async (selectedValue) => {
  const bokehDoc = window.Bokeh.documents[0]
  // 直接触发自定义事件,参数会自动同步到Python端
  bokehDoc.send_event("vue_trigger", {
    selected_val: selectedValue,
    extra_payload: { user_id: "123", filter: "xxx" }
  })
}

注意事项

  • 以上方案都依赖Bokeh服务端的运行环境,不能用于静态导出的Bokeh图表
  • 如果页面嵌入了多个Bokeh应用,可通过window.Bokeh.documents数组的下标区分不同应用的文档实例
  • 所有传递的参数需要满足JSON可序列化要求

内容的提问来源于stack exchange,提问作者Eduardo Rios

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.09 22:15:00