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

Plotly网格溢出Trace处理:Dash应用Indicator滚动显示问题

Dash应用Indicator网格滚动显示问题解决方案

我开发了一个Dash应用,用以下代码构建了一列Indicator网格:

indicators_ptf = go.Figure()
indicators_ptf.layout.template = CHART_THEME
indicators_ptf.add_trace(go.Indicator(
    mode = "number+delta",
    value = totalprolos,
    number = {'prefix': " $"},
    title = {"text": "<br><span style='font-size:0.7em;color:gray'>Profit/Loss</span>"},
    delta = {'position': "bottom", 'reference': totalprolos - portfolio_pct/100, 'relative': False, 'valueformat': ".2%"},
    domain = {'row': 0, 'column': 0}))

indicators_ptf.add_trace(go.Indicator(
    mode = "number+delta",
    value = availableCash,
    number = {'prefix': "$"},
    title = {"text": "<br><span style='font-size:0.7em;color:gray'>Available Cash</span>"},
    delta = {'position': "bottom", 'reference': 10000, 'relative': False},
    domain = {'row': 1, 'column': 0}))

indicators_ptf.add_trace(go.Indicator(
    mode = "number+delta",
    value = grandTotal,
    number = {'prefix': "$"},
    title = {"text": "<span style='font-size:0.7em;color:gray'>Total Value</span>"},
    delta = {'position': "bottom", 'reference': 10000, 'relative': False},
    domain = {'row': 2, 'column': 0}))

row_n=3
for stock in stocks:
    indicators_ptf.add_trace(go.Indicator(
        mode = "number+delta",
        value = stock['prolos'],
        number = {'prefix': "$"},
        title = {"text": stock['symbol']},
        delta = {'position': "bottom", 'reference': stock['prolos'] - stock['perc_change']/100, 'relative': False, 'valueformat': ".2%"},
        domain = {'row': row_n, 'column': 0}))
    row_n += 1


indicators_ptf.update_layout(
    grid = {'rows': 5, 'columns': 1, 'pattern': "independent"},
    margin=dict(l=50, r=50, t=30, b=30)
)

问题描述

当投资组合中的股票数量超过2只时,新增的股票Indicator会覆盖其他行的内容。我希望META及后续股票Indicator能被隐藏在下方,支持滚动查看。尝试过fig.update_traces(colorbar_ticklabeloverflow=...)和fig.update_yaxes(ticklabeloverflow=...)但无效果。我的Dash布局代码如下:

dash_app.layout = dbc.Container(
    [
        dbc.Row(dbc.Col(html.H2('PORTFOLIO OVERVIEW', className='text-center text-primary, mb-3'))),  # 标题行

        dbc.Row([  # 第二行开始
            dbc.Col([  # 第二行第一列
            html.H5('Total Portfolio Value ($USD)', className='text-center'),
            dcc.Graph(id='chrt-portfolio-main',
                    figure=chart_ptfvalue,
                    style={'height':550}),
            html.Hr(),
            ], width={'size': 8, 'offset': 0, 'order': 1}),  # 第二行第一列宽度
            dbc.Col([  # 第二行第二列
            html.H5('Portfolio', className='text-center'),
            dcc.Graph(id='indicators-ptf',
                    figure=indicators_ptf,
                    style={'height':550, 'overflowY': 'scroll', 'maxHeight': '550px'}),
            html.Hr()
            ], width={'size': 2, 'offset': 0, 'order': 2}),  # 第二行第二列宽度
            dbc.Col([  # 第二行第三列
            html.H5('S&P500', className='text-center'),
            dcc.Graph(id='indicators-sp',
                    figure=indicators_sp500,
                    style={'height':550}),
            html.Hr()
            ], width={'size': 2, 'offset': 0, 'order': 3}),  # 第二行第三列宽度
        ]),  # 第二行结束

        dbc.Row([  # 第三行开始
            dbc.Col([  # 第三行第一列
                html.H5('Monthly Return (%)', className='text-center'),
                dcc.Graph(id='chrt-portfolio-secondary',
                    figure=fig_growth2,
                    style={'height':380}),
            ], width={'size': 8, 'offset': 0, 'order': 1}),  # 第三行第一列宽度
            dbc.Col([  # 第三行第二列
                html.H5('Top 15 Holdings', className='text-center'),
                dcc.Graph(id='pie-top15',
                    figure = donut_top,
                    style={'height':380}),
            ], width={'size': 4, 'offset': 0, 'order': 2}),  # 第三行第二列宽度
        ])  # 第三行结束

    ], fluid=True)

问题原因及修复方案

  1. 核心问题:

    • 固定设置grid={'rows':5},当股票数量超过2只时,总Indicator数量超过5,Plotly会强制压缩所有元素到5行内,导致重叠。
    • dcc.Graph是Canvas渲染组件,直接给它加overflowY样式无法作用于内部图表内容。
  2. 具体修复步骤:

    • 动态设置网格行数:根据实际Indicator总数(固定3个+股票数量)设置grid.rows,避免固定行数限制。
    • 用HTML容器包裹图表实现滚动:将dcc.Graph放入html.Div容器,给容器设置滚动样式,让图表内容超出容器高度时显示滚动条。

