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

如何创建可复用的Jinja Bokeh图表组件 实现Flask跨路由调用

实现Bokeh图表逻辑复用的方案

你可以通过以下三种常用方式实现,优先级从高到低推荐:

方案1:抽离公共生成函数(最优)

把和路由无关的图表生成逻辑单独封装为工具函数,所有路由都可以直接调用,还支持自定义参数适配不同场景。

步骤1:封装公共函数

# 可以放在单独的utils/bokeh_utils.py,也可以直接在当前文件定义
def generate_bokeh_line_chart(
    plot_width=800, 
    plot_height=600, 
    x_label='x', 
    y_label='y',
    x_data=[1,2,3,10],
    y_data=[1.7,2.2,4.6,3.9],
    legend_label="随机数值"
):
    fig = figure(
        plot_width=plot_width,
        plot_height=plot_height,
        x_axis_label=x_label,
        y_axis_label=y_label
    )
    fig.line(
        legend_label=legend_label,
        x=x_data,
        y=y_data,
    )
    hover = HoverTool(mode="vline")
    hover.tooltips=[
        ('数值', '@x'),
        ('结果', '@y')
    ]
    fig.tools.append(hover)

    js_resources = INLINE.render_js()
    css_resources = INLINE.render_css()
    script, div = components(fig)
    
    return {
        "plot_script": script,
        "plot_div": div,
        "js_resources": js_resources,
        "css_resources": css_resources
    }

步骤2:原有路由复用函数

@bokeh.route('/bokeh', methods=['GET', 'POST'])
def bokeh_main():
    chart_data = generate_bokeh_line_chart()
    return render_template('index.html', **chart_data)

步骤3:其他路由复用

比如你的销售报表路由:

@report.route('/sales')
def sales_report():
    # 可以传自定义参数适配销售数据场景
    sales_chart = generate_bokeh_line_chart(
        x_label='日期',
        y_label='销售额',
        x_data=[1,2,3,4,5],
        y_data=[1200, 3100, 2800, 4500, 3900],
        legend_label="每日销售额"
    )
    # 把图表参数传到销售报表的模板里即可
    return render_template('sales.html', sales_chart=sales_chart)

方案2:Jinja模板复用

如果是多个模板都要渲染相同结构的Bokeh图表,可以把渲染逻辑抽为公共子模板或宏:

  1. 新建templates/_bokeh_chart.html子模板:
<!-- 传入参数:chart_data 就是generate_bokeh_line_chart返回的字典 -->
{{ chart_data.css_resources|safe }}
{{ chart_data.js_resources|safe }}
{{ chart_data.plot_div|safe }}
{{ chart_data.plot_script|safe }}
  1. 任意需要显示图表的模板直接引入即可:
<!-- 比如sales.html里要放销售图表的位置加这句 -->
{% include '_bokeh_chart.html' %}

方案3:直接复用现有路由返回(不推荐,适合临时场景)

如果你不想修改现有Bokeh路由的逻辑,可以用前端异步加载的方式嵌入:
在需要显示图表的页面加如下代码:

<div id="bokeh-chart-container"></div>
<script>
fetch('/bokeh')
.then(res => res.text())
.then(html => {
    document.getElementById('bokeh-chart-container').innerHTML = html
})
</script>

注意:该方式如果/bokeh返回的是完整页面,会有样式冲突,仅适合返回纯图表片段的路由使用


内容的提问来源于stack exchange,提问作者Fredi Tansari

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 18:03:00