2025-08-24 21:28:33 +02:00
|
|
|
import pandas as pd
|
2025-09-06 07:06:47 +02:00
|
|
|
import plotly.express as px
|
|
|
|
from dash import Dash, dcc, html
|
2025-08-24 21:28:33 +02:00
|
|
|
from dash.dependencies import Input, Output
|
|
|
|
|
|
|
|
from ..data.loader import DataSchema
|
|
|
|
from . import ids
|
|
|
|
|
|
|
|
|
|
|
|
def render(app: Dash, data: pd.DataFrame) -> html.Div:
|
|
|
|
@app.callback(
|
2025-09-06 07:06:47 +02:00
|
|
|
Output(ids.BAR_CHART, "children"),
|
2025-08-24 21:28:33 +02:00
|
|
|
[
|
|
|
|
Input(ids.YEAR_DROPDOWN, "value"),
|
|
|
|
Input(ids.MONTH_DROPDOWN, "value"),
|
|
|
|
Input(ids.CATEGORY_DROPDOWN, "value"),
|
|
|
|
],
|
|
|
|
)
|
2025-09-05 05:46:52 +02:00
|
|
|
def update_data_table(
|
2025-08-24 21:28:33 +02:00
|
|
|
years: list[str], months: list[str], categories: list[str]
|
2025-09-05 05:46:52 +02:00
|
|
|
) -> list[dict]:
|
2025-08-24 21:28:33 +02:00
|
|
|
filtered_data = data.query(
|
|
|
|
"year in @years and month in @months and category in @categories"
|
|
|
|
)
|
|
|
|
|
|
|
|
if filtered_data.shape[0] == 0:
|
2025-09-05 05:46:52 +02:00
|
|
|
return []
|
2025-08-24 21:28:33 +02:00
|
|
|
|
|
|
|
def create_pivot_table() -> pd.DataFrame:
|
|
|
|
pt = filtered_data.pivot_table(
|
|
|
|
values=DataSchema.AMOUNT,
|
|
|
|
index=[DataSchema.CATEGORY],
|
|
|
|
aggfunc="sum",
|
|
|
|
fill_value=0,
|
|
|
|
dropna=False,
|
|
|
|
)
|
|
|
|
return pt.reset_index().sort_values(DataSchema.AMOUNT, ascending=False)
|
|
|
|
|
2025-09-05 05:46:52 +02:00
|
|
|
return create_pivot_table().to_dict("records")
|
|
|
|
|
|
|
|
return html.Div(
|
|
|
|
DataTable(
|
|
|
|
id=ids.DATA_TABLE,
|
|
|
|
columns=[
|
|
|
|
{"name": col, "id": col}
|
|
|
|
for col in [DataSchema.CATEGORY, DataSchema.AMOUNT]
|
|
|
|
],
|
|
|
|
data=[],
|
|
|
|
sort_action="native",
|
2025-08-24 21:28:33 +02:00
|
|
|
)
|
2025-09-05 05:46:52 +02:00
|
|
|
)
|