如何在具有多个唯一图形的布局上实现 Dash/Plotly 清单持久性?

Posted

技术标签:

【中文标题】如何在具有多个唯一图形的布局上实现 Dash/Plotly 清单持久性?【英文标题】:How do I implement Dash/Plotly checklist persistence on a layout with multiple unique graphs? 【发布时间】:2021-11-25 18:45:10 【问题描述】:

我的仪表板有一个 2 x 2 的图表布局,每个图表上覆盖一个清单。

每个图表都需要一个唯一的 ID,以便通过回调进行实时更新。 这些 ID 在循环中生成(例如,graph-BMW、graph-MB 等)。 同样,每个清单都有一个通过相同循环生成的唯一 ID(例如,清单-BMW、清单-MB 等)。 这些 ID 被传递到回调的 inputoutput

计算图表数据并返回清单值和图形。

由于清单需要包含在与图表相同的 DIV 中,因此它们是嵌套的,然后在布局中解包。

所有这些都完美运行,除了一个例外:persistence 不起作用。 如果单击清单,刷新页面时我无法保留当前(新)状态。 清单值总是返回到未选中状态,因为它似乎被重置了。

我该如何解决这个问题?

应用程序的精简版:

cars = ['BMW', 'MB', 'AUDI', 'FIAT']

app3 = dash.Dash(__name__)

for car in cars:
    graph = 'graph-' + car
    checklist = 'checklist-' + car

    @app3.callback(Output(checklist, 'value'),
                   Output(graph, 'figure'),
                   Input(checklist, 'value'),
                   Input('interval-component', 'n_intervals'))
    def update_charts(checklist, n_interval, c=car):
        data = get_car_data(c)
        df = calcs_on_car_data(data)

        fig = go.Figure(go.Scatter(x=df.index, y=df['A'].values))
        return checklist, fig

list_graphs = []
for car in cars:
    list_graphs.append([html.Div(className='box',
                                 children=[html.Div([
                                     dcc.Checklist(id='checklist-' + str(car),
                                                   options=['label': '', 'value': 'on'], value=[],
                                                   persistence=True),
                                     dcc.Graph(id='graph-' + str(car))])
                                 ])
                        ])

app3.layout = html.Div([
    *[j for i in list_graphs for j in i],  # unpacking a nested list
    dcc.Interval(id='interval-component', interval=300000, n_intervals=0)
])

if __name__ == '__main__':
    app3.run_server(debug=True)

【问题讨论】:

查看本期/PR github.com/plotly/dash/pull/903 感谢您的指点。您的看法是:在这一点上这是一个失败的原因吗? 我记得曾经遇到过同样的问题并用一些非常丑陋/hacky的解决方案解决了它。但那是大约 2 年前的事了。 您的代码似乎没有 get_car_data(c) 和 calcs_on_car_data(data) 函数。请提供示例数据,以便我可以提供帮助 为什么def update_charts 在(第一个)“for”循环中?这在Dash 中正常吗? 【参考方案1】:

您可以按照以下步骤操作

利用会话变量来存储清单值 一旦页面刷新完成(所有页面元素都重新加载),触发访问会话变量的调用并将值分配给相关清单。

【讨论】:

【参考方案2】:

循环回调似乎破坏了持久性功能。通过删除清单输出将其删除,持久性按预期工作。这是MWE,

import plotly.express as px
from dash import dash, dcc, html, Output, Input


def make_car_card(car: str):
    graph_id = f'graph-car'
    checklist_id = f'checklist-car'
    card = html.Div(className='box',
                    children=html.Div([
                        dcc.Checklist(id=checklist_id,
                                      options=['label': '', 'value': 'on'], value=[],
                                      persistence=True),
                        dcc.Graph(id=graph_id)])
                    )

    @app.callback(Output(graph_id, 'figure'), Input('interval-component', 'n_intervals'), Input(checklist_id, 'value'))
    def update_charts(_, value, this_car=car):
        if 'on' not in value:
            return px.scatter()
        return px.scatter(px.data.iris(), x="sepal_width", y="sepal_length", title=this_car)

    return card


# Create small example app.
app = dash.Dash(__name__)
app.layout = html.Div(
    [make_car_card(car) for car in ['BMW', 'MB', 'AUDI', 'FIAT']] +
    [dcc.Interval(id='interval-component', interval=300000, n_intervals=0)]
)

if __name__ == '__main__':
    app.run_server(debug=True)

【讨论】:

以上是关于如何在具有多个唯一图形的布局上实现 Dash/Plotly 清单持久性?的主要内容,如果未能解决你的问题,请参考以下文章

使用 d3 自动布局的图形(具有多个父节点的树)

如何在屏幕上实现具有许多文本字段的 NSScrollView?

如何在不相关的类型上实现动态多态(运行时调用调度)?

如何使用具有不同分片数量的索引在 ElasticSearch 上实现负载的均匀分布?

如何在多个域的 vue 应用上实现谷歌分析?

如何在多个 Amazon 实例上实现自定义维护页面?