Support all time resolutions on all counter views
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
import streamlit as st
|
||||
|
||||
import sql
|
||||
from queries import crud, daily_stats, weekly_stats, monthly_stats, yearly_stats
|
||||
from enums import CounterType
|
||||
|
||||
@st.dialog("Add New Counter", icon=":material/add_box:")
|
||||
def _add_counter():
|
||||
colors = sql.get_colors(1)
|
||||
colors = crud.get_colors(1)
|
||||
with st.form(key="add_counter", border=False, clear_on_submit=True):
|
||||
title = st.text_input("Title:")
|
||||
counter_type_name = st.selectbox("Type", options=[e.name for e in CounterType])
|
||||
@@ -16,7 +16,7 @@ def _add_counter():
|
||||
format_func=lambda c: f"#{c}")
|
||||
with st.container(horizontal=True, width="stretch", horizontal_alignment="center"):
|
||||
if st.form_submit_button(label="Create", icon=":material/save:"):
|
||||
sql.create_counter(title, CounterType[counter_type_name], color)
|
||||
crud.create_counter(title, CounterType[counter_type_name], color)
|
||||
st.rerun()
|
||||
|
||||
|
||||
@@ -26,10 +26,10 @@ def _remove_counter(counter_id:int):
|
||||
st.subheader("Are you sure?")
|
||||
with st.container(horizontal=True, width="stretch", horizontal_alignment="center"):
|
||||
if st.form_submit_button("Confirm", icon=":material/delete:"):
|
||||
sql.remove_counter(counter_id)
|
||||
crud.remove_counter(counter_id)
|
||||
st.rerun()
|
||||
|
||||
df = sql.get_counters()
|
||||
df = crud.get_counters()
|
||||
|
||||
with st.container(key="counter-table"):
|
||||
for counter_id, name, counter_type_str, color in zip(df['id'], df['name'], df['type'], df['color']):
|
||||
@@ -38,7 +38,7 @@ with st.container(key="counter-table"):
|
||||
st.header(f":material/calendar_clock: {name}", width="stretch")
|
||||
|
||||
if st.button("", icon=":material/exposure_plus_1:", key=f"increment_counter_{counter_id}"):
|
||||
sql.increment_counter(counter_id)
|
||||
crud.increment_counter(counter_id)
|
||||
st.rerun()
|
||||
|
||||
if st.button("", icon=":material/delete_forever:", key=f"remove_counter_{counter_id}"):
|
||||
@@ -51,22 +51,22 @@ with st.container(key="counter-table"):
|
||||
stats_prev_unit = counter_type.previous_unit_text()
|
||||
match counter_type:
|
||||
case CounterType.DAILY.value | CounterType.SIMPLE.value:
|
||||
stats = sql.get_daily_analytics(counter_id)
|
||||
stats = daily_stats.get_daily_analytics(counter_id)
|
||||
stats_current = stats.iloc[0]["count"]
|
||||
stats_prev = stats.iloc[1]["count"]
|
||||
|
||||
case CounterType.WEEKLY.value:
|
||||
stats = sql.get_weekly_analytics(counter_id)
|
||||
stats = weekly_stats.get_weekly_analytics(counter_id)
|
||||
stats_current = stats.iloc[0]["count"]
|
||||
stats_prev = stats.iloc[1]["count"]
|
||||
|
||||
case CounterType.MONTHLY.value:
|
||||
stats = sql.get_monthly_analytics(counter_id)
|
||||
stats = monthly_stats.get_monthly_analytics(counter_id)
|
||||
stats_current = stats.iloc[-1]["count"]
|
||||
stats_prev = stats.iloc[-2]["count"]
|
||||
|
||||
case CounterType.YEARLY.value:
|
||||
stats = sql.get_yearly_analytics(counter_id)
|
||||
stats = yearly_stats.get_yearly_analytics(counter_id)
|
||||
stats_current = stats.iloc[-1]["count"]
|
||||
stats_prev = stats.iloc[-2]["count"]
|
||||
|
||||
|
||||
@@ -1,44 +1,89 @@
|
||||
import enum
|
||||
import logging
|
||||
import streamlit as st
|
||||
import json
|
||||
import sql
|
||||
import pandas as pd
|
||||
|
||||
from enums import CounterType
|
||||
from enum import StrEnum
|
||||
from queries import crud, daily_stats, weekly_stats, monthly_stats, yearly_stats
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
counter_type_names = ([e.name for e in CounterType])
|
||||
options = counter_type_names
|
||||
options.remove(CounterType.SIMPLE.name)
|
||||
|
||||
if "counter_id" in st.query_params.keys():
|
||||
|
||||
'''
|
||||
Show specific Counter analytics where the counter id is passed as query parameter "counter_id".
|
||||
'''
|
||||
|
||||
counter_id = int(st.query_params["counter_id"])
|
||||
df = sql.get_counter(counter_id)
|
||||
df = crud.get_counter(counter_id)
|
||||
|
||||
st.header('Counter: ' + df['name'])
|
||||
counter_type_id = df['type'] - 1
|
||||
counter_type = [e for e in CounterType][counter_type_id]
|
||||
counter_color ='#' + df['color']
|
||||
|
||||
with st.container(horizontal_alignment="right", vertical_alignment="bottom", horizontal=True):
|
||||
st.header('Counter: ' + df['name'])
|
||||
selection = st.segmented_control("Time Range", options, selection_mode="single", required=True, default=counter_type.name, label_visibility="hidden")
|
||||
|
||||
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}")
|
||||
|
||||
color ='#' + df['color']
|
||||
match df['type']:
|
||||
case CounterType.DAILY.value | CounterType.SIMPLE.value:
|
||||
st.bar_chart(sql.get_daily_analytics(int(df['id'])), x="date", y="count", color=color)
|
||||
case CounterType.WEEKLY.value:
|
||||
st.bar_chart(sql.get_weekly_analytics(int(df['id'])), x="week", y="count", color=color)
|
||||
case CounterType.MONTHLY.value:
|
||||
st.bar_chart(sql.get_monthly_analytics(int(df['id'])), x="month", y="count", color=color)
|
||||
case CounterType.YEARLY.value:
|
||||
st.bar_chart(sql.get_yearly_analytics(int(df['id'])), x="year", y="count", color=color)
|
||||
|
||||
else:
|
||||
|
||||
st.header("Statistics")
|
||||
'''
|
||||
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}")
|
||||
|
||||
entries = sql.get_analytics()
|
||||
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)
|
||||
|
||||
selected_counters = [c for c in entries_full.columns if c != "date"]
|
||||
all_counters = sql.get_counters()
|
||||
selected_counters = [c for c in entries_full.columns if c != unit]
|
||||
all_counters = crud.get_counters()
|
||||
|
||||
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()
|
||||
|
||||
st.bar_chart(entries_full, x="date", x_label="Date", y_label="Count", color=colors)
|
||||
st.bar_chart(entries_full, x=unit, x_label=unit_label, y_label="Count", color=colors)
|
||||
|
||||
Reference in New Issue
Block a user