如何在HTML页面中动态渲染基于SQL数据的Bokeh图表?
如何将Bokeh图表整合到网页指定位置(从SQL取数动态渲染)
我之前也遇到过类似的问题——用Jupyter导出的独立Bokeh HTML总是弹窗,没法嵌入现有网页。核心解决思路是不要生成完整独立页面,而是导出Bokeh的可嵌入组件片段,把这些片段放到网页的指定DOM位置即可。下面是具体的分步方案:
1. 后端:从SQL取数并生成Bokeh组件片段
用Python(毕竟你用Jupyter,应该是Python栈)连接SQL取数,然后用Bokeh的components()函数把图表拆成JS脚本和HTML容器两部分——这俩就是你要嵌入网页的核心内容。
举个完整的示例代码:
from bokeh.plotting import figure from bokeh.embed import components import pandas as pd from sqlalchemy import create_engine # 1. 连接SQL数据库并查询数据 # 替换成你的数据库连接信息 engine = create_engine('postgresql://user:password@host:port/dbname') query = "SELECT date, sales FROM monthly_sales WHERE region = 'North'" df = pd.read_sql(query, engine) # 2. 创建Bokeh图表 p = figure(x_axis_type='datetime', title='北区月度销售额趋势', width=800, height=400) p.line(df['date'], df['sales'], line_width=2, color='#2ecc71') p.xaxis.axis_label = '日期' p.yaxis.axis_label = '销售额' # 3. 生成可嵌入的组件:script是渲染逻辑,div是图表挂载容器 script, div = components(p)
如果要生成多个图表(按顺序展示),可以循环处理多组SQL查询:
# 定义多组查询和图表配置 chart_tasks = [ {"query": "SELECT date, sales FROM monthly_sales WHERE region = 'North'", "title": "北区销售额"}, {"query": "SELECT date, sales FROM monthly_sales WHERE region = 'South'", "title": "南区销售额"}, {"query": "SELECT date, sales FROM monthly_sales WHERE region = 'East'", "title": "东区销售额"}, ] scripts = [] divs = [] for task in chart_tasks: df = pd.read_sql(task["query"], engine) p = figure(x_axis_type='datetime', title=task["title"], width=800, height=400) p.line(df['date'], df['sales'], line_width=2) script, div = components(p) scripts.append(script) divs.append(div)
2. 前端:将组件嵌入网页指定位置
不管你用静态HTML还是后端模板(Flask/Django/Jinja2),核心是:
- 先引入Bokeh的依赖资源(CSS+JS)
- 把所有图表的
div放到网页的指定区域(按顺序排列) - 把所有图表的
script放到页面底部(或<head>末尾)
用Jinja2模板的示例(Flask/Django通用)
<!DOCTYPE html> <html> <head> <title>区域销售额图表</title> <!-- 引入Bokeh依赖,注意版本要和你后端安装的Bokeh一致! --> <link rel="stylesheet" href="https://cdn.bokeh.org/bokeh/release/bokeh-3.3.4.min.css" type="text/css" /> <script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-3.3.4.min.js"></script> <!-- 如果需要图表交互工具(缩放、平移),再加这两个 --> <script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.3.4.min.js"></script> <script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.3.4.min.js"></script> </head> <body> <h1>各区域月度销售额趋势</h1> <!-- 图表展示区域:按顺序渲染所有div --> <div class="chart-container"> {% for div in divs %} {{ div|safe }} <hr style="margin: 20px 0;"> <!-- 可选:用分隔线区分图表 --> {% endfor %} </div> <!-- 图表渲染脚本:放在页面底部确保DOM已加载 --> {% for script in scripts %} {{ script|safe }} {% endfor %} </body> </html>
纯静态HTML的做法
如果没有后端框架,直接在Python脚本里打印出所有div和script,然后手动复制粘贴到静态HTML的对应位置即可。比如运行Python脚本后,把输出的div依次粘贴到<div class="chart-container">里,把script粘贴到页面底部。
关键注意事项
- 版本一致性:CDN的Bokeh版本必须和你本地安装的Bokeh版本完全一致,否则会出现渲染错误。
- 交互功能:如果你的图表需要缩放、悬停提示等交互,一定要引入
bokeh-widgets和bokeh-tables的CDN。 - 动态刷新:如果需要定时更新图表数据,可以用AJAX调用后端接口重新生成组件,然后替换页面上的div和script(或者用Bokeh Server做更复杂的实时交互)。
内容的提问来源于stack exchange,提问作者S. Pynewb22
相关产品推荐
相关产品推荐

