2026-04-21 12:59:55 +02:00
|
|
|
import enum
|
2026-03-31 19:09:37 +02:00
|
|
|
import logging
|
|
|
|
|
import streamlit as st
|
|
|
|
|
import json
|
|
|
|
|
import pandas as pd
|
|
|
|
|
|
|
|
|
|
from enums import CounterType
|
2026-04-21 12:59:55 +02:00
|
|
|
from enum import StrEnum
|
|
|
|
|
from queries import crud, daily_stats, weekly_stats, monthly_stats, yearly_stats
|
2026-03-31 19:09:37 +02:00
|
|
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
2026-04-21 12:59:55 +02:00
|
|
|
counter_type_names = ([e.name for e in CounterType])
|
|
|
|
|
options = counter_type_names
|
|
|
|
|
options.remove(CounterType.SIMPLE.name)
|
|
|
|
|
|
2026-03-31 19:09:37 +02:00
|
|
|
if "counter_id" in st.query_params.keys():
|
2026-04-21 12:59:55 +02:00
|
|
|
|
|
|
|
|
'''
|
|
|
|
|
Show specific Counter analytics where the counter id is passed as query parameter "counter_id".
|
|
|
|
|
'''
|
|
|
|
|
|
2026-03-31 19:09:37 +02:00
|
|
|
counter_id = int(st.query_params["counter_id"])
|
2026-04-21 12:59:55 +02:00
|
|
|
df = crud.get_counter(counter_id)
|
|
|
|
|
|
|
|
|
|
counter_type_id = df['type'] - 1
|
|
|
|
|
counter_type = [e for e in CounterType][counter_type_id]
|
|
|
|
|
counter_color ='#' + df['color']
|
2026-03-31 19:09:37 +02:00
|
|
|
|
2026-04-21 12:59:55 +02:00
|
|
|
with st.container(horizontal_alignment="right", vertical_alignment="bottom", horizontal=True):
|
|
|
|
|
st.header('Counter: ' + df['name'])
|
2026-04-28 21:04:52 +02:00
|
|
|
selected = counter_type.name
|
|
|
|
|
if selected == CounterType.SIMPLE.name:
|
|
|
|
|
selected = CounterType.DAILY.name
|
|
|
|
|
selection = st.segmented_control("Time Range", options, selection_mode="single", required=True, default=selected, label_visibility="hidden")
|
2026-04-21 12:59:55 +02:00
|
|
|
|
|
|
|
|
match getattr(CounterType, selection):
|
|
|
|
|
case CounterType.DAILY:
|
|
|
|
|
st.bar_chart(daily_stats.get_daily_analytics(counter_id), x="date", y="count", color=counter_color)
|
|
|
|
|
case CounterType.WEEKLY:
|
|
|
|
|
st.bar_chart(weekly_stats.get_weekly_analytics(counter_id), x="week", y="count", color=counter_color)
|
|
|
|
|
case CounterType.MONTHLY:
|
|
|
|
|
st.bar_chart(monthly_stats.get_monthly_analytics(counter_id), x="month", y="count", color=counter_color)
|
|
|
|
|
case CounterType.YEARLY:
|
|
|
|
|
st.bar_chart(yearly_stats.get_yearly_analytics(counter_id), x="year", y="count", color=counter_color)
|
|
|
|
|
case _:
|
|
|
|
|
logger.error(f"Unknown selection: {selection}")
|
2026-03-31 19:09:37 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
2026-04-21 12:59:55 +02:00
|
|
|
'''
|
|
|
|
|
By default, if no counter id is passed then show all counters in a a stacked graph
|
|
|
|
|
'''
|
|
|
|
|
with st.container(horizontal_alignment="right", vertical_alignment="bottom", horizontal=True):
|
|
|
|
|
st.header("Statistics")
|
|
|
|
|
selection = st.segmented_control("Time range", options, selection_mode="single", default=f"{CounterType.DAILY.name}", required=True, label_visibility="hidden")
|
|
|
|
|
|
|
|
|
|
selectedRange = getattr(CounterType, selection)
|
|
|
|
|
match getattr(CounterType, selection):
|
|
|
|
|
case CounterType.DAILY:
|
|
|
|
|
unit = 'date'
|
|
|
|
|
unit_label = 'Date'
|
|
|
|
|
entries = daily_stats.get_all_daily_analytics()
|
|
|
|
|
case CounterType.WEEKLY:
|
|
|
|
|
unit = 'week'
|
|
|
|
|
unit_label ='Week'
|
|
|
|
|
entries = weekly_stats.get_all_weekly_analytics()
|
|
|
|
|
case CounterType.MONTHLY:
|
|
|
|
|
unit = 'month'
|
|
|
|
|
unit_label = 'Month'
|
|
|
|
|
entries = monthly_stats.get_all_monthly_analytics()
|
|
|
|
|
case CounterType.YEARLY:
|
|
|
|
|
unit = 'year'
|
|
|
|
|
unit_label = 'Year'
|
|
|
|
|
entries = yearly_stats.get_all_yearly_analytics()
|
|
|
|
|
case _:
|
|
|
|
|
logger.error(f"Unknown selection: {selection}")
|
2026-03-31 19:09:37 +02:00
|
|
|
|
|
|
|
|
entries_norm = pd.json_normalize(entries.counters.apply(json.loads)).fillna(0)
|
|
|
|
|
entries_full = pd.concat([entries, entries_norm], axis=1).drop(['counters'], axis=1)
|
|
|
|
|
|
2026-04-21 12:59:55 +02:00
|
|
|
selected_counters = [c for c in entries_full.columns if c != unit]
|
|
|
|
|
all_counters = crud.get_counters()
|
|
|
|
|
|
2026-03-31 19:09:37 +02:00
|
|
|
colors = all_counters.loc[all_counters['name'].isin(selected_counters), ["name", "color"]]
|
|
|
|
|
colors.name = colors.name.astype("category")
|
|
|
|
|
colors.name = colors.name.cat.set_categories(selected_counters)
|
|
|
|
|
colors = colors.sort_values(["name"])
|
|
|
|
|
colors = colors.color.apply(lambda c: "#" + c).tolist()
|
|
|
|
|
|
2026-04-21 12:59:55 +02:00
|
|
|
st.bar_chart(entries_full, x=unit, x_label=unit_label, y_label="Count", color=colors)
|