This commit adds a new diagram in stats: a bar chart with hourly drinks from the database.
This commit is contained in:
@@ -916,3 +916,29 @@ def get_stats_drink_types():
|
||||
drink["icon"] = drink_type_info["icon"]
|
||||
|
||||
return drinks
|
||||
|
||||
def get_stats_drink_hourly():
|
||||
"""
|
||||
Retrieve hourly drink statistics from the database.
|
||||
Executes a SQL query to count the number of drinks grouped by hour of the day
|
||||
(00-23). Returns a list of dictionaries containing the hour and count for each
|
||||
hour. Hours without any drinks are included with a count of 0.
|
||||
Returns:
|
||||
list[dict]: A list of dictionaries with keys 'hour' (string, e.g., "00", "01", ..., "23")
|
||||
and 'count' (int). The list is sorted by hour in ascending order.
|
||||
Returns an empty list if no drinks exist in the database.
|
||||
"""
|
||||
|
||||
t = text("SELECT strftime('%H', timestamp), count(*) FROM drinks GROUP BY strftime('%H', timestamp);")
|
||||
with engine.connect() as connection:
|
||||
result = connection.execute(t).fetchall()
|
||||
if not result:
|
||||
return []
|
||||
hourly_stats = [{"hour": row[0], "count": row[1]} for row in result]
|
||||
# sort by hour and add hours without drinks with count 0
|
||||
for hour in range(24):
|
||||
if not any(stat["hour"] == f"{hour:02d}" for stat in hourly_stats):
|
||||
hourly_stats.append({"hour": f"{hour:02d}", "count": 0})
|
||||
hourly_stats.sort(key=lambda x: x["hour"])
|
||||
|
||||
return hourly_stats
|
||||
|
||||
@@ -500,12 +500,14 @@ def stats(request: Request):
|
||||
raise HTTPException(status_code=404, detail="User not found")
|
||||
|
||||
drink_types = db.models.get_stats_drink_types()
|
||||
hourly_stats = db.models.get_stats_drink_hourly()
|
||||
|
||||
return templates.TemplateResponse("stats.html", {
|
||||
"request": request,
|
||||
"user": user_authentik,
|
||||
"user_db_id": user_db_id,
|
||||
"stats_drink_types": drink_types,
|
||||
"stats_drink_hourly": hourly_stats,
|
||||
})
|
||||
|
||||
@app.post("/add_drink_type")
|
||||
|
||||
@@ -7,12 +7,18 @@
|
||||
|
||||
<h3>Verteilung der Getränkesorten</h3>
|
||||
<canvas id="pieChart" width="400" height="200"></canvas>
|
||||
<canvas id="hourChart" width="400" height="200"></canvas>
|
||||
|
||||
<script>
|
||||
// Pie Chart für Getränketypen
|
||||
const pieChartLabels = {{ stats_drink_types | map(attribute='drink_type') | list | tojson }};
|
||||
const pieChartData = {{ stats_drink_types | map(attribute='count') | list | tojson }};
|
||||
const pieCtx = document.getElementById('pieChart').getContext('2d');
|
||||
|
||||
const hourChartLabels = {{ stats_drink_hourly | map(attribute='hour') | list | tojson }};
|
||||
const hourChartData = {{ stats_drink_hourly | map(attribute='count') | list | tojson }};
|
||||
const hourCtx = document.getElementById('hourChart').getContext('2d');
|
||||
|
||||
new Chart(pieCtx, {
|
||||
type: 'doughnut',
|
||||
data: {
|
||||
@@ -32,5 +38,29 @@ new Chart(pieCtx, {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
new Chart(hourCtx, {
|
||||
type: 'bar',
|
||||
data: {
|
||||
labels: hourChartLabels,
|
||||
datasets: [{
|
||||
label: 'Getränke pro Stunde',
|
||||
data: hourChartData,
|
||||
backgroundColor: 'rgba(54, 162, 235, 0.2)',
|
||||
borderColor: 'rgba(54, 162, 235, 1)',
|
||||
borderWidth: 1
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
plugins: {
|
||||
legend: { position: 'top' },
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Getränkeverbrauch pro Stunde'
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user