import sys import dash from dash import dcc, html import pandas as pd import plotly.graph_objects as go import plotly.express as px def numerize(df, column): if isinstance(column, list): for item in column: df = numerize(df, item) else: df[column] = pd.to_numeric(df[column], errors="coerce") return df data = [] with open("financials.txt", "r") as f: for line in f: line = line.strip() if line == "": pass elif line.startswith("#"): data.append([]) else: data[-1].append(line.split(",")) asset = numerize(pd.DataFrame(data[0], columns=["Name", "Amount"]), "Amount") debt = numerize(pd.DataFrame(data[2], columns=["Name", "Amount"]), "Amount") net = numerize(pd.DataFrame(data[3], columns=["Name", "Amount"]), "Amount") expense = numerize(pd.DataFrame(data[4], columns=["Name", "Amount"]), "Amount") revenue = numerize(pd.DataFrame(data[5], columns=["Name", "Amount"]), "Amount") inv_asset = numerize(pd.DataFrame(data[1], columns=["Name", "Amount"]), "Amount") inv_expense = numerize(pd.DataFrame(data[7], columns=["Name", "Amount"]), "Amount") inv_revenue = numerize(pd.DataFrame(data[8], columns=["Name", "Amount"]), "Amount") food_expense = numerize(pd.DataFrame(data[6], columns=["Name", "Amount"]), "Amount") daily = numerize(pd.DataFrame(data[9], columns=["Date", "Asset", "RealNet", "Risked"]), ["Asset", "RealNet", "Risked"]) # ---- displaying ---- def PieAndTable(title, data): total = sum(data["Amount"]) fig = px.pie( data.sort_values(by="Amount", ascending=False), names="Name", values="Amount", hole=0.5, hover_name="Name", title=title, ) fig.update_traces( hovertemplate="%{label}
%{value} (%{percent})", textinfo="label", ) fig.update_layout( annotations=[ dict( x=0.5, y=0.5, text=f"{total:,}", showarrow=False, ), ], showlegend=False, ) return dcc.Graph( style={"flex": "1", "height": "20rem"}, figure=fig, ) def PlWaterfall(title, e, r): merged = pd.merge(e, r, on="Name", suffixes=["E", "R"], how="outer") merged["Amount"] = merged["AmountR"].fillna(0) - merged["AmountE"].fillna(0) merged = merged.sort_values(by="Amount", ascending=False) fig = go.Figure(go.Waterfall( orientation="v", x=merged["Name"], y=merged["Amount"], )) fig.update_layout(title=title) return dcc.Graph(figure=fig) def DailyLines(df): fig = go.Figure() fig.add_trace(go.Scatter( x=df["Date"], y=df["Asset"], mode="lines", name="Total" )) fig.add_trace(go.Scatter( x=df["Date"], y=df["RealNet"], mode="lines", name="Realtime Net" )) fig.add_trace(go.Scatter( x=df["Date"], y=df["Risked"], mode="lines", name="Risked" )) fig.update_layout(hovermode="x unified") return dcc.Graph(figure=fig) app = dash.Dash(__name__) app.layout = html.Div([ html.H2("WHOLE"), html.Div( style={"display": "flex", "gap": "1rem"}, children=[ PieAndTable("Asset", asset), PieAndTable("Debt", debt), PieAndTable("Net", net), ], ), PlWaterfall("P&L", expense, revenue), html.H2("DAILY"), html.Div(children=[ DailyLines(daily), ]), html.H2("DETAILS"), html.Div( style={"display": "flex", "gap": "1rem"}, children=[ PieAndTable("Food Expenses", food_expense), PieAndTable("RiskedAsset", inv_asset), ], ), PlWaterfall("Investment P&L", inv_expense, inv_revenue), ]) app.run(debug=True)