import time import webbrowser from pathlib import Path from threading import Thread from typing import cast import pandas as pd import plotly.express as px from dash import ( Dash, Input, Output, State, callback, dash_table, dcc, html, ) from lang_main.io import load_pickle from lang_main.types import ObjectID, TimelineCandidates from pandas import DataFrame # df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminder_unfiltered.csv') # ** data p_df = Path(r'./Pipe-TargetFeature_Step-3_remove_NA.pkl').resolve() p_tl = Path(r'/Pipe-Timeline_Analysis_Step-4_get_timeline_candidates.pkl').resolve() ret = cast(DataFrame, load_pickle(p_df)) data = ret[0] ret = cast(tuple[TimelineCandidates, dict[ObjectID, str]], load_pickle(p_tl)) cands = ret[0] texts = ret[1] # p_df = Path(r'.\test-notebooks\dashboard\data.pkl') # p_cands = Path(r'.\test-notebooks\dashboard\map_candidates.pkl') # p_map = Path(r'.\test-notebooks\dashboard\map_texts.pkl') # data = cast(DataFrame, load_pickle(p_df)) # cands = cast(TimelineCandidates, load_pickle(p_cands)) # texts = cast(dict[ObjectID, str], load_pickle(p_map)) table_feats = [ 'ErstellungsDatum', 'ErledigungsDatum', 'VorgangsTypName', 'VorgangsBeschreibung', ] table_feats_dates = [ 'ErstellungsDatum', 'ErledigungsDatum', ] # ** graph config markers = { 'size': 12, 'color': 'yellow', 'line': { 'width': 2, 'color': 'red', }, } hover_data = { 'ErstellungsDatum': '|%d.%m.%Y', 'VorgangsBeschreibung': True, } app = Dash(prevent_initial_callbacks=True) app.layout = [ html.H1(children='Demo Zeitreihenanalyse', style={'textAlign': 'center'}), html.Div( children=[ html.H2('Wählen Sie ein Objekt aus (ObjektID):'), dcc.Dropdown( list(cands.keys()), id='dropdown-selection', placeholder='ObjektID auswählen...', ), ] ), html.Div( children=[ html.H3(id='object_text'), dcc.Dropdown(id='choice-candidates'), dcc.Graph(id='graph-output'), ] ), html.Div(children=[dash_table.DataTable(id='table-candidates')]), ] @callback( Output('object_text', 'children'), Input('dropdown-selection', 'value'), prevent_initial_call=True, ) def update_obj_text(obj_id): obj_id = int(obj_id) obj_text = texts[obj_id] headline = f'HObjektText: {obj_text}' return headline @callback( Output('choice-candidates', 'options'), Input('dropdown-selection', 'value'), prevent_initial_call=True, ) def update_choice_candidates(obj_id): obj_id = int(obj_id) cands_obj_id = cands[obj_id] choices = list(range(1, len(cands_obj_id) + 1)) return choices @callback( Output('graph-output', 'figure'), Input('choice-candidates', 'value'), State('dropdown-selection', 'value'), prevent_initial_call=True, ) def update_timeline(index, obj_id): obj_id = int(obj_id) # title obj_text = texts[obj_id] title = f'HObjektText: {obj_text}' # cands cands_obj_id = cands[obj_id] cands_choice = cands_obj_id[int(index) - 1] # data df = data.loc[list(cands_choice)].sort_index() # type: ignore # figure fig = px.line( data_frame=df, x='ErstellungsDatum', y='ObjektID', title=title, hover_data=hover_data, ) fig.update_traces(mode='markers+lines', marker=markers, marker_symbol='diamond') fig.update_xaxes( tickformat='%B\n%Y', rangeslider_visible=True, ) fig.update_yaxes(type='category') fig.update_layout(hovermode='x unified') return fig @callback( [Output('table-candidates', 'data'), Output('table-candidates', 'columns')], Input('choice-candidates', 'value'), State('dropdown-selection', 'value'), prevent_initial_call=True, ) def update_table_candidates(index, obj_id): obj_id = int(obj_id) # cands cands_obj_id = cands[obj_id] cands_choice = cands_obj_id[int(index) - 1] # data df = data.loc[list(cands_choice)].sort_index() # type: ignore df = df.filter(items=table_feats, axis=1).sort_values( by='ErstellungsDatum', ascending=True ) cols = [{'name': i, 'id': i} for i in df.columns] # convert dates to strings for col in table_feats_dates: df[col] = df[col].dt.strftime(r'%Y-%m-%d') table_data = df.to_dict('records') return table_data, cols def _start_webbrowser(): host = '127.0.0.1' port = '8050' adress = f'http://{host}:{port}/' time.sleep(2) webbrowser.open_new(adress) def main(): webbrowser_thread = Thread(target=_start_webbrowser, daemon=True) webbrowser_thread.start() app.run(debug=True) if __name__ == '__main__': main()