Add hits to chart data (#141)
* Add hits to chart data * Hide legend Co-authored-by: R. Miles McCain <github@sendmiles.email>
This commit is contained in:
parent
ab44ba8318
commit
83b20643d2
@ -198,6 +198,36 @@ class Service(models.Model):
|
||||
|
||||
avg_hits_per_session = hit_count / session_count if session_count > 0 else None
|
||||
|
||||
avg_session_duration = self._get_avg_session_duration(sessions, session_count)
|
||||
|
||||
chart_data, chart_tooltip_format, chart_granularity = self._get_chart_data(
|
||||
sessions, hits, start_time, end_time, tz_now
|
||||
)
|
||||
return {
|
||||
"currently_online": currently_online,
|
||||
"session_count": session_count,
|
||||
"hit_count": hit_count,
|
||||
"has_hits": has_hits,
|
||||
"bounce_rate_pct": bounce_count * 100 / session_count
|
||||
if session_count > 0
|
||||
else None,
|
||||
"avg_session_duration": avg_session_duration,
|
||||
"avg_load_time": avg_load_time,
|
||||
"avg_hits_per_session": avg_hits_per_session,
|
||||
"locations": locations,
|
||||
"referrers": referrers,
|
||||
"countries": countries,
|
||||
"operating_systems": operating_systems,
|
||||
"browsers": browsers,
|
||||
"devices": devices,
|
||||
"device_types": device_types,
|
||||
"chart_data": chart_data,
|
||||
"chart_tooltip_format": chart_tooltip_format,
|
||||
"chart_granularity": chart_granularity,
|
||||
"online": True,
|
||||
}
|
||||
|
||||
def _get_avg_session_duration(self, sessions, session_count):
|
||||
try:
|
||||
avg_session_duration = sessions.annotate(
|
||||
duration=models.F("last_seen") - models.F("start_time")
|
||||
@ -212,68 +242,72 @@ class Service(models.Model):
|
||||
if session_count == 0:
|
||||
avg_session_duration = None
|
||||
|
||||
return avg_session_duration
|
||||
|
||||
def _get_chart_data(self, sessions, hits, start_time, end_time, tz_now):
|
||||
# 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"))
|
||||
chart_tooltip_format = "MM/dd HH:mm"
|
||||
chart_granularity = "hourly"
|
||||
sessions_per_hour = (
|
||||
sessions.annotate(hour=TruncHour("start_time"))
|
||||
.values("hour")
|
||||
.annotate(count=models.Count("uuid"))
|
||||
.order_by("hour")
|
||||
)
|
||||
chart_data = {
|
||||
k["hour"]: {"sessions": k["count"]} for k in sessions_per_hour
|
||||
}
|
||||
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
|
||||
hits_per_hour = (
|
||||
hits.annotate(hour=TruncHour("start_time"))
|
||||
.values("hour")
|
||||
.annotate(count=models.Count("id"))
|
||||
.order_by("hour")
|
||||
)
|
||||
for k in hits_per_hour:
|
||||
if k["hour"] not in chart_data:
|
||||
chart_data[k["hour"]] = {"hits": k["count"], "sessions": 0}
|
||||
else:
|
||||
chart_data[k["hour"]]["hits"] = k["count"]
|
||||
|
||||
hours_range = range(int((end_time - start_time).total_seconds() / 3600) + 1)
|
||||
for hour_offset in hours_range:
|
||||
hour = start_time + timezone.timedelta(hours=hour_offset)
|
||||
if hour not in chart_data and hour <= tz_now:
|
||||
chart_data[hour] = {"sessions": 0, "hits": 0}
|
||||
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"))
|
||||
chart_tooltip_format = "MMM d"
|
||||
chart_granularity = "daily"
|
||||
sessions_per_day = (
|
||||
sessions.annotate(date=TruncDate("start_time"))
|
||||
.values("date")
|
||||
.annotate(count=models.Count("uuid"))
|
||||
.order_by("date")
|
||||
}
|
||||
)
|
||||
chart_data = {k["date"]: {"sessions": k["count"]} for k in sessions_per_day}
|
||||
hits_per_day = (
|
||||
hits.annotate(date=TruncDate("start_time"))
|
||||
.values("date")
|
||||
.annotate(count=models.Count("id"))
|
||||
.order_by("date")
|
||||
)
|
||||
for k in hits_per_day:
|
||||
chart_data[k["date"]]["hits"] = k["count"]
|
||||
|
||||
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
|
||||
if day not in chart_data and day <= tz_now.date():
|
||||
chart_data[day] = {"sessions": 0, "hits": 0}
|
||||
|
||||
return {
|
||||
"currently_online": currently_online,
|
||||
"session_count": session_count,
|
||||
"hit_count": hit_count,
|
||||
"has_hits": has_hits,
|
||||
"avg_hits_per_session": hit_count / (max(session_count, 1)),
|
||||
"bounce_rate_pct": bounce_count * 100 / session_count
|
||||
if session_count > 0
|
||||
else None,
|
||||
"avg_session_duration": avg_session_duration,
|
||||
"avg_load_time": avg_load_time,
|
||||
"avg_hits_per_session": avg_hits_per_session,
|
||||
"locations": locations,
|
||||
"referrers": referrers,
|
||||
"countries": countries,
|
||||
"operating_systems": operating_systems,
|
||||
"browsers": browsers,
|
||||
"devices": devices,
|
||||
"device_types": device_types,
|
||||
"session_chart_data": json.dumps(
|
||||
[
|
||||
{"x": str(key), "y": value}
|
||||
for key, value in sorted(
|
||||
session_chart_data.items(), key=lambda k: k[0]
|
||||
)
|
||||
]
|
||||
),
|
||||
"session_chart_tooltip_format": session_chart_tooltip_format,
|
||||
"session_chart_granularity": session_chart_granularity,
|
||||
"online": True,
|
||||
chart_data = sorted(chart_data.items(), key=lambda k: k[0])
|
||||
chart_data = {
|
||||
'sessions': [v['sessions'] for k, v in chart_data],
|
||||
'hits': [v['hits'] for k, v in chart_data],
|
||||
'labels': [str(k) for k, v in chart_data],
|
||||
}
|
||||
|
||||
return chart_data, chart_tooltip_format, chart_granularity
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse(
|
||||
"dashboard:service",
|
||||
|
@ -51,7 +51,7 @@
|
||||
</div>
|
||||
<hr class="sep h-4">
|
||||
<div style="bottom: -1px;">
|
||||
{% 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 %}
|
||||
{% include 'dashboard/includes/time_chart.html' with data=stats.chart_data sparkline=True height=100 name=object.uuid tooltip_format=stats.chart_tooltip_format granularity=stats.chart_granularity %}
|
||||
</div>
|
||||
{% endwith %}
|
||||
</a>
|
||||
</a>
|
||||
|
@ -5,12 +5,14 @@
|
||||
enabled: false
|
||||
},
|
||||
tooltip: {
|
||||
shared: false,
|
||||
shared: true,
|
||||
x: {
|
||||
format: '{{tooltip_format|default:"MMM d"}}',
|
||||
},
|
||||
},
|
||||
colors: ["#805AD5"],
|
||||
legend: {
|
||||
show: false,
|
||||
},
|
||||
chart: {
|
||||
zoom: {
|
||||
enabled: false,
|
||||
@ -18,7 +20,7 @@
|
||||
toolbar: {
|
||||
show: false,
|
||||
},
|
||||
type: 'area',
|
||||
type: 'line',
|
||||
height: {{height|default:"200"}},
|
||||
offsetY: -1,
|
||||
animations: {
|
||||
@ -27,20 +29,10 @@
|
||||
sparkline: {
|
||||
enabled: {% if sparkline %}true{% else %}false{% endif %},
|
||||
},
|
||||
fill: {
|
||||
type: 'gradient',
|
||||
gradient: {
|
||||
shadeIntensity: 1,
|
||||
inverseColors: false,
|
||||
opacityFrom: 0.8,
|
||||
opacityTo: 0,
|
||||
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
|
||||
const day = config.labels[dataPointIndex]
|
||||
window.location.href = `?startDate=${day}&endDate=${day}`
|
||||
},
|
||||
},
|
||||
@ -79,13 +71,22 @@
|
||||
},
|
||||
},
|
||||
stroke: {
|
||||
width: 1.5,
|
||||
width: 2,
|
||||
curve: 'smooth',
|
||||
},
|
||||
series: [{
|
||||
name: "{{unit|default:'Sessions'}}",
|
||||
data: {{data|safe}}
|
||||
}]
|
||||
name: "Hits",
|
||||
type: 'area',
|
||||
color: "#ddd6fe",
|
||||
data: {{data.hits|safe}}
|
||||
}, {
|
||||
name: "Sessions",
|
||||
type: 'line',
|
||||
color: "#805AD5",
|
||||
data: {{data.sessions|safe}}
|
||||
}],
|
||||
labels: {{data.labels|safe}}
|
||||
};
|
||||
var triggerMatchesChart = new ApexCharts(document.querySelector("#chart{{name|default:'Main'}}"), triggerMatchesChartOptions);
|
||||
triggerMatchesChart.render();
|
||||
</script>
|
||||
</script>
|
||||
|
@ -94,7 +94,7 @@
|
||||
{% endwith %}
|
||||
</div>
|
||||
<div class="card overflow-visible ~neutral !low py-0 mb-6">
|
||||
{% 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 %}
|
||||
{% include 'dashboard/includes/time_chart.html' with data=stats.chart_data tooltip_format=stats.chart_tooltip_format granularity=stats.chart_granularity click_zoom=True %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-6">
|
||||
|
Loading…
Reference in New Issue
Block a user