修改后的Indicator构建代码

indicators_ptf = go.Figure()
indicators_ptf.layout.template = CHART_THEME
indicators_ptf.add_trace(go.Indicator(
    mode = "number+delta",
    value = totalprolos,
    number = {'prefix': " $"},
    title = {"text": "<br><span style='font-size:0.7em;color:gray'>Profit/Loss</span>"},
    delta = {'position': "bottom", 'reference': totalprolos - portfolio_pct/100, 'relative': False, 'valueformat': ".2%"},
    domain = {'row': 0, 'column': 0}))

indicators_ptf.add_trace(go.Indicator(
    mode = "number+delta",
    value = availableCash,
    number = {'prefix': "$"},
    title = {"text": "<br><span style='font-size:0.7em;color:gray'>Available Cash</span>"},
    delta = {'position': "bottom", 'reference': 10000, 'relative': False},
    domain = {'row': 1, 'column': 0}))

indicators_ptf.add_trace(go.Indicator(
    mode = "number+delta",
    value = grandTotal,
    number = {'prefix': "$"},
    title = {"text": "<span style='font-size:0.7em;color:gray'>Total Value</span>"},
    delta = {'position': "bottom", 'reference': 10000, 'relative': False},
    domain = {'row': 2, 'column': 0}))

row_n=3
for stock in stocks:
    indicators_ptf.add_trace(go.Indicator(
        mode = "number+delta",
        value = stock['prolos'],
        number = {'prefix': "$"},
        title = {"text": stock['symbol']},
        delta = {'position': "bottom", 'reference': stock['prolos'] - stock['perc_change']/100, 'relative': False, 'valueformat': ".2%"},
        domain = {'row': row_n, 'column': 0}))
    row_n += 1

# 动态计算总行数:固定3个指标 + 股票数量
total_rows = 3 + len(stocks)
indicators_ptf.update_layout(
    grid = {'rows': total_rows, 'columns': 1, 'pattern': "independent"},
    margin=dict(l=50, r=50, t=30, b=30)
)

修改后的布局代码

dash_app.layout = dbc.Container(
    [
        dbc.Row(dbc.Col(html.H2('PORTFOLIO OVERVIEW', className='text-center text-primary, mb-3'))),  # 标题行

        dbc.Row([  # 第二行开始
            dbc.Col([  # 第二行第一列
            html.H5('Total Portfolio Value ($USD)', className='text-center'),
            dcc.Graph(id='chrt-portfolio-main',
                    figure=chart_ptfvalue,
                    style={'height':550}),
            html.Hr(),
            ], width={'size': 8, 'offset': 0, 'order': 1}),  # 第二行第一列宽度
            dbc.Col([  # 第二行第二列
            html.H5('Portfolio', className='text-center'),
            # 用Div包裹Graph,设置滚动容器
            html.Div(
                dcc.Graph(id='indicators-ptf',
                        figure=indicators_ptf,
                        style={'height': '100%'}),
                style={'height': 550, 'overflowY': 'auto'}
            ),
            html.Hr()
            ], width={'size': 2, 'offset': 0, 'order': 2}),  # 第二行第二列宽度
            dbc.Col([  # 第二行第三列
            html.H5('S&P500', className='text-center'),
            dcc.Graph(id='indicators-sp',
                    figure=indicators_sp500,
                    style={'height':550}),
            html.Hr()
            ], width={'size': 2, 'offset': 0, 'order': 3}),  # 第二行第三列宽度
        ]),  # 第二行结束

        dbc.Row([  # 第三行开始
            dbc.Col([  # 第三行第一列
                html.H5('Monthly Return (%)', className='text-center'),
                dcc.Graph(id='chrt-portfolio-secondary',
                    figure=fig_growth2,
                    style={'height':380}),
            ], width={'size': 8, 'offset': 0, 'order': 1}),  # 第三行第一列宽度
            dbc.Col([  # 第三行第二列
                html.H5('Top 15 Holdings', className='text-center'),
                dcc.Graph(id='pie-top15',
                    figure = donut_top,
                    style={'height':380}),
            ], width={'size': 4, 'offset': 0, 'order': 2}),  # 第三行第二列宽度
        ])  # 第三行结束

    ], fluid=True)
  1. 额外说明:
    • 动态设置grid.rows确保每个Indicator都有独立的行空间,不会出现重叠。
    • 容器的overflowY: auto会在内容高度超过容器时自动显示垂直滚动条,实现滚动查看所有Indicator。
    • 将Graph的高度设为100%,让它完全填满容器,滚动体验更流畅。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 21:15:45