使用 plot.ly Dash 等待结果时显示加载符号

Display loading symbol while waiting for a result with plot.ly Dash

在我基于 Dash 的应用程序中,一个按钮会触发一个长 运行 计算。在结果尚未出现时显示加载动画并使按钮处于非活动状态以便在计算完成之前不会再次单击它不是很好吗?

我正在使用 Bulma 进行 UI 设计,并希望为此目的使用 button is-loading CSS class。

我的第一个想法是有两个回调:一个由按钮点击触发以将按钮设置为 is-loading,另一个由输出更改触发以将其设置回正常状态。

@app.callback(
    Output('enter-button', 'className'),
    [
        Input('graph', 'figure')
    ],
)
def set_trend_enter_button_loading(figure_changed):
    return "button is-large is-primary is-outlined"


@app.callback(
    Output('enter-button', 'className'),
    [
        Input('enter-button', 'n_clicks')
    ],
)
def set_trend_enter_button_loading(n_clicks):
    return "button is-large is-primary is-outlined is-loading"

显然不是这样的:

dash.exceptions.CantHaveMultipleOutputs:
You have already assigned a callback to the output
with ID "enter-button" and property "className". An output can only have
a single callback function. Try combining your inputs and
callback functions together into one function.

有什么想法可以实现吗?

上周我遇到了同样的问题,甚至尝试使用Javascript来实现禁用按钮的行为,但最终放弃了。我在 plotly forums 上看到过这个讨论,显然需要这种功能,但我认为在当前版本中无法轻松实现。

虽然 可能的,但 Dash 开发人员将其作为临时解决方案提到的一件事是添加全局加载屏幕。简而言之,您需要将以下 CSS 添加到样式表中:

@keyframes fadein {
    0% {
        opacity: 0;
    }
    100% {
        opacity: 0.5;
    }
}

._dash-loading-callback {
  font-family: sans-serif;
  padding-top: 50px;
  color: rgb(90, 90, 90);

  /* The banner */
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  text-align: center;
  cursor: progress;

  opacity: 0;
  background-color: rgb(250, 250, 250);
  /* Delay animation by 1s to prevent flashing 
     and smoothly transition the animation over 0.5s 
   */
  -moz-animation: fadein 0.5s ease-in 1s forwards; /* Firefox */
  -webkit-animation: fadein 0.5s ease-in 1s forwards; /* Safari and Chrome */
  -o-animation: fadein 0.5s ease-in 1s forwards; /* Opera */
    animation: fadein 0.5s ease-in 1s forwards;
}

几点说明:

  • _dash-loading-callback 选择器选择一个 div,每次回调时添加到 body 元素的末尾,完成后删除。
  • 您可以通过为 _dash-loading-callback 定义背景 GIF 添加加载动画。
  • 上面CSS中定义的动画是为了防止加载屏幕在短回调时闪烁。它设置为在一秒钟后淡入,因此它只会在长时间加载操作时出现。您当然可以使用这些设置。

由于 dash-renderer==0.9.0,当您的应用程序等待回调时,div 标记被添加到您的布局中。您可以按照 Chris 的建议在其中放入不同的 css:https://community.plot.ly/t/mega-dash-loading-states/5687

另外,一项符合您需求的新功能即将推出。目前处于 alpha 版本:https://community.plot.ly/t/loading-states-api-and-a-loading-component-prerelease/16406

带有自定义 GIF 的加载程序

只需在您的应用程序目录的根目录中创建一个名为 assets 的文件夹,并将您的 CSS 和 JavaScript 文件包含在该文件夹中。 Dash 将自动提供此文件夹中包含的所有文件。默认情况下,请求资产的 url 将是 /assets 但您可以使用 assets_url_path 参数对 dash.Dash.

进行自定义

Create a customer css file under style folder

- app.py
- assets/
    |-- loader.css

custom css

        ._dash-loading-callback {
        position: fixed;
        z-index: 100;
        }

        ._dash-loading-callback::after {
        content: 'Loading';
        font-family: sans-serif;
        padding-top: 50px;
        color: #000;

        -webkit-animation: fadein 0.5s ease-in 1s forwards; /* Safari, Chrome and Opera > 12.1 */
           -moz-animation: fadein 0.5s ease-in 1s forwards; /* Firefox < 16 */
            -ms-animation: fadein 0.5s ease-in 1s forwards; /* Internet Explorer */
             -o-animation: fadein 0.5s ease-in 1s forwards; /* Opera < 12.1 */
                animation: fadein 0.5s ease-in 1s forwards;  
        /* prevent flickering on every callback */
        -webkit-animation-delay: 0.5s;
        animation-delay: 0.5s;

        /* The banner */
        opacity: 0;
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background-color: rgba(255, 255, 255, 0.5);
        text-align: center;
        cursor: progress;
        z-index: 100000;

        background-image: url(https://www.w3schools.com/html/programming.gif);
        background-position: center center;
        background-repeat: no-repeat;
        }

        @keyframes fadein {
          from { opacity: 0; }
          to   { opacity: 1; }
        }

        /* Firefox < 16 */
        @-moz-keyframes fadein {
          from { opacity: 0; }
          to   { opacity: 1; }
        }

        /* Safari, Chrome and Opera > 12.1 */
        @-webkit-keyframes fadein {
          from { opacity: 0; }
          to   { opacity: 1; }
        }

        /* Internet Explorer */
        @-ms-keyframes fadein {
          from { opacity: 0; }
          to   { opacity: 1; }
        }

        /* Opera < 12.1 */
        @-o-keyframes fadein {
          from { opacity: 0; }
          to   { opacity: 1; }
        }