akono-app-v4 / callbacks /tab_grapheàchoix_callbacks.py
mzufferey
0610
1a02e7a
import sys
from dash.dependencies import Input, Output
from settings import *
from utils_fcts import *
import plotly.express as px
def register_callbacks(app):
timecols2show = list(showcols_settings.keys())#x for x in timedata_columns if not showcols_settings[x] == "NA"]
dayIcols2show = list(dayIcols_settings.keys())#[x for x in dayIdata_columns if not x == db_daycol]
################################################################################################
################################ CALLBACKS - TAB EVOTIME - VISUALISATIONS tab-evotime
################################################################################################
# callback pour vérifier le nombre de variables sélectionnées et afficher la pop-up :
@app.callback(
[Output('confirm-dialog-evotime', 'displayed'),
Output('evotimeTimeDB-graph-col', 'value')],
[Input('evotimeTimeDB-graph-col', 'value')]
)
def limit_selection_evotimedata(selected_columns):
if selected_columns :
if len(selected_columns) > maxTimePlotVar:
return True, selected_columns[:maxTimePlotVar] # Afficher la pop-up et limiter la sélection à 2
return False, selected_columns # Ne pas afficher la pop-up
@app.callback(
Output('evotimeTimeDB-graph-varinfo', 'children'),
[Input('evotimeTimeDB-graph-col', 'value')],
[State('evotimeTimeDB-db', 'value')]
)
def update_evotimevarinfo(selected_col, selected_db):
if selected_col and selected_db:
desc_txt = get_var_desc(selected_col, selected_db)
else:
return None
return html.Div([dcc.Markdown(desc_txt,
dangerously_allow_html=True)])
# Callback pour gérer l'ouverture et la fermeture de la modale, et l'affichage du graphique
@app.callback(
[Output('evotime-modal-graph-modal', 'is_open'),
Output('evotime-modal-graph', 'figure')],
[Input('evotimeTimeDB-graph', 'clickData'),
Input('close-modal', 'n_clicks')],
[State('evotime-modal-graph-modal', 'is_open'),
State('evotimeTimeDB-graph', 'figure')],
prevent_initial_call=True
)
def toggle_modal_evotime(clickData, n_clicks, is_open, myfig):
ctx = dash.callback_context
if ctx.triggered and ctx.triggered[0]['prop_id'] == 'close-modal.n_clicks':
return False, go.Figure() # Fermer la modale
if clickData:
return True, myfig # Ouvrir la modale avec le graphique
return is_open, go.Figure() # Ne change rien si aucun événement n'est détecté
# Callback pour afficher le graphique en fonction de la sélection :
@app.callback(
[Output('evotimeTimeDB-graph', 'figure'),
Output('confirm-dialog-evoTimeDBgraph', 'displayed'),
Output('confirm-dialog-evoTimeDBgraph', 'message'),
Output('evotime-range-info', 'children')],
[Input('show-evotimeTimeDBgraph-btn', 'n_clicks')],
[State('evotimeTimeDB-db', 'value'),
State('evotimeTimeDB-graph-col', 'value'),
State('evotimeTimeDB-graph-viz', 'value'),
State('evotimeperiod-dropdown', 'value'),
State('range-picker-evotime', 'start_date'),
State('range-picker-evotime', 'end_date'),
State('stored_timeDB', 'data'),
State('stored_dayDB', 'data')]
)
def display_timeevolution_graph(n_clicks, selected_db, selected_col, selected_viz,
selected_period, start_date, end_date, time_db, day_db):
if n_clicks is None or n_clicks == 0:
return [go.Figure(), False, "", ""]
if (not selected_db or not selected_col or not selected_viz) :
return [go.Figure(), True, "Sélectionnez dans les menus déroulants", ""]
if selected_db == dbTime_name:
df = pd.DataFrame(time_db)
dfcol = db_timecol
elif selected_db == dbDayI_name:
df = pd.DataFrame(day_db)
dfcol = db_daycol
else:
sys.exit(1)
df = df.sort_values(by=dfcol)
if selected_period == "stat_perso" and (not start_date or not end_date):
return [go.Figure(), True, "Sélectionnez une date de début et fin", ""]
if selected_period == "stat_perso":
start_date = datetime.strptime(start_date, '%Y-%m-%d').date()
end_date = datetime.strptime(end_date, '%Y-%m-%d').date()
else:
start_date, end_date = get_startrange_date_vLatest(df[dfcol], selected_period)
date_info = f"Zoom sur les données du {start_date} au {end_date}"
if selected_db == dbTime_name:
xcol = db_timecol
assert db_daycol != db_timecol
df[db_daycol] = pd.to_datetime(df[xcol]).dt.date
colsettings = showcols_settings
else:
xcol = db_daycol
if selected_db == dbDayI_name:
colsettings = dayIcols_settings
for col in dayI_cols:
df[col] = df[col + "_1"].fillna(0) + df[col + "_2"].fillna(0)
#df.to_pickle('df_grapheàchoix_1.pkl')
if selected_viz == "boxplot" and isinstance(selected_col, list) and len(selected_col) > 1:
df_melted = pd.melt(df, id_vars=[db_daycol], value_vars=selected_col,
var_name='variable', value_name='valeur')
# Créer le boxplot avec des couleurs différentes pour chaque variable
fig = px.box(df_melted, x=db_daycol, y='valeur', color='variable',
title=f'Box Plot par jour pour {selected_col}',
labels={'valeur': 'Nouvelle Étiquette Y'} )
# if selected_db == dbTime_name and selected_viz == 'boxplot':
# fig = px.box(df, x='date', y=selected_col, title=f'{selected_col} Box Plot par jour')
else:
if selected_viz == 'lineplot':
# fig = px.line(df, x=xcol, y=selected_col, title=f'{selected_col} Line Plot')
# Lire toutes les données de la base de données
# df = fetch_timedata()
fig = go.Figure()
for i, col in enumerate(selected_col):
# Ajout de chaque variable sur un axe y différent
fig.add_trace(
go.Scatter(
x=df[xcol],
y=df[col],
mode='lines+markers',
name=col,
yaxis=f'y{i + 1}'
)
)
update_layout_cols(selected_col)
yaxis_layout['title'] = colsettings[selected_col[0]]['lab']
fig.update_layout(
xaxis=dict(domain=[0.25, 0.75], showline=True, linewidth=2, linecolor='black'),
yaxis=yaxis_layout,
yaxis2=yaxis2_layout,
yaxis3=yaxis3_layout,
yaxis4=yaxis4_layout,
title_text="", ## titre en-haut à gauche
margin=dict(l=40, r=40, t=40, b=30)
)
elif selected_viz == 'barplot':
fig = px.bar(df, x=xcol, y=selected_col, title=f'{selected_col} Bar Plot')
fig.update_layout(barmode='group')
elif selected_viz == 'boxplot':
fig = px.box(df, x=xcol, y=selected_col, title=f'{selected_col} Box Plot')
fig.update_layout(xaxis=xaxis_settings)
fig.update_layout(
template='plotly_white',
plot_bgcolor='white',
paper_bgcolor='white',
title_font=dict(size=18, family='Arial', color='black'),
xaxis_title_font=dict(size=14, family='Arial', color='black'),
yaxis_title_font=dict(size=14, family='Arial', color='black'),
xaxis=dict(
showgrid=True,
gridcolor='lightgrey',
zeroline=False,
showline=True,
linewidth=1,
linecolor='black',
),
yaxis=dict(
showgrid=True,
gridcolor='lightgrey',
zeroline=False,
showline=True,
linewidth=1,
linecolor='black',
)
)
if start_date and end_date:
fig.update_xaxes(range=[start_date, end_date])
return [fig, False, "", date_info]
@app.callback(
Output('evotimeTimeDB-graph-viz', 'options'),
[Input('evotimeTimeDB-db', 'value')]
)
def update_evotimeviz_options(selected_db):
if selected_db == dbTime_name:
return [
{'label': 'Line Plot', 'value': 'lineplot'},
{'label': 'Bar Plot', 'value': 'barplot'},
{'label': 'Box Plot', 'value': 'boxplot'}
]
else:
return [
{'label': 'Line Plot', 'value': 'lineplot'},
{'label': 'Bar Plot', 'value': 'barplot'}
]
################################ CALLBACKS - TAB STAT - VISUALISATION
# Callback pour mettre à jour les colonnes disponibles en fonction de la table sélectionnée :
@app.callback(
Output('evotimeTimeDB-graph-col', 'options'),
[Input('evotimeTimeDB-db', 'value')]
)
def update_evotime_columns(selected_db):
if selected_db:
if selected_db == dbTime_name:
columns = [{'label': col, 'value': col} for col in timecols2show]
elif selected_db == dbDayI_name:
columns = [{'label': col + "=" + dayIcols_settings[col]['lab'],
'value': col} for col in dayI_cols + dayIcols2show]
else:
sys.exit(1)
return columns
return []
# Callback pour gérer l'ouverture et la fermeture de la modale, et l'affichage du graphique
@app.callback(
[Output('stat-modal-graph-modal', 'is_open'),
Output('stat-modal-graph', 'figure')],
[Input('evotimeTimeDB-graph', 'clickData'),
Input('close-modal-stat', 'n_clicks')],
[State('stat-modal-graph-modal', 'is_open'),
State('evotimeTimeDB-graph', 'figure')],
prevent_initial_call=True
)
def toggle_modal_stat(clickData, n_clicks, is_open, myfig):
ctx = dash.callback_context
if ctx.triggered and ctx.triggered[0]['prop_id'] == 'close-modal.n_clicks':
return False, go.Figure() # Fermer la modale
if clickData:
return True, myfig # Ouvrir la modale avec le graphique
return is_open, go.Figure() # Ne change rien si aucun événement n'est détecté