From 2221a9966250f61c8b621fdab7d7dd72c59b2783 Mon Sep 17 00:00:00 2001 From: CasperVerswijvelt Date: Sun, 25 Apr 2021 22:54:06 +0200 Subject: [PATCH 1/5] When daterange is 1 day, show hourly data in chart --- shynet/core/models.py | 44 +++++++++++++------ .../dashboard/includes/service_overview.html | 2 +- .../dashboard/includes/time_chart.html | 6 +++ .../templates/dashboard/pages/service.html | 2 +- 4 files changed, 39 insertions(+), 15 deletions(-) diff --git a/shynet/core/models.py b/shynet/core/models.py index e67f614..de15a65 100644 --- a/shynet/core/models.py +++ b/shynet/core/models.py @@ -7,7 +7,7 @@ from django.apps import apps from django.contrib.auth.models import AbstractUser from django.core.exceptions import ValidationError from django.db import models -from django.db.models.functions import TruncDate +from django.db.models.functions import TruncDate, TruncHour from django.db.utils import NotSupportedError from django.shortcuts import reverse from django.utils import timezone @@ -119,8 +119,10 @@ class Service(models.Model): Session = apps.get_model("analytics", "Session") Hit = apps.get_model("analytics", "Hit") + tz_now = timezone.now() + currently_online = Session.objects.filter( - service=self, last_seen__gt=timezone.now() - timezone.timedelta(seconds=10) + service=self, last_seen__gt=tz_now - timezone.timedelta(seconds=10) ).count() sessions = Session.objects.filter( @@ -202,17 +204,32 @@ class Service(models.Model): if session_count == 0: avg_session_duration = None - session_chart_data = { - k["date"]: k["count"] - for k in sessions.annotate(date=TruncDate("start_time")) - .values("date") - .annotate(count=models.Count("uuid")) - .order_by("date") - } - for day_offset in range((end_time - start_time).days + 1): - day = (start_time + timezone.timedelta(days=day_offset)).date() - if day not in session_chart_data: - session_chart_data[day] = 0 + if end_time.day == start_time.day: + session_chart_tooltip_format = "MM/dd HH:mm" + session_chart_data = { + k["hour"]: k["count"] + for k in sessions.annotate(hour=TruncHour("start_time")) + .values("hour") + .annotate(count=models.Count("uuid")) + .order_by("hour") + } + for hour_offset in range(int((end_time - start_time).seconds / 3600) + 1): + hour = (start_time + timezone.timedelta(hours=hour_offset)) + if hour not in session_chart_data: + session_chart_data[hour] = 0 if hour < tz_now else None + else: + session_chart_tooltip_format = "MMM d" + session_chart_data = { + k["date"]: k["count"] + for k in sessions.annotate(date=TruncDate("start_time")) + .values("date") + .annotate(count=models.Count("uuid")) + .order_by("date") + } + for day_offset in range((end_time - start_time).days + 1): + day = (start_time + timezone.timedelta(days=day_offset)).date() + if day not in session_chart_data: + session_chart_data[day] = 0 if day < tz_now.date() else None return { "currently_online": currently_online, @@ -240,6 +257,7 @@ class Service(models.Model): ) ] ), + "session_chart_tooltip_format": session_chart_tooltip_format, "online": True, } diff --git a/shynet/dashboard/templates/dashboard/includes/service_overview.html b/shynet/dashboard/templates/dashboard/includes/service_overview.html index 1996ddb..a966f55 100644 --- a/shynet/dashboard/templates/dashboard/includes/service_overview.html +++ b/shynet/dashboard/templates/dashboard/includes/service_overview.html @@ -51,7 +51,7 @@
- {% include 'dashboard/includes/time_chart.html' with data=stats.session_chart_data sparkline=True height=100 name=object.uuid %} + {% include 'dashboard/includes/time_chart.html' with data=stats.session_chart_data sparkline=True height=100 name=object.uuid tooltip_format=stats.session_chart_tooltip_format %}
{% endwith %} \ No newline at end of file diff --git a/shynet/dashboard/templates/dashboard/includes/time_chart.html b/shynet/dashboard/templates/dashboard/includes/time_chart.html index 61e50ec..9254a0e 100644 --- a/shynet/dashboard/templates/dashboard/includes/time_chart.html +++ b/shynet/dashboard/templates/dashboard/includes/time_chart.html @@ -6,6 +6,9 @@ }, tooltip: { shared: false, + x: { + format: '{{tooltip_format|default:"MMM d"}}', + }, }, colors: ["#805AD5"], chart: { @@ -63,6 +66,9 @@ }, xaxis: { type: "datetime", + labels: { + datetimeUTC: false + }, }, stroke: { width: 1.5, diff --git a/shynet/dashboard/templates/dashboard/pages/service.html b/shynet/dashboard/templates/dashboard/pages/service.html index 8a0dec0..c873e00 100644 --- a/shynet/dashboard/templates/dashboard/pages/service.html +++ b/shynet/dashboard/templates/dashboard/pages/service.html @@ -86,7 +86,7 @@ {% endwith %}
- {% include 'dashboard/includes/time_chart.html' with data=stats.session_chart_data %} + {% include 'dashboard/includes/time_chart.html' with data=stats.session_chart_data tooltip_format=stats.session_chart_tooltip_format %}
From c2daf3a5a5e45ff4aa0c48bd6744edaded6d0baf Mon Sep 17 00:00:00 2001 From: CasperVerswijvelt Date: Tue, 27 Apr 2021 21:58:07 +0200 Subject: [PATCH 2/5] Show hourly chart starting from ranges of 3 days and less --- shynet/core/models.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/shynet/core/models.py b/shynet/core/models.py index de15a65..302e6fd 100644 --- a/shynet/core/models.py +++ b/shynet/core/models.py @@ -204,7 +204,8 @@ class Service(models.Model): if session_count == 0: avg_session_duration = None - if end_time.day == start_time.day: + # Show hourly chart for date ranges of 3 days or less, otherwise daily chart + if end_time.day <= start_time.day + 2: session_chart_tooltip_format = "MM/dd HH:mm" session_chart_data = { k["hour"]: k["count"] From 78bea501a872de3ad870c24a198ad1d39a0e31af Mon Sep 17 00:00:00 2001 From: CasperVerswijvelt Date: Tue, 27 Apr 2021 23:39:58 +0200 Subject: [PATCH 3/5] Use timedelta instead of checking days difference which did not work correctly --- shynet/core/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shynet/core/models.py b/shynet/core/models.py index 302e6fd..7c7d40e 100644 --- a/shynet/core/models.py +++ b/shynet/core/models.py @@ -205,7 +205,7 @@ class Service(models.Model): avg_session_duration = None # Show hourly chart for date ranges of 3 days or less, otherwise daily chart - if end_time.day <= start_time.day + 2: + if (end_time - start_time).days <= 3: session_chart_tooltip_format = "MM/dd HH:mm" session_chart_data = { k["hour"]: k["count"] From 7c69b0bd815249c3fceee9532dd155b63a195991 Mon Sep 17 00:00:00 2001 From: CasperVerswijvelt Date: Wed, 28 Apr 2021 18:08:26 +0200 Subject: [PATCH 4/5] Fix hourly chart bug --- shynet/core/models.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/shynet/core/models.py b/shynet/core/models.py index 7c7d40e..2e69507 100644 --- a/shynet/core/models.py +++ b/shynet/core/models.py @@ -205,7 +205,7 @@ class Service(models.Model): avg_session_duration = None # Show hourly chart for date ranges of 3 days or less, otherwise daily chart - if (end_time - start_time).days <= 3: + if (end_time - start_time).days < 3: session_chart_tooltip_format = "MM/dd HH:mm" session_chart_data = { k["hour"]: k["count"] @@ -214,10 +214,10 @@ class Service(models.Model): .annotate(count=models.Count("uuid")) .order_by("hour") } - for hour_offset in range(int((end_time - start_time).seconds / 3600) + 1): + for hour_offset in range(int((end_time - start_time).total_seconds() / 3600) + 1): hour = (start_time + timezone.timedelta(hours=hour_offset)) if hour not in session_chart_data: - session_chart_data[hour] = 0 if hour < tz_now else None + session_chart_data[hour] = 0 if hour <= tz_now else None else: session_chart_tooltip_format = "MMM d" session_chart_data = { @@ -230,7 +230,7 @@ class Service(models.Model): for day_offset in range((end_time - start_time).days + 1): day = (start_time + timezone.timedelta(days=day_offset)).date() if day not in session_chart_data: - session_chart_data[day] = 0 if day < tz_now.date() else None + session_chart_data[day] = 0 if day <= tz_now.date() else None return { "currently_online": currently_online, From 4cd0c4735dc93f0751136edf31375a6f3546651c Mon Sep 17 00:00:00 2001 From: CasperVerswijvelt Date: Sat, 1 May 2021 22:00:12 +0200 Subject: [PATCH 5/5] Add click handler for going from daily to hourly chart view by clicking chart at specific date --- shynet/core/models.py | 3 +++ .../templates/dashboard/includes/service_overview.html | 2 +- .../templates/dashboard/includes/time_chart.html | 8 ++++++++ shynet/dashboard/templates/dashboard/pages/service.html | 2 +- 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/shynet/core/models.py b/shynet/core/models.py index 2e69507..9535341 100644 --- a/shynet/core/models.py +++ b/shynet/core/models.py @@ -207,6 +207,7 @@ class Service(models.Model): # Show hourly chart for date ranges of 3 days or less, otherwise daily chart if (end_time - start_time).days < 3: session_chart_tooltip_format = "MM/dd HH:mm" + session_chart_granularity = "hourly" session_chart_data = { k["hour"]: k["count"] for k in sessions.annotate(hour=TruncHour("start_time")) @@ -220,6 +221,7 @@ class Service(models.Model): session_chart_data[hour] = 0 if hour <= tz_now else None else: session_chart_tooltip_format = "MMM d" + session_chart_granularity = "daily" session_chart_data = { k["date"]: k["count"] for k in sessions.annotate(date=TruncDate("start_time")) @@ -259,6 +261,7 @@ class Service(models.Model): ] ), "session_chart_tooltip_format": session_chart_tooltip_format, + "session_chart_granularity": session_chart_granularity, "online": True, } diff --git a/shynet/dashboard/templates/dashboard/includes/service_overview.html b/shynet/dashboard/templates/dashboard/includes/service_overview.html index a966f55..afbb116 100644 --- a/shynet/dashboard/templates/dashboard/includes/service_overview.html +++ b/shynet/dashboard/templates/dashboard/includes/service_overview.html @@ -51,7 +51,7 @@

- {% include 'dashboard/includes/time_chart.html' with data=stats.session_chart_data sparkline=True height=100 name=object.uuid tooltip_format=stats.session_chart_tooltip_format %} + {% include 'dashboard/includes/time_chart.html' with data=stats.session_chart_data sparkline=True height=100 name=object.uuid tooltip_format=stats.session_chart_tooltip_format granularity=stats.session_chart_granularity %}
{% endwith %} \ No newline at end of file diff --git a/shynet/dashboard/templates/dashboard/includes/time_chart.html b/shynet/dashboard/templates/dashboard/includes/time_chart.html index 9254a0e..22542a9 100644 --- a/shynet/dashboard/templates/dashboard/includes/time_chart.html +++ b/shynet/dashboard/templates/dashboard/includes/time_chart.html @@ -37,6 +37,14 @@ stops: [0, 75, 100] }, }, + {% if granularity == "daily" and click_zoom %} + events: { + markerClick: function(event, chartContext, { seriesIndex, dataPointIndex, w: {config}}) { + const day = config.series[seriesIndex].data[dataPointIndex].x + window.location.href = `?startDate=${day}&endDate=${day}` + }, + }, + {% endif %} }, grid: { padding: { diff --git a/shynet/dashboard/templates/dashboard/pages/service.html b/shynet/dashboard/templates/dashboard/pages/service.html index c873e00..7747af5 100644 --- a/shynet/dashboard/templates/dashboard/pages/service.html +++ b/shynet/dashboard/templates/dashboard/pages/service.html @@ -86,7 +86,7 @@ {% endwith %}
- {% include 'dashboard/includes/time_chart.html' with data=stats.session_chart_data tooltip_format=stats.session_chart_tooltip_format %} + {% include 'dashboard/includes/time_chart.html' with data=stats.session_chart_data tooltip_format=stats.session_chart_tooltip_format granularity=stats.session_chart_granularity click_zoom=True %}