diff --git a/CHANGELOG.md b/CHANGELOG.md index 20f94b2..13951d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ * Fixed * When filtering by game, the "Filtering by (...)" text would erroneously list an unrelated platform * Playtime graph would display timeline backwards + * Playtime graph with many dates would overlap (https://git.kucharczyk.xyz/lukas/timetracker/issues/34) ## 0.2.3 / 2023-01-15 23:13+01:00 diff --git a/src/web/common/util/plots.py b/src/web/common/util/plots.py index ff39ce5..5bc6a1b 100644 --- a/src/web/common/util/plots.py +++ b/src/web/common/util/plots.py @@ -3,6 +3,7 @@ from datetime import datetime from io import BytesIO import matplotlib.pyplot as plt +import matplotlib.dates as mdates import pandas as pd from django.db.models import F, IntegerField, QuerySet, Sum from django.db.models.functions import TruncDay @@ -30,7 +31,8 @@ def playtime_over_time_chart(queryset: QuerySet = Session.objects): values = [] running_total = int(0) for item in result: - date_value = datetime.strftime(item["date"], "%d-%m-%Y") + # date_value = datetime.strftime(item["date"], "%d-%m-%Y") + date_value = item["date"] keys.append(date_value) running_total += int(item["hours"] / (3600 * microsecond_in_second)) values.append(running_total) @@ -50,13 +52,34 @@ def get_graph(): def get_chart(data, title="", xlabel="", ylabel=""): + x = data[0] + y = data[1] 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() + fig, ax = plt.subplots() + fig.set_size_inches(10, 4) + ax.plot(x, y) + first = x[0] + last = x[-1] + difference = last - first + if difference.days <= 14: + ax.xaxis.set_major_locator(mdates.DayLocator()) + elif difference.days < 60 or len(x) < 60: + ax.xaxis.set_major_locator(mdates.WeekdayLocator()) + ax.xaxis.set_minor_locator(mdates.DayLocator()) + elif difference.days < 720: + ax.xaxis.set_major_locator(mdates.MonthLocator()) + ax.xaxis.set_minor_locator(mdates.WeekdayLocator()) + else: + ax.xaxis.set_major_locator(mdates.YearLocator()) + ax.xaxis.set_minor_locator(mdates.MonthLocator()) + + ax.xaxis.set_major_formatter(mdates.DateFormatter("%Y-%m-%d")) + for label in ax.get_xticklabels(which="major"): + label.set(rotation=30, horizontalalignment="right") + ax.set_xlabel(xlabel) + ax.set_ylabel(ylabel) + ax.set_title(title) + fig.tight_layout() chart = get_graph() return chart