I am trying to create a near real-time dashboard that updates every 1 min or less. my data is from a database and i created a connection and queried the data in a pandas df before creating the layouts and the callbacks.
I use the data to create my radio-item,drop-downs as inputs, and to visualize the the data in graphs as outputs. the problem happens when I try to add the live-update component. I cant have the callback update the data before the layout, so I need to make it update every component I have in the layout. Makes a spaghetti code but I can manage to do that. My concern is I couldn’t find any examples where the output of a component has multiple Inputs including the n_intervals and other filtering components.
Here’s app code:
app = dash.Dash()
conn = pyodbc.connect("DRIVER={SQL Server};SERVER=IP;UID=username;PWD=password;DATABASE=master")
q = open('main.sql',mode='r',encoding='utf-8-sig').read()
results = pd.read_sql(q,conn)
results.created_at = pd.to_datetime(results.created_at)
app.layout(html.Div([
html.Div([ #row1 eight columns
html.Div([ #container-display
html.Div([
html.H6('Region'),
html.H5(id='region-card')
],className='mini_container')
html.Div([
html.H6('Latest Update'),
html.H5(id='date-card')
],className='mini_container')
],className='row flex-display',style={'margin':'0.5%'}),
html.Div([
html.Div([
html.Div(
[dcc.Dropdown(id='mapstyle',
options=[{'label':i,'value':i} for i in map_styles],
value='light',style={'width':'50%'}),
dcc.Graph(id='scattermap'),
dcc.Interval(id='data-update',interval=30*1000,n_intervals=0)
],className='pretty_container')
],className='eight columns'),
html.Div([
html.Div([
html.H3('Filters'),
html.Div([
html.Div([
html.Label('filter1'),
html.Div([dcc.RadioItems(id='radio1',
options=[{'label': i, 'value': str(i)} for i in
results.inside.unique())],value='All')
],className='six columns'),
html.Div([
html.Div(html.Label('Region'),style={'width':'20%'}),
html.Div([dcc.Dropdown(id='drop1',
options=[{'label': i , 'value': i } for i in
results.region_en.unique())],
value='All',multi=True)])
])
],className='pretty_container'),
html.Div([
dcc.Graph(id='bar')])
],className='pretty_container')
],className='four columns')
],className='row flex-display')
An here’s my callback:
[Input('data-update','n_intervals'),
Input('radio1','value'),
Input('drop1','value'),
Input('mapstyle','value')])
def update_map(n,radio1,drop1,value):
results = pd.read_sql(q,conn)
results.created_at = pd.to_datetime(results.created_at)
df = results[results.created_at.map(lambda x: x.date()) == datetime.strptime(date, '%Y-%m-%d').date()].copy()
if region == 'All' or (type(region) == list and ('All' in region or len(drop1) > 1)):
layout_map = some_layout
if 'All' not in region and len(region) == 1:
df = df[df.region_en.isin(region)]
layout_map = some_other_layout
return {'data':[go.Scattermapbox(lat=df['lat'],lon=df['long'])],
'layout':layout_map}
if __name__ == '__main__':
app.run_server(debug=True)
The intervals doesn’t reproduce an error until i change the other inputs (radio, drop-down, etc) in a non-consistent way
My questions is: whats the best practice in mixing interval updates with other inputs for multiple outputs, andd is there a way or a shortcut to just update the data i queried before the app layout?
P.S. I deleted some components to make the code short so I might have some missing parenthesis