Change lang stat page

This commit is contained in:
cuom1999 2022-09-22 17:33:14 -05:00
parent fa8c683439
commit fe5e7198ee
5 changed files with 90 additions and 112 deletions

View file

@ -886,27 +886,7 @@ urlpatterns = [
"^language/", "^language/",
include( include(
[ [
url("^$", stats.language, name="language_stats"), url("^$", stats.StatLanguage.as_view(), name="language_stats"),
url(
"^data/all/$",
stats.language_data,
name="language_stats_data_all",
),
url(
"^data/ac/$",
stats.ac_language_data,
name="language_stats_data_ac",
),
url(
"^data/status/$",
stats.status_data,
name="stats_data_status",
),
url(
"^data/ac_rate/$",
stats.ac_rate,
name="language_stats_data_ac_rate",
),
] ]
), ),
), ),

View file

@ -1,5 +1,6 @@
from itertools import chain, repeat from itertools import chain, repeat
from operator import itemgetter from operator import itemgetter
import json
from django.conf import settings from django.conf import settings
from django.db.models import Case, Count, FloatField, IntegerField, Value, When from django.db.models import Case, Count, FloatField, IntegerField, Value, When
@ -7,6 +8,9 @@ from django.db.models.expressions import CombinedExpression
from django.http import JsonResponse from django.http import JsonResponse
from django.shortcuts import render from django.shortcuts import render
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from django.http import Http404
from django.views.generic import TemplateView
from django.utils.safestring import mark_safe
from judge.models import Language, Submission from judge.models import Language, Submission
from judge.utils.stats import ( from judge.utils.stats import (
@ -17,18 +21,25 @@ from judge.utils.stats import (
) )
ac_count = Count( class StatViewBase(TemplateView):
def get(self, request, *args, **kwargs):
if not request.user.is_superuser:
raise Http404
return super().get(request, *args, **kwargs)
class StatLanguage(StatViewBase):
template_name = "stats/language.html"
ac_count = Count(
Case(When(submission__result="AC", then=Value(1)), output_field=IntegerField()) Case(When(submission__result="AC", then=Value(1)), output_field=IntegerField())
) )
def repeat_chain(iterable):
def repeat_chain(iterable):
return chain.from_iterable(repeat(iterable)) return chain.from_iterable(repeat(iterable))
def language_data(
def language_data( self, language_count=Language.objects.annotate(count=Count("submission"))
request, language_count=Language.objects.annotate(count=Count("submission")) ):
):
languages = ( languages = (
language_count.filter(count__gt=0) language_count.filter(count__gt=0)
.values("key", "name", "count") .values("key", "name", "count")
@ -37,8 +48,7 @@ def language_data(
num_languages = min(len(languages), settings.DMOJ_STATS_LANGUAGE_THRESHOLD) num_languages = min(len(languages), settings.DMOJ_STATS_LANGUAGE_THRESHOLD)
other_count = sum(map(itemgetter("count"), languages[num_languages:])) other_count = sum(map(itemgetter("count"), languages[num_languages:]))
return JsonResponse( return {
{
"labels": list(map(itemgetter("name"), languages[:num_languages])) "labels": list(map(itemgetter("name"), languages[:num_languages]))
+ ["Other"], + ["Other"],
"datasets": [ "datasets": [
@ -50,16 +60,12 @@ def language_data(
+ [other_count], + [other_count],
}, },
], ],
}, }
safe=False,
)
def ac_language_data(self):
return self.language_data(Language.objects.annotate(count=self.ac_count))
def ac_language_data(request): def status_data(self, statuses=None):
return language_data(request, Language.objects.annotate(count=ac_count))
def status_data(request, statuses=None):
if not statuses: if not statuses:
statuses = ( statuses = (
Submission.objects.values("result") Submission.objects.values("result")
@ -75,12 +81,12 @@ def status_data(request, statuses=None):
count = status["count"] count = status["count"]
data.append((str(Submission.USER_DISPLAY_CODES[res]), count)) data.append((str(Submission.USER_DISPLAY_CODES[res]), count))
return JsonResponse(get_pie_chart(data), safe=False) return get_pie_chart(data)
def ac_rate(request): def ac_rate(self):
rate = CombinedExpression( rate = CombinedExpression(
ac_count / Count("submission"), "*", Value(100.0), output_field=FloatField() self.ac_count / Count("submission"), "*", Value(100.0), output_field=FloatField()
) )
data = ( data = (
Language.objects.annotate(total=Count("submission"), ac_rate=rate) Language.objects.annotate(total=Count("submission"), ac_rate=rate)
@ -88,15 +94,15 @@ def ac_rate(request):
.order_by("total") .order_by("total")
.values_list("name", "ac_rate") .values_list("name", "ac_rate")
) )
return JsonResponse(get_bar_chart(list(data))) return get_bar_chart(list(data))
def language(request): def get_context_data(self, **kwargs):
return render( context = super().get_context_data(**kwargs)
request, context["title"] = _("Language statistics")
"stats/language.html", context["tab"] = "language"
{ context["data_all"] = mark_safe(json.dumps(self.language_data()))
"title": _("Language statistics"), context["lang_ac"] = mark_safe(json.dumps(self.ac_language_data()))
"tab": "language", context["status_counts"] = mark_safe(json.dumps(self.status_data()))
}, context["ac_rate"] = mark_safe(json.dumps(self.ac_rate()))
) return context

View file

@ -6,13 +6,10 @@
{% endcompress %} {% endcompress %}
{% endblock %} {% endblock %}
{% block content_title %}{{ _('Statistics') }}{% endblock %} {% block content_title %}{% endblock %}
{% block title_ruler %}{% endblock %}
{% block body %} {% block body %}
<div class="tabs"> {% include "stats/tab.html" %}
<li{% if tab == 'language' %} class="active"{% endif %}>
<a href="{{ url('language_stats') }}">{{ _('Language') }}</a>
</li>
</div>
{% block chart_body %}{% endblock %} {% block chart_body %}{% endblock %}
{% endblock %} {% endblock %}

View file

@ -36,20 +36,10 @@
Chart.defaults.global.tooltipFontFamily = Chart.defaults.global.tooltipFontFamily =
Chart.defaults.global.tooltipTitleFontFamily = Chart.defaults.global.tooltipTitleFontFamily =
$('body').css('font-family'); $('body').css('font-family');
draw_pie_chart({{ data_all }}, $('#lang-all'));
function pie_chart(url, $chart) { draw_pie_chart({{ lang_ac }}, $('#lang-ac'));
$.getJSON(url, function (data) { draw_pie_chart({{ status_counts }}, $('#status-counts'));
draw_pie_chart(data, $chart); draw_bar_chart({{ ac_rate }}, $('#ac-rate'));
});
}
pie_chart('{{ url('language_stats_data_all') }}', $('#lang-all'));
pie_chart('{{ url('language_stats_data_ac') }}', $('#lang-ac'));
pie_chart('{{ url('stats_data_status') }}', $('#status-counts'));
$.getJSON('{{ url('language_stats_data_ac_rate') }}', function (data) {
draw_bar_chart(data, $('#ac-rate'));
});
}); });
</script> </script>
{% endblock %} {% endblock %}

5
templates/stats/tab.html Normal file
View file

@ -0,0 +1,5 @@
{% extends "tabs-base.html" %}
{% block tabs %}
{{ make_tab('language', 'fa-list', url('language_stats'), _('Language')) }}
{% endblock %}