Hello!
Many thanks for the suggestion, I did try to use it but unfortunately it did not work.
I’m including now an example based on the multi page instructions in Dash.
Here is my index.py file:
from dash.dependencies import Input, Output
import dash_core_components as dcc
import dash_html_components as html
import dash_table_experiments as dt
from app import app
from apps import app1, app2, app3
app.layout = html.Div([
dcc.Location(id='url', refresh=False),
dcc.Link('Navigate to App1 barpplot', href='/apps/app1'),
html.Br(),
dcc.Link('Navigate to App2 data tables', href='/apps/app2'),
html.Br(),
dcc.Link('Navigate to App3 scatter plot', href='/apps/app3'),
# Included sniper as per suggestion
html.Div(dt.DataTable(rows=[{}]), style={'display': 'none'}),
html.Div(id='page-content')
])
@app.callback(Output('page-content', 'children'),
[Input('url', 'pathname')])
def display_page(pathname):
if pathname == '/apps/app1':
return app1.layout
elif pathname == '/apps/app2':
return app2.layout
elif pathname == '/apps/app3':
return app3.layout
else:
return '404'
if __name__ == '__main__':
app.run_server(debug=True)
The index serves a very basic App where the links are displayed (from here I want to give access to three apps). When I click on the first and third link they both work, but not the second.
See bellow the code for app2.py (modified code from your example, usage.py to fetch a table from a postgre DB), that code works as a separate app but not in the multipage ensemble.
Important considerations for app2.py
As I’m pinging the data base to get info from different tables, I needed to add two extra appcalls, one to update the name of the columns depending on the table and dropping some unwanted columns, and another one to update the content of the table (rows), depending on what was selected and called using the drop menu (in this case either table 1 or table 2).
I suspect those two calls might be the culprits as your example (usage.py) worked well when I tested it on the multipage ensemble. Any advise/suggestion or work-around?
Thanks!
Leo
import dash
from dash.dependencies import Input, Output, State
import dash_core_components as dcc
import dash_html_components as html
import dash_table_experiments as dt
import json
import pandas as pd
import numpy as np
import plotly
from sqlalchemy import create_engine
from app import app
app.scripts.config.serve_locally = True
# app.css.config.serve_locally = True
connstr = 'database_link'
engine = create_engine(connstr)
breakdowns = [
{'label': 'Option1', 'value': '1'},
{'label': 'Option2', 'value': '2'},
]
layout = html.Div([
html.H4('Gapminder DataTable'),
html.Div(
[
html.Div(
[
html.Label('Select the study to explore'),
dcc.Dropdown(
id='file_to_load',
options=breakdowns,
value='1'),
])
]),
dt.DataTable(
rows=[{}],
# optional - sets the order of columns
columns=[{}],
row_selectable=True,
filterable=True,
sortable=True,
selected_row_indices=[],
id='datatable-gapminder'
),
html.Div(id='selected-indexes'),
dcc.Graph(
id='graph-gapminder'
),
], className="container")
@app.callback(
Output('datatable-gapminder', 'rows'),
[Input('file_to_load', 'value')])
def update_table(value):
with engine.connect() as conn, conn.begin():
DF_GAPMINDER = pd.read_sql("""
SELECT *
FROM """+value+"""aggreg ORDER BY var DESC;""", conn)
DF_GAPMINDER = DF_GAPMINDER.drop(['drop_col1','drop_col2'],
axis=1)
DF_GAPMINDER.loc[0:20]
return DF_GAPMINDER.to_dict('records')
@app.callback(
Output('datatable-gapminder', 'columns'),
[Input('file_to_load', 'value')])
def update_col(value):
with engine.connect() as conn, conn.begin():
DF_GAPMINDER = pd.read_sql("""
SELECT *
FROM """+value+"""aggreg LIMIT 1;""", conn)
DF_GAPMINDER = DF_GAPMINDER.drop(['drop_col1','drop_col2'],
axis=1)
return sorted(DF_GAPMINDER.columns)
@app.callback(
Output('datatable-gapminder', 'selected_row_indices'),
[Input('graph-gapminder', 'clickData')],
[State('datatable-gapminder', 'selected_row_indices')])
def update_selected_row_indices(clickData, selected_row_indices):
if clickData:
for point in clickData['points']:
if point['pointNumber'] in selected_row_indices:
selected_row_indices.remove(point['pointNumber'])
else:
selected_row_indices.append(point['pointNumber'])
return selected_row_indices
@app.callback(
Output('graph-gapminder', 'figure'),
[Input('datatable-gapminder', 'rows'),
Input('file_to_load', 'value'),
Input('datatable-gapminder', 'selected_row_indices'),
])
def update_figure(rows, value, selected_row_indices):
if value == '1':
dff = pd.DataFrame(rows)
fig = plotly.tools.make_subplots(
rows=4, cols=1,
subplot_titles=('var1', 'var2', 'var3', 'var4'),
shared_xaxes=True)
marker = {'color': ['#0074D9'] * len(dff)}
for i in (selected_row_indices or []):
marker['color'][i] = '#FF851B'
fig.append_trace({
'x': dff['1'],
'y': dff['var1'],
'type': 'bar',
'marker': marker
}, 1, 1)
fig.append_trace({
'x': dff['1'],
'y': dff['var2'],
'type': 'bar',
'marker': marker
}, 2, 1)
fig.append_trace({
'x': dff['1'],
'y': dff['var3'],
'type': 'bar',
'marker': marker
}, 3, 1)
fig.append_trace({
'x': dff['1'],
'y': dff['var4'],
'type': 'bar',
'marker': marker
}, 4, 1)
fig['layout']['showlegend'] = False
fig['layout']['height'] = 800
fig['layout']['margin'] = {
'l': 40,
'r': 10,
't': 60,
'b': 200
}
fig['layout']['yaxis2']['type'] = 'log'
elif value == '2':
dff = pd.DataFrame(rows)
fig = plotly.tools.make_subplots(
rows=4, cols=1,
subplot_titles=('var1', 'var2', 'var3', 'var4'),
shared_xaxes=True)
marker = {'color': ['#0074D9'] * len(dff)}
for i in (selected_row_indices or []):
marker['color'][i] = '#FF851B'
fig.append_trace({
'x': dff['2'],
'y': dff['var1'],
'type': 'bar',
'marker': marker
}, 1, 1)
fig.append_trace({
'x': dff['2'],
'y': dff['var2'],
'type': 'bar',
'marker': marker
}, 2, 1)
fig.append_trace({
'x': dff['2'],
'y': dff['var3'],
'type': 'bar',
'marker': marker
}, 3, 1)
fig.append_trace({
'x': dff['2'],
'y': dff['var4'],
'type': 'bar',
'marker': marker
}, 4, 1)
fig['layout']['showlegend'] = False
fig['layout']['height'] = 800
fig['layout']['margin'] = {
'l': 40,
'r': 10,
't': 60,
'b': 200
}
fig['layout']['yaxis2']['type'] = 'log'
return fig
app.css.append_css({
"external_url": "https://codepen.io/chriddyp/pen/bWLwgP.css"
})