Fakultas Ilmu Komputer UI

Commit 5a6b8def authored by I Gusti Putu Agastya Indrayana's avatar I Gusti Putu Agastya Indrayana
Browse files

[GREEN] Progress on statistics chart.

parent 35af4181
Pipeline #49682 passed with stage
in 3 minutes and 45 seconds
......@@ -7,6 +7,7 @@ LONG_MONTH = ['', 'Januari', 'Februari', 'Maret', 'April', 'Mei', 'Juni',
BASE_PERIODE = [
("", "Pilih"),
('-----', (
("LAST_WEEK", "7 Hari Terakhir"),
("LAST_MONTH", "30 Hari Terakhir"),
......
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit
from crispy_forms.layout import Layout, Submit, Row, Column, Reset, ButtonHolder, Button
from crispy_forms.bootstrap import InlineCheckboxes
from django import forms
from administration.choices import genereatePeriodeChoices
......@@ -9,6 +9,12 @@ from app.models import Category
from authentication.models import User
def generate_category_choices():
categories = Category.objects.all()
category_choices = [(i.id, i.name) for i in categories]
return category_choices
class DateInput(forms.DateInput):
input_type = 'date'
......@@ -80,9 +86,14 @@ class RegistrasiAdminForm(forms.ModelForm):
class PeriodForm(forms.Form):
period = forms.ChoiceField(choices=genereatePeriodeChoices(), label="Periode", required=False)
start_date = forms.DateField(widget=DateInput, label="Waktu mulai", required=False)
end_date = forms.DateField(widget=DateInput, label="Waktu selesai", required=False)
period = forms.ChoiceField(
choices=genereatePeriodeChoices(), label="Periode", required=False)
start_date = forms.DateField(
widget=DateInput, label="Waktu mulai", required=False)
end_date = forms.DateField(
widget=DateInput, label="Waktu selesai", required=False)
categories = forms.MultipleChoiceField(
label="Kategori", required=False, choices=generate_category_choices)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
......@@ -91,8 +102,34 @@ class PeriodForm(forms.Form):
field.widget.attrs['class'] = 'form-control'
self.helper = FormHelper()
self.helper.attrs["name"] = "filter-form"
self.helper.form_method = 'get'
self.helper.add_input(Submit('submit', 'Filter'))
# def get_date(self):
self.helper.layout = Layout(
Row(
Column('period', css_class='form-group col-md-4 mb-0'),
Column('start_date', css_class='form-group col-md-4 mb-0'),
Column('end_date', css_class='form-group col-md-4 mb-0'),
css_class='form-row'
),
InlineCheckboxes('categories'),
Row(
ButtonHolder(Submit('submit', 'Filter')),
ButtonHolder(Button('reset_form', 'Hapus filter'), css_class ="btn-warning")
)
)
def clean(self):
cleaned_data = super().clean()
start_date = cleaned_data.get('start_date')
end_date = cleaned_data.get('end_date')
if start_date is not None and end_date is None:
self.add_error("end_date",
"masukan waktu selesai")
if start_date is None and end_date is not None:
self.add_error("start_date",
"masukan waktu mulai")
if start_date is not None and end_date is not None:
if start_date > end_date:
self.add_error("end_date",
"waktu selesai sebelum waktu mulai")
......@@ -2,48 +2,4 @@
// var canvas = document.getElementById("chart1");
// var heightRatio = 1.5;
// canvas.height = canvas.width * heightRatio;
// });
var ctx = document.getElementById("chart1").getContext("2d");
var myChart = new Chart(ctx, {
type: "bar",
responsive: true,
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [
{
label: "# of Votes",
data: [12, 19, 3, 5, 2, 3],
backgroundColor: [
"rgba(255, 99, 132, 0.2)",
"rgba(54, 162, 235, 0.2)",
"rgba(255, 206, 86, 0.2)",
"rgba(75, 192, 192, 0.2)",
"rgba(153, 102, 255, 0.2)",
"rgba(255, 159, 64, 0.2)",
],
borderColor: [
"rgba(255, 99, 132, 1)",
"rgba(54, 162, 235, 1)",
"rgba(255, 206, 86, 1)",
"rgba(75, 192, 192, 1)",
"rgba(153, 102, 255, 1)",
"rgba(255, 159, 64, 1)",
],
borderWidth: 1,
},
],
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
yAxes: [
{
ticks: {
beginAtZero: true,
},
},
],
},
},
});
// });
\ No newline at end of file
from django.urls import path
from administration.views import VerificationView, DetailVerificationView, VerificationSettingView, CategorySettingView, KelolaKontributorView, ProfileContributorAdminView, ProfileAdminAdministrationView, KelolaAdminView, RegistrasiAdminView, EditVerificationView, delete_admin, delete_contributor, delete_verification, StatisticsView, StatisticApiView
from administration.views import VerificationView, DetailVerificationView, VerificationSettingView, CategorySettingView, KelolaKontributorView, ProfileContributorAdminView, ProfileAdminAdministrationView, KelolaAdminView, RegistrasiAdminView, EditVerificationView, delete_admin, delete_contributor, delete_verification, StatisticsView, StatisticApiView, EditCategoryView, delete_category
app_name = "administration"
......
import random
import string
from django.utils import timezone, lorem_ipsum
from dateutil.relativedelta import relativedelta
def id_generator(size=6, chars=string.ascii_uppercase + string.digits): # pragma: no cover
def generate_time_step(s, e, step="DAILY"):
result = []
time = s.replace(hour=0, minute=0, second=0, microsecond=0)
while time < e:
result.append(time)
if step == "DAILY":
time = time + relativedelta(days=1)
result.append(e)
return result
def id_generator(size=6, chars=string.ascii_uppercase + string.digits): # pragma: no cover
return ''.join(random.choice(chars) for _ in range(size))
import json
from datetime import datetime, date
from django.core.exceptions import PermissionDenied
from django.contrib.auth.hashers import make_password
......@@ -6,13 +7,63 @@ from django.http import HttpResponseRedirect, JsonResponse
from django.shortcuts import get_object_or_404, render
from django.views.generic import TemplateView, View
from django.contrib import messages
from django.utils import timezone, lorem_ipsum
from dateutil.relativedelta import relativedelta
from administration.models import VerificationReport, VerificationSetting
from administration.forms import CategoryForm, VerificationSettingForm, RegistrasiAdminForm, PeriodForm
from app.models import Category, Materi
from app.models import Category, Materi, ViewStatistics, DownloadStatistics, Comment, Like, getRandomColor
from authentication.models import User
from administration.utils import generate_time_step
def get_start_end_date(period):
if period == 'ALL_TIME':
return (None, None)
elif period.split("_")[0] == "LAST":
end = timezone.now()
delta = 7
if period.split("_")[1] == "WEEK":
delta = 7
if period.split("_")[1] == "MONTH":
delta = 30
if period.split("_")[1] == "QUARTER":
delta = 90
if period.split("_")[1] == "YEAR":
delta = 365
start = end - relativedelta(days=delta)
return (start, end)
elif period.split("_")[0] == "CURRENT":
start = timezone.now()
if period.split("_")[1] == "MONTH":
start = start.replace(day=1, hour=0, minute=0,
second=0, microsecond=0)
end = start + relativedelta(months=1)
return (start, end)
elif period.split("_")[1] == "YEAR":
start = start.replace(month=1, day=1, hour=0,
minute=0, second=0, microsecond=0)
end = start + relativedelta(years=1)
return (start, end)
elif period.split("_")[0] == "MINUS":
start = timezone.now()
delta = int(period.split("_")[1])
if period.split("_")[2] == "MONTH":
start = start.replace(day=1, hour=0, minute=0,
second=0, microsecond=0)
start = start - relativedelta(months=delta)
end = start + relativedelta(months=1)
return (start, end)
elif period.split("_")[2] == "YEAR":
start = start.replace(month=1, day=1, hour=0,
minute=0, second=0, microsecond=0)
start = start - relativedelta(years=delta)
end = start + relativedelta(years=1)
return (start, end)
else:
return (None, None)
# Create your views here.
class VerificationView(TemplateView):
template_name = "verif.html"
......@@ -216,15 +267,120 @@ class ProfileContributorAdminView(TemplateView):
class StatisticsView(TemplateView):
template_name = "administration/data_statistik.html"
def dispatch(self, request, *args, **kwargs):
if not request.user.is_authenticated:
raise PermissionDenied(request)
return super(StatisticsView, self).dispatch(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super(StatisticsView, self).get_context_data(**kwargs)
context["page_title"] = "Statistik"
context["periodForm"] = PeriodForm(self.request.GET)
return context
def get_filter_set(self, **kwargs):
filter_set = {}
form = PeriodForm(self.request.GET)
DEFAULT_PERIOD = "LAST_MONTH"
if form.is_valid():
form_data = form.cleaned_data
if len(form_data["categories"]) == 0:
form_data["categories"] = None
if form_data["period"] == "":
form_data["period"] = DEFAULT_PERIOD
# check if using custom date range
if form_data["start_date"] is not None and form_data["end_date"] is not None:
start = timezone.make_aware(datetime.combine(
form_data["start_date"], datetime.min.time()))
end = timezone.make_aware(datetime.combine(
form_data["end_date"], datetime.min.time()))
elif form_data["period"] is not None:
start, end = get_start_end_date(form_data["period"])
else:
start, end = get_start_end_date(DEFAULT_PERIOD)
filter_set["start"] = start
filter_set["end"] = end
filter_set["categories"] = form_data["categories"]
return filter_set
def get_query_set(self, object_statistic, **kwargs):
if self.request.user.is_admin:
return object_statistic.objects.filter(materi__status="APPROVE")
else:
return object_statistic.objects.filter(materi__status="APPROVE", materi__uploader=self.request.user.id)
def filter_qs(self, qs, filter_set):
if filter_set.get("categories", None) is not None:
qs = qs.filter(materi__categories__in=filter_set.get("categories"))
if filter_set.get("start") is not None and filter_set.get("end") is not None:
s = filter_set.get("start")
e = filter_set.get("end")
qs = qs.filter(timestamp__gte=s, timestamp__lt=e)
return qs.distinct()
# def generate_table_data(self, data_sets):
# table_data = {}
# counter = 1
# row_materi_table = []
# for item in data_sets:
# # return res
def generate_chart_data(self, start, end, data_sets):
chart_data = {
"charts": [],
"total": [],
"label": []
}
label = ["Dilihat", "Diunduh", "Komentar", "Disukai"]
colors = ["#4e73df", "#e74a3b", "#1cc88a", "#f6c23e"]
time_step = generate_time_step(start, end)
for i in time_step:
chart_data["label"].append(i.strftime("%d/%m/%Y"))
# generate view stat
for label, color, dataset in zip(label, colors, data_sets):
result = {
"label": label,
"backgroundColor": color,
"borderColor": color,
"borderWidth": 1
}
data = []
total = 0
s = 0
e = 1
while e < len(time_step):
todays = dataset.filter(
timestamp__gte=time_step[s], timestamp__lt=time_step[e]).count()
data.append(todays)
total += todays
s += 1
e += 1
result["data"] = data
chart_data["charts"].append(result)
chart_data["total"].append(total)
return chart_data
def get(self, request, *args, **kwargs):
context = self.get_context_data(**kwargs)
form = context["periodForm"]
filter_set = self.get_filter_set(**kwargs)
view_set = self.get_query_set(ViewStatistics, **kwargs)
view_set = self.filter_qs(view_set, filter_set)
download_set = self.get_query_set(DownloadStatistics, **kwargs)
download_set = self.filter_qs(download_set, filter_set)
like_set = self.get_query_set(Like, **kwargs)
like_set = self.filter_qs(like_set, filter_set)
comment_set = self.get_query_set(Comment, **kwargs)
comment_set = self.filter_qs(comment_set, filter_set)
data_sets = [view_set, download_set, like_set, comment_set]
chart_data = self.generate_chart_data(
filter_set["start"], filter_set["end"], data_sets)
context["chart_data"] = chart_data
return self.render_to_response(context=context)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment