Hi,
I have this strange issue where if I change the ids of certain elements, the callbacks no longer work. Here’s my code:
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State
import pandas as pd
from app import app, cache
from helper import *
CACHE_TIMEOUT = 3600
#############################
# Data Manipulation / Model #
#############################
def activity_query(date_col, start_date, end_date, date_group, group="", filter_dict={}):
addl_filters = ""
if not all(x is None for x in filter_dict.values()):
for col, flt in filter_dict.items():
if not flt:
continue
addl_filters += "AND {0} IN {1} ".format(col, create_sql_list(flt))
if group == "":
group_select = ""
elif group == "usergroup":
group_select = (
", CASE "
"WHEN usergroup IN ('Active Member', 'Ex Member', 'Banned', 'Test') THEN 'Member' "
"ELSE usergroup "
"END AS grp ")
group = ', grp'
else:
group_select = ', ' + group + ' AS grp '
group = ', grp'
query = (
"SELECT {} AS date, ".format(sql_date_group(date_col, date_group)) +
"COUNT(*) AS count" +
group_select +
"FROM dashboard_activity "
"WHERE {0} BETWEEN '{1}' AND '{2}' ".format(date_col, start_date, end_date) +
addl_filters +
"GROUP BY date{};".format(group))
return query
usergroup_filters = {'Members': 'Members', 'Administrators': 'Administrator', 'Moderators': 'Moderator'}
###########################
# Dashboard Layout / View #
###########################
layout = html.Div([
html.Div([
html.H3('Forum Activity'),
html.Img(src='/assets/img/info.png', className='desc-tooltip')
], className='chart-title'),
html.Div([
html.Div([
html.Label('Group by:', className='control-title'),
dcc.Dropdown(
id='activity-group',
options=[
{'label': 'Activity Type', 'value': 'activity'},
{'label': 'User Group', 'value': 'usergroup'},
{'label': 'Forum Section', 'value': 'cat_1_clean'}],
value='activity', clearable=False, className='control-item')
], className='control-group'),
dcc.Checklist(
options=[{'label': 'Filters', 'value': 'show'}],
id='toggle-filters', className='toggle-filters', values=[]),
html.Div([
dcc.RadioItems(
id='activity-date-grouping',
options=[
{'label': 'Day', 'value': 'D'},
{'label': 'Week', 'value': 'W'},
{'label': 'Month', 'value': 'M'}],
value='D', className='date-group-items')
], className='date-group')
], className='chart-control'),
html.Div([
html.Div([
dcc.Dropdown(
options=create_flt_options('activity', 'dashboard_activity'),
id='activity-type-flt', placeholder='Activity', multi=True, className='control-item'),
dcc.Dropdown(
options=create_flt_options('usergroup', 'dashboard_activity', usergroup_filters),
id='activity-usergroup-flt', placeholder='User Group', multi=True, className='control-item'),
dcc.Dropdown(
options=create_flt_options('cat_1_clean', 'dashboard_activity'),
id='activity-forum-flt', placeholder='Forum Section', multi=True, className='control-item'),
dcc.Dropdown(
id='activity-subforum-flt', disabled=True,
placeholder='Forum Sub-Section', multi=True, className='control-item'),
html.Button('Set Filters', id='filter-submit', className='filter-submit', n_clicks=0),
html.Button('Clear', id='filter-clear', className='filter-clear', n_clicks=0)
], className='control-filter')
], id='hidden-filters', className='hidden-filters', hidden=True),
html.Div([
dcc.Graph(id='stm-activity', config={'displayModeBar': False})
], className='chart-display')
])
###############################################
# Interaction Between Components / Controller #
###############################################
# Show filters
@app.callback(
Output('hidden-filters', 'hidden'),
[Input('toggle-filters', 'values')])
def display_act_filters(values):
if 'show' in values:
return False
else:
return True
# Hide filters upon filter submit
@app.callback(
Output('toggle-filters', 'values'),
[Input('filter-submit', 'n_clicks')])
def hide_act_upon_click(flt_clicked):
return ['']
# Clear activity type filters upon clear click
@app.callback(
Output('activity-type-flt', 'value'),
[Input('filter-clear', 'n_clicks')])
def hide_activity_type_flt(flt_clr_clicked):
return None
# Clear usergroup filters upon clear click
@app.callback(
Output('activity-usergroup-flt', 'value'),
[Input('filter-clear', 'n_clicks')])
def hide_usergroup_flt(flt_clr_clicked):
return None
# Clear forum filters upon clear click
@app.callback(
Output('activity-forum-flt', 'value'),
[Input('filter-clear', 'n_clicks')])
def hide_forum_flt(flt_clr_clicked):
return None
# Clear subforum filters upon clear click
@app.callback(
Output('activity-subforum-flt', 'value'),
[Input('filter-clear', 'n_clicks')])
def hide_subforum_flt(flt_clr_clicked):
return None
# Update Forum Sub-Section Filter Options
@app.callback(
Output('activity-subforum-flt', 'options'),
[Input('activity-forum-flt', 'value')])
@cache.memoize(timeout=CACHE_TIMEOUT)
def update_subforum_options(forum_flt):
subforum_options = create_flt_options('cat_2_title', 'dashboard_activity', filter_dict={'cat_1_clean': forum_flt})
return subforum_options
# Update Forum Sub-Section Filter Access
@app.callback(
Output('activity-subforum-flt', 'disabled'),
[Input('activity-forum-flt', 'value')])
def update_subforum_state(forum_flt):
if forum_flt:
return False
return True
# Update STM Forum Activity Chart
@app.callback(
Output('stm-activity', 'figure'),
[Input('date-picker-range', 'start_date'),
Input('date-picker-range', 'end_date'),
Input('activity-date-grouping', 'value'),
Input('activity-group', 'value'),
Input('filter-submit', 'n_clicks')],
[State('activity-type-flt', 'value'),
State('activity-usergroup-flt', 'value'),
State('activity-forum-flt', 'value'),
State('activity-subforum-flt', 'value')])
@cache.memoize(timeout=CACHE_TIMEOUT)
def update_activity(start_date, end_date, date_group, act_group, flt_clicked, act_flt, usergroup_flt, forum_flt, subforum_flt):
start_date = pd.period_range(start_date, start_date, freq=date_group).start_time[0]
end_date = pd.period_range(end_date, end_date, freq=date_group).end_time[0]
if usergroup_flt:
if 'Members' in usergroup_flt:
usergroup_flt.extend(['Ex Member', 'Active Member'])
usergroup_flt.remove('Members')
filter_dict = {}
filter_dict['activity'] = act_flt
filter_dict['usergroup'] = usergroup_flt
filter_dict['cat_1_clean'] = forum_flt
filter_dict['cat_2_title'] = subforum_flt
query = activity_query('datetime', start_date, end_date, date_group, act_group, filter_dict)
activity = pd.read_sql_query(query, engine_an)
activity = gen_cnst_df(activity, 'date', 'count')
df_shape = (activity['x'].max() - activity['x'].min()).days / date_group_map[date_group]
return {
'data': gen_traces(activity, 'bar'),
'layout': dict(
barmode='stack', showlegend=True,
legend=dict(orientation='h', xanchor='center', yanchor='middle', x=0.5, y=1.1),
font=dict(family='Roboto', size=14, color='#000'),
xaxis=gen_ts_xaxis(df_shape, date_group, start_date),
yaxis=dict(title='Activity Count')
)
}
This works fine. I know there are quite a few functions called from imported libraries here, but I don’t think it’s necessary to include them. Yet if I change the following ids, for some reason, the functionality breaks, and the graph no longer gets displayed, nor does the show/hide filter button work as intended. I wanted to change the following ids:
filter-submit
filter-clear
toggle-filters
hidden-filters
and just prepend ‘activity-’ at the beginning. Note that this is part of a larger app, and is just 1 page.
Also, I’m always open to feedback on how to improve my code =)