Jupyter+Dashで配送計画
以前紹介したJupyterlab+DashはWndowsに対応していなかったようだが,JupyterならWindowsでも動くようだ.
とりあえず配送計画のGUIを作ってみた.
使うのはJupyterlabの方だ.CSSを使うと簡単に綺麗になる.
# Build AppViewer
# external CSS stylesheets
external_stylesheets = [
'https://codepen.io/chriddyp/pen/bWLwgP.css'
]
app = dash.Dash(__name__,
external_stylesheets=external_stylesheets)
# Build AppViewer
from jupyterlab_dash import AppViewer
viewer = AppViewer()
レイアウトはこんな感じで,テーブルなどの中身は長くなるので他で定義しておく.よってこのままでは動かないので注意.
app.layout = html.Div(children=[
html.H3('Vehicle Routing Solver Dashboard'),
header_div,
dcc.Tabs([
dcc.Tab(label="Customer Data", children=[
customer_table_div
]),
dcc.Tab(label="Vehicle Data", children=[
vehicle_table_div
]),
dcc.Tab(label='Gannt Chart', children=[
gannt_div
]),
dcc.Tab(label='Result', children=[
html.Div(className="row",
children=[
html.Div(className="six columns",
children=[map_div]),
html.Div(className="six columns",
children=[map_div2]),
]
),
route_div
])
]) # end of Tabs
])
CSSでsix columns表示のスタイルなどが定義されているので,半分の領域にdivを表示してくれる.全部では12 columnsだ.デザインとしてはDashのタブを利用して,種々の表示をタブで切り替えるようにした.Dashは複数ページにすると色々面倒なことが起こるので,できるだけ1ページにおさめるためだ.
#最適化のボタンを押すと,地図とガントチャートを表示
@app.callback([Output('output-state2', 'children'),Output("map","figure"),Output("gannt","figure") ],
[Input('solve-button','n_clicks')],
[State('input-box', 'value'),State("input-box-tw","value")])
def update_output2(n_clicks, input1, input2):
if n_clicks>=1:
if int(input2)==10000:
obj, model = solve(int(input1))
else:
obj, model = solve(int(input1),int(input2))
fig = make_fig(model)
gannt_fig = gannt(model)
save_route(model)
return f"Obj.={obj}", fig, gannt_fig
else:
pass
# ルートを選択すると、選んだトラックを表示
@app.callback(
Output('dd-output-container', 'children'),
[Input('vehicle-dropdown', 'value')])
def update_output(value):
return 'You have selected vehicle {}'.format(value)
# ルートを選択すると、表を表示(同時に地図のルートを表示)
@app.callback(
[Output('table-route','data'),Output("map2","figure")],
[Input('vehicle-dropdown', 'value')])
def update_output(value):
#route_df = make_route_df(int(value))
route_df = pd.read_csv(f"route{value}.csv")
#route_df = make_route_df(value,model)
fig = make_fig_route(route_df)
return route_df.to_dict('records'), fig
viewer.show(app)
あとは,callback関数に入力,出力,状態のデコレータを付与して,最適化とかルート選択時の表示切り替えを定義するだけだ.もちろん,呼び出す関数の中では色々面倒なことを書いているが,配送最適化ソルバーMETROを使えば簡単に作ることができる.
冒頭の画面は地図とルート選択のdrop downの部分だ.Webアプリの開発は苦行だったが,昔のように楽しく作れるようになると良い.ただし,デバッグ環境が最悪なので,まだまだだ.よっぽど用心深いプログラマでないと,こう短時間には開発できないだろう.
この記事が気に入ったらサポートをしてみませんか?