Hey Everyone,
I am currently in the process of creating a simple dashboard which tracks the volume and type calls by user(s) within our team utilizing a multi input and output callback.
Upon page load the dataset is read from a mysql database and loaded into Dash’s DataTable.
This db is then additionally filtered through two input types, a date picker range and a multi-value dropdown (with two values loaded by default).
What’s interesting is that whenever I enter inputs that do not exist in the dataset, the outputs, in this case additional charts and tables still reflect the previous output data instead of changing to blank.
However, if I enter different inputs that do exist in the dataset, then the outputs get updated.
As an example, let’s say I want to look up the number of calls for user X for the date range May 16th through to the 20th. The output will show the volume of calls, duration etc.
However, if I change the date range for dates where I know X was not active, the outputs will keep the previous loaded data instead of going blank.
Once I do change the inputs to values that exist for X, then the outputs will update again.
Hopefully this makes sense.
I believe I have tried everything possible but can’t seem to fix this.
Here is the portion of the code which includes the callback:
@app.callback(
[Output('chart-source', 'figure'),
Output('chart-avg-calls', 'figure'),
Output('table-summary','data'),
Output('table-summary','columns')],
[Input('table', 'data'),
Input('date-picker-range', 'start_date'),
Input('date-picker-range', 'end_date'),
Input('user', 'value')])
def update_data(data, start_date, end_date, value):
updated_data = pd.DataFrame.from_dict(data)
filtered_data = pd.DataFrame()
for i in value:
filtered_data = filtered_data.append(updated_data[(updated_data['Time Start'] >= start_date) & (updated_data['Time Start'] < end_date) & (updated_data['User'] == i)])
fig_source = {
'data': [dict(
type='histogram',
x=filtered_data[filtered_data['Source'] != ""]['Source'],
marker={'color':'#03a9f4'},
hoverinfo="x+y",
hoverlabel={
'bgcolor':'#ec407a'
}
)],
'layout': dict(
yaxis={
'title': 'Number of Calls'
},
xaxis={
'tickangle': -90,
'categoryorder': 'total descending'
},
margin={'l': 40, 'b': 150, 't': 80, 'r': 0},
hovermode='closest',
title='Calls by Source'
)
}
user_summary = filtered_data.copy()
avg_calls = filtered_data.copy()
averages = avg_calls.groupby(['Day','Hour'])['Call Type'].count().reset_index()
data_summary = {
'Total No. of Calls':[user_summary['User'].count()],
'Onnet Calls':[user_summary[user_summary['Call Type'] == 'onnet']['User'].count()],
'Avg. No./Hour':[round(user_summary.groupby(['Day','Hour'])['Call Type'].count().reset_index().groupby(['Hour'])['Call Type'].mean().reset_index()['Call Type'].mean(),2)],
'Avg. Duration':[str(datetime.timedelta(seconds = round(user_summary['Duration'].mean(),0)))]
}
df_summary = pd.DataFrame(data_summary, columns = ['Total No. of Calls','Onnet Calls','Avg. No./Hour','Avg. Duration'])
columns_summary = [{"name": i, "id": i} for i in df_summary]
fig_avg_calls = {
'data': [dict(
type='bar',
x=sorted(averages['Hour'].unique()),
y=averages.groupby(['Hour'])['Call Type'].mean().reset_index()['Call Type'],
marker={'color':'#03a9f4'},
hoverinfo="y",
hoverlabel={
'bgcolor':'#ec407a'
}
)],
'layout': dict(
yaxis={
'title': 'Number of Calls'
},
xaxis={
'tickmode': 'array',
'tickvals': list(range(0,24)),
'nticks': 24,
'tick0': 0,
'dtick': 1,
'title':'Hour'
},
hovermode='closest',
title='Avg. Number of Calls by Time of Day'
)
}
return [fig_source, fig_avg_calls, df_summary.to_dict('records'), columns_summary]
Thank you in advance for your help!
Cheers