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

Bokeh中如何实现点击按钮弹出可拖动的含DataTable的弹窗

Bokeh实现带可拖动DataTable弹窗的解决方案

核心实现完全基于Bokeh原生组件+前端原生API,不需要引入任何外部依赖,适配所有Web端运行环境。

实现步骤

1. 导入所需依赖

from bokeh.models import Button, DataTable, ColumnDataSource, CustomJS, Div
from bokeh.layouts import column
from bokeh.io import curdoc
import pandas as pd

2. 初始化DataTable与弹窗容器

  • 首先构造需要展示的表格数据与DataTable实例:
# 构造示例数据,可替换为你的业务数据
df = pd.DataFrame({
    "序号": [1,2,3,4,5],
    "内容": ["样本1","样本2","样本3","样本4","样本5"],
    "数值": [10.5, 20.3, 15.8, 30.2, 25.7]
})
source = ColumnDataSource(df)
data_table = DataTable(
    source=source,
    width=450,
    height=300,
    editable=False
)
# 隐藏初始状态的表格,仅在弹窗中展示
data_table.visible = False
  • 定义可拖动弹窗的基础容器,默认隐藏:
modal = Div(
    text="""
    <div id="drag-modal" style="position: fixed; top: 100px; left: 100px; z-index: 1000; border: 1px solid #e0e0e0; background: #ffffff; box-shadow: 0 2px 12px rgba(0,0,0,0.15); display: none;">
        <!-- 拖动触发的标题栏 -->
        <div id="modal-header" style="padding: 8px 12px; background: #f5f5f5; cursor: move; user-select: none; border-bottom: 1px solid #e0e0e0;">
            数据表格
        </div>
        <!-- 表格渲染容器 -->
        <div id="modal-content" style="padding: 12px;">
        </div>
    </div>
    """,
    width=0,
    height=0
)

3. 绑定按钮点击回调与拖动逻辑

open_btn = Button(label="打开数据表格", button_type="primary")

open_btn.js_on_click(CustomJS(args=dict(modal=modal, table=data_table), code="""
// 显示弹窗
const modalEl = document.getElementById('drag-modal');
modalEl.style.display = 'block';
// 渲染DataTable到弹窗内容区
const contentEl = document.getElementById('modal-content');
contentEl.innerHTML = '';
Bokeh.embed.add_document_standalone(table, contentEl);

// 绑定窗口拖动逻辑
const header = document.getElementById('modal-header');
let isDragging = false;
let offsetX, offsetY;

header.addEventListener('mousedown', (e) => {
    isDragging = true;
    offsetX = e.clientX - modalEl.offsetLeft;
    offsetY = e.clientY - modalEl.offsetTop;
});

document.addEventListener('mousemove', (e) => {
    if (!isDragging) return;
    modalEl.style.left = (e.clientX - offsetX) + 'px';
    modalEl.style.top = (e.clientY - offsetY) + 'px';
});

document.addEventListener('mouseup', () => {
    isDragging = false;
});
"""))

4. 组装布局启动应用

# 所有组件必须加入root才会被Bokeh识别
curdoc().add_root(column(open_btn, modal, data_table))

补充说明

  • 如果需要添加关闭弹窗功能,只需在弹窗标题栏新增关闭按钮,绑定JS事件将modalEl.style.display设为none即可
  • DataTable原生的排序、选中、筛选等交互功能不受弹窗容器影响,可正常使用
    注意:必须将DataTable实例加入到当前文档的root布局中,否则Bokeh无法识别组件,会导致弹窗内渲染失败

内容的提问来源于stack exchange,提问作者bhawna1 Bhasin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 13:39:01