【Python】Dashのcallbackにアニメーションをつける

# Dash Loading Component

![ezgif.com-crop.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143058/bf61e155-1613-f261-21b3-7f01c20c0f2f.gif)


## 背景

Dashの可視化アプリケーションの描画に、loadingアニメーションをつけたいと思いました.

ちなみに、デフォルトだと以下のように何も変化がなく、inputを検知したことが伝わりにくくなってしまいます.

![default_loading.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143058/cd7dfff3-0378-a4a8-d543-c3e3ae5c6f15.gif)



- 環境
    - macOSX Mojave version 10.14,3
    - Python 3.6.1
    - 実行環境はlocal

- 仕様
    - Dropdownのinputを受けてから2秒待機してcomponentを描画する
    - 2秒間の間にアニメーションを表示する

## 方法

[Loading Component](https://dash.plot.ly/dash-core-components/loading_component)で紹介されている`dash_core_components.Loading()`を使います．

アニメーションのあとで表示させたいcomponentを`dcc.Loading()`の`children`として与えます.

```python:app.py
import dash
import dash_html_components as html
import dash_core_components as dcc
import time

from dash.dependencies import Input, Output

app = dash.Dash(__name__)
common_style = {'position': 'relative', 'width': '100%',
                'font-family': 'Dosis', 'text-align': 'center'}

app.layout = html.Div(
    children=[
        html.H1("Dash app with loading state", style={'margin-bottom': '10%'}),
        dcc.Dropdown(
            id='my-dropdown',
            options=[
                {'label': 'Cactus',
                 'value': 'https://image.flaticon.com/icons/svg/874/874979.svg'},
                {'label': 'Clownfish',
                 'value': 'https://image.flaticon.com/icons/svg/875/875011.svg'},
                {'label': 'Crab',
                    'value': 'https://image.flaticon.com/icons/svg/875/875010.svg'}
            ],
            value='https://image.flaticon.com/icons/svg/874/874979.svg'
        ),
        dcc.Loading(id="loading-1",
                    children=[
                        html.Div(id='output-container',
                                 )
                    ],
                    style={"margin": "10%"},
                    type="default"),
    ],
    style=common_style
)


@app.callback(
    Output('output-container', 'children'),
    [Input('my-dropdown', 'value')])
def input_triggers_spinner(value):
    time.sleep(2)
    return html.Img(src=value, height="30%", width="30%", style={"margin": "10%"})


if __name__ == "__main__":
    app.run_server(debug=False)

```

## 結果

![ezgif.com-crop.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143058/bf61e155-1613-f261-21b3-7f01c20c0f2f.gif)


## その他

spinnerの種類は上のdefaultを含めて5種類用意されているようです.

- graph

![graph.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143058/53e5b6c9-0e91-8e83-a950-4a2a28da0265.gif)

- cube

![cube.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143058/a0db3c3e-5b45-13bf-c0d9-8c945dc36c9e.gif)

- circle

![circle.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143058/84678cc2-febc-7140-9585-9f791ec07fcb.gif)


- dot 

![dot.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143058/7a7b4b0a-1a2d-8671-9207-60acb069499b.gif)


ぜひお試しください！


### 参考

- [Loading Component](https://dash.plot.ly/dash-core-components/loading_component)
- [flaticon](https://www.flaticon.com/)