2023-01-15 17:03:59 +00:00
|
|
|
import base64
|
2023-01-15 22:39:52 +00:00
|
|
|
from datetime import datetime
|
2023-01-15 17:03:59 +00:00
|
|
|
from io import BytesIO
|
2023-01-15 22:39:52 +00:00
|
|
|
|
|
|
|
import matplotlib.pyplot as plt
|
|
|
|
import pandas as pd
|
|
|
|
from django.db.models import F, IntegerField, QuerySet, Sum
|
2023-01-15 17:03:59 +00:00
|
|
|
from django.db.models.functions import TruncDay
|
2023-01-15 22:39:52 +00:00
|
|
|
from tracker.models import Session
|
2023-01-15 17:03:59 +00:00
|
|
|
|
|
|
|
|
|
|
|
def key_value_to_value_value(data):
|
|
|
|
return {data["date"]: data["hours"]}
|
|
|
|
|
|
|
|
|
|
|
|
def playtime_over_time_chart(queryset: QuerySet = Session.objects):
|
|
|
|
microsecond_in_second = 1000000
|
|
|
|
result = (
|
|
|
|
queryset.annotate(date=TruncDay("timestamp_start"))
|
|
|
|
.values("date")
|
|
|
|
.annotate(
|
|
|
|
hours=Sum(
|
|
|
|
F("duration_calculated") + F("duration_manual"),
|
|
|
|
output_field=IntegerField(),
|
|
|
|
)
|
|
|
|
)
|
|
|
|
.values("date", "hours")
|
|
|
|
)
|
|
|
|
keys = []
|
|
|
|
values = []
|
|
|
|
running_total = int(0)
|
|
|
|
for item in result:
|
|
|
|
date_value = datetime.strftime(item["date"], "%d-%m-%Y")
|
|
|
|
keys.append(date_value)
|
|
|
|
running_total += int(item["hours"] / (3600 * microsecond_in_second))
|
|
|
|
values.append(running_total)
|
|
|
|
data = [keys, values]
|
|
|
|
return get_chart(data, title="Playtime over time", xlabel="Date", ylabel="Hours")
|
|
|
|
|
|
|
|
|
|
|
|
def get_graph():
|
|
|
|
buffer = BytesIO()
|
|
|
|
plt.savefig(buffer, format="svg", transparent=True)
|
|
|
|
buffer.seek(0)
|
|
|
|
image_png = buffer.getvalue()
|
|
|
|
graph = base64.b64encode(image_png)
|
|
|
|
graph = graph.decode("utf-8")
|
|
|
|
buffer.close()
|
|
|
|
return graph
|
|
|
|
|
|
|
|
|
|
|
|
def get_chart(data, title="", xlabel="", ylabel=""):
|
|
|
|
plt.style.use("dark_background")
|
|
|
|
plt.switch_backend("SVG")
|
|
|
|
fig = plt.figure(figsize=(10, 4))
|
|
|
|
plt.plot(data[0], data[1])
|
|
|
|
plt.title(title)
|
|
|
|
plt.xlabel(xlabel)
|
|
|
|
plt.ylabel(ylabel)
|
|
|
|
plt.tight_layout()
|
|
|
|
chart = get_graph()
|
|
|
|
return chart
|