hi, I would like to use @app.callback inside a function that I use to create graph inside a card .
def SingleCard(df,title,id_figure,title_periode,app,typeChart,withDrillDown=False):
id_dropdownPeriode=str(id_figure)+'_periode'
id_buttonSave=str(id_figure)+'_Save'
id_icon=str(id_figure)+'_icon'
id_buttonExpand=str(id_figure)+'_expand'
id_download=str(id_figure)+'_download'
id_session=str(id_figure)+'_session'
id_form=str(id_figure)+'_form'
id_fichier=str(id_figure)+'_fichier'
id_buttonExp=str(id_figure)+'_exporter'
id_dropdownFormat=str(id_figure)+'_format'
id_buttonAnnuler=str(id_figure)+'_annuler'
id_modalSave=str(id_figure)+'_modalSave'
id_modalExpand=str(id_figure)+'_modalExpand'
id_figure2='Full'+str(id_figure)
id_dropdownPeriode2=str(id_figure)+'_periode2'
id_buttonFermer=str(id_figure)+'_buttonFermer'
chartType=typeChart
card= dbc.Card([
dbc.CardHeader(title,style={'fontSize':'15px'}),
dbc.CardBody(
[
dbc.Col([dbc.Row(html.P(title_periode,style={'font-size':'10px','marginLeft': '10px','marginBottom': '-11px'})),
dbc.Row(dropdownSingle(['Cette année','Année précédente','Ce trimestre'],id_dropdownPeriode,"periode",'Cette année'))]),
dcc.Loading(
children=html.Div(className="mycontainer",
children=[dbc.Col([dbc.Button(id=id_buttonSave,children=[html.I(className="fas fa-download modebar-group icon",id=id_icon),
dbc.Tooltip("save as excel file",hide_arrow=False,target=id_icon,placement="bottom",style={'fontSize':'10px','backgroundColor':'#6c7581','textAlign':'center','height':'20px','marginTop':'2px'})],
className="mr-2",style={'zIndex': '10','float': 'right','top': '0px','position': 'relative','right': '-21px','backgroundColor':'transparent','border':'None','paddingTop': '0px','opacity':'0.7'})
]),
dbc.Col(dbc.Button(id=id_buttonExpand,children=html.I(className="fas fa-expand-arrows-alt modebar-group"),
className="mr-2",style={'zIndex': '10','float': 'left','top': '-5px','position': 'relative','left': '-23px','backgroundColor':'transparent','border':'None','paddingTop': '0px','opacity':'0.7'})),
dcc.Graph(id=id_figure)]), type="graph",style={'zIndex':'2'}),
dbc.Col([dbc.Button("Reset",id='button_reset2',className="mr-2",style={'zIndex': '10','float': 'left','bottom': '44px','position': 'relative',"right":"10px"})]),
dcc.Download(id=id_download),
dcc.Store(id=id_session, storage_type='session',clear_data=True),
dbc.Modal(
[
dbc.ModalHeader("Exporter les données sous format excel"),
dbc.ModalBody(children=dbc.FormGroup(
[
dbc.Label("Nom du fichier"),
dbc.Input(placeholder="Nom du fichier", type="text",id=id_fichier,value=str(title)[0:22]),
html.Br(),
dbc.Label("Format d'exportation"),
dcc.Dropdown(
id=id_dropdownFormat,
options=[
{'label': '.xls', 'value': '.xls'},
{'label': '.xlsx', 'value': '.xlsx'},
{'label': '.csv', 'value': '.csv'},
],
value='.xlsx',
clearable=False,
),
]
)
),
dbc.ModalFooter([
dbc.Button("exporter", id=id_buttonExp, className="ml-auto"),
dbc.Button("Annuler", id=id_buttonAnnuler, className="ml-auto"),
]
),
],
id=id_modalSave,
),
dbc.Modal(
[
dbc.ModalHeader(title),
dbc.Col([dbc.Row(html.P(title_periode,style={'font-size':'12px','marginLeft': '20px','marginBottom': '-6px'})),
dbc.Row(dropdownSingle(['Cette année','Année précédente','Ce trimestre'],id_dropdownPeriode2,"periode",'Cette année'))]),
dbc.ModalBody(children=dcc.Graph(id=id_figure2)
),
dbc.ModalFooter([
dbc.Button("Fermer", id=id_buttonFermer),
]
),
],
id=id_modalExpand,
size="xl",
style={"width":"100%","maxWidth":"none","maxHeight":"none"}
),
]
),],
outline=True,
color="dark",
inverse=True,
)
@app.callback(
Output(id_download, "data"),[
Input(id_buttonExp, "n_clicks")],
[State(id_fichier, "value"),
State(id_dropdownPeriode,'value'),
State(id_dropdownFormat,"value"),
State(id_session, 'data')
],
)
def func(n_clicks,nom,periode,format,data):
ctx = dash.callback_context
year=datetime.now().year
final_df=pd.read_json(data, orient='split')
df_export=final_df.drop(columns=['myyear', 'QUARTER'])
name=str(nom).replace(' ', '_')+str(format)
if str(format)==".csv":
print(name)
return dcc.send_data_frame(df_export.to_csv,name)
else :
print(name)
return dcc.send_data_frame(df_export.to_excel,name,sheet_name=str(nom))
@app.callback(
Output(id_modalSave, "is_open"),
[Input(id_buttonSave, "n_clicks"), Input(id_buttonAnnuler, "n_clicks")],
[State(id_modalSave, "is_open")],
)
def toggle_modal(n1, n2, is_open):
if n1 or n2 :
return not is_open
return is_open
@app.callback(
Output(id_modalExpand, "is_open"),
[Input(id_buttonExpand, "n_clicks"), Input(id_buttonFermer, "n_clicks")],
[State(id_modalExpand, "is_open")],
)
def toggle_modal(n1, n2, is_open):
if n1 or n2 :
return not is_open
return is_open
return card
I create this function as a template where my charts will be put to avoid repeating the code,this card include a reset button in case there is a drill down, a button to export as csv/excel and a button to show the chart with full width.
this the code I use to call the function
cards1 = dbc.CardDeck(
[
SingleCard("Répartition des dossiers e-déposés par localité", "pie", "Date e-dépôt", app, "pie"),
SingleCard("Evolution du nombre de dossiers e-déposés par catégorie projet", "histogram_drill", "Date e-dépôt", app, "histogram",True),
])
Unfortunately, I met these following problems:
- The callbacks aren’t identified on the first run I need to refresh the page
- If I refresh a second time or open the dashboard in two tabs I get “Duplicate callback outputs”
With a first refresh the app works well
Some help will be appreciated
Thanks