mirror of
https://github.com/boostorg/website-v2.git
synced 2026-01-19 04:42:17 +00:00
@@ -8,7 +8,7 @@ from django.urls import path, reverse
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.shortcuts import redirect
|
||||
|
||||
from libraries.forms import CreateReportForm
|
||||
from libraries.forms import CreateReportForm, CreateReportFullForm
|
||||
from versions.tasks import import_all_library_versions
|
||||
from .models import (
|
||||
Category,
|
||||
@@ -139,40 +139,75 @@ class LibraryAdmin(admin.ModelAdmin):
|
||||
name="library_stat_detail",
|
||||
),
|
||||
path(
|
||||
"report-form/",
|
||||
self.admin_site.admin_view(self.report_form_view),
|
||||
name="library_report_form",
|
||||
"release-report-form/",
|
||||
self.admin_site.admin_view(self.release_report_form),
|
||||
name="release_report_form",
|
||||
),
|
||||
path(
|
||||
"report/",
|
||||
self.admin_site.admin_view(self.report_view),
|
||||
name="library_report",
|
||||
"release-report/",
|
||||
self.admin_site.admin_view(self.release_report_view),
|
||||
name="release_report",
|
||||
),
|
||||
path(
|
||||
"report-full-form/",
|
||||
self.admin_site.admin_view(self.report_form_full_view),
|
||||
name="library_report_full_form",
|
||||
),
|
||||
path(
|
||||
"report-full/",
|
||||
self.admin_site.admin_view(self.report_full_view),
|
||||
name="library_report_full",
|
||||
),
|
||||
]
|
||||
return my_urls + urls
|
||||
|
||||
def report_form_view(self, request):
|
||||
def release_report_form(self, request):
|
||||
form = CreateReportForm()
|
||||
context = {}
|
||||
if request.GET.get("version", None):
|
||||
if request.GET.get("submit", None):
|
||||
form = CreateReportForm(request.GET)
|
||||
if form.is_valid():
|
||||
context.update(form.get_stats())
|
||||
return redirect(
|
||||
reverse("admin:library_report") + f"?{request.GET.urlencode()}"
|
||||
reverse("admin:release_report") + f"?{request.GET.urlencode()}"
|
||||
)
|
||||
if not context:
|
||||
context["form"] = form
|
||||
return TemplateResponse(request, "admin/library_report_form.html", context)
|
||||
|
||||
def report_view(self, request):
|
||||
def release_report_view(self, request):
|
||||
form = CreateReportForm(request.GET)
|
||||
context = {"form": form}
|
||||
if form.is_valid():
|
||||
context.update(form.get_stats())
|
||||
else:
|
||||
return redirect("admin:library_report_form")
|
||||
return TemplateResponse(request, "admin/library_report_detail.html", context)
|
||||
return redirect("admin:release_report_form")
|
||||
return TemplateResponse(request, "admin/release_report_detail.html", context)
|
||||
|
||||
def report_form_full_view(self, request):
|
||||
form = CreateReportFullForm()
|
||||
context = {}
|
||||
if request.GET.get("submit", None):
|
||||
form = CreateReportFullForm(request.GET)
|
||||
if form.is_valid():
|
||||
context.update(form.get_stats())
|
||||
return redirect(
|
||||
reverse("admin:library_report_full") + f"?{request.GET.urlencode()}"
|
||||
)
|
||||
if not context:
|
||||
context["form"] = form
|
||||
return TemplateResponse(request, "admin/library_report_form.html", context)
|
||||
|
||||
def report_full_view(self, request):
|
||||
form = CreateReportFullForm(request.GET)
|
||||
context = {"form": form}
|
||||
if form.is_valid():
|
||||
context.update(form.get_stats())
|
||||
else:
|
||||
return redirect("admin:library_report_full_form")
|
||||
return TemplateResponse(
|
||||
request, "admin/library_report_full_detail.html", context
|
||||
)
|
||||
|
||||
def view_stats(self, instance):
|
||||
url = reverse("admin:library_stat_detail", kwargs={"pk": instance.pk})
|
||||
|
||||
@@ -22,19 +22,14 @@ class VersionSelectionForm(Form):
|
||||
)
|
||||
|
||||
|
||||
class CreateReportForm(Form):
|
||||
class CreateReportFullForm(Form):
|
||||
"""Form for creating a report over all releases."""
|
||||
|
||||
library_queryset = Library.objects.all().order_by("name")
|
||||
version = ModelChoiceField(
|
||||
queryset=Version.objects.active()
|
||||
.exclude(name__in=["develop", "master", "head"])
|
||||
.order_by("-name")
|
||||
)
|
||||
library_1 = ModelChoiceField(
|
||||
queryset=library_queryset,
|
||||
required=False,
|
||||
help_text=(
|
||||
"If none are selected, the top 5 for this release will be auto-selected."
|
||||
),
|
||||
help_text="If none are selected, the top 5 will be auto-selected.",
|
||||
)
|
||||
library_2 = ModelChoiceField(
|
||||
queryset=library_queryset,
|
||||
@@ -65,28 +60,14 @@ class CreateReportForm(Form):
|
||||
required=False,
|
||||
)
|
||||
|
||||
def _get_top_contributors_for_version(self):
|
||||
def _get_top_libraries(self):
|
||||
return (
|
||||
CommitAuthor.objects.filter(
|
||||
commit__library_version__version=self.cleaned_data["version"]
|
||||
)
|
||||
.annotate(commit_count=Count("commit"))
|
||||
.values("name", "avatar_url", "commit_count")
|
||||
.order_by("-commit_count")[:10]
|
||||
)
|
||||
|
||||
def _get_top_libraries_for_version(self):
|
||||
return (
|
||||
Library.objects.filter(
|
||||
library_version=LibraryVersion.objects.filter(
|
||||
library=OuterRef("id"), version=self.cleaned_data["version"]
|
||||
)[:1],
|
||||
)
|
||||
Library.objects.all()
|
||||
.annotate(commit_count=Count("library_version__commit"))
|
||||
.order_by("-commit_count")[:5]
|
||||
)
|
||||
|
||||
def _get_library_order(self, top_libraries_release):
|
||||
def _get_library_order(self, top_libraries):
|
||||
library_order = [
|
||||
x.id
|
||||
for x in [
|
||||
@@ -102,7 +83,7 @@ class CreateReportForm(Form):
|
||||
if x is not None
|
||||
]
|
||||
if not library_order:
|
||||
library_order = [x.id for x in top_libraries_release]
|
||||
library_order = [x.id for x in top_libraries]
|
||||
return library_order
|
||||
|
||||
def _get_library_full_counts(self, libraries, library_order):
|
||||
@@ -115,6 +96,99 @@ class CreateReportForm(Form):
|
||||
key=lambda x: library_order.index(x["id"]),
|
||||
)
|
||||
|
||||
def _get_top_contributors_overall(self):
|
||||
return (
|
||||
CommitAuthor.objects.all()
|
||||
.annotate(commit_count=Count("commit"))
|
||||
.values("name", "avatar_url", "commit_count", "github_profile_url")
|
||||
.order_by("-commit_count")[:10]
|
||||
)
|
||||
|
||||
def _get_top_contributors_for_library(self, library_order):
|
||||
top_contributors_library = []
|
||||
for library_id in library_order:
|
||||
top_contributors_library.append(
|
||||
CommitAuthor.objects.filter(
|
||||
commit__library_version__library_id=library_id
|
||||
)
|
||||
.annotate(commit_count=Count("commit"))
|
||||
.values(
|
||||
"name",
|
||||
"avatar_url",
|
||||
"github_profile_url",
|
||||
"commit_count",
|
||||
"commit__library_version__library_id",
|
||||
)
|
||||
.order_by("-commit_count")[:10]
|
||||
)
|
||||
return top_contributors_library
|
||||
|
||||
def get_stats(self):
|
||||
commit_count = Commit.objects.count()
|
||||
|
||||
top_libraries = self._get_top_libraries()
|
||||
library_order = self._get_library_order(top_libraries)
|
||||
libraries = Library.objects.filter(id__in=library_order)
|
||||
library_data = [
|
||||
{
|
||||
"library": x[0],
|
||||
"full_count": x[1],
|
||||
"top_contributors": x[2],
|
||||
}
|
||||
for x in zip(
|
||||
sorted(list(libraries), key=lambda x: library_order.index(x.id)),
|
||||
self._get_library_full_counts(libraries, library_order),
|
||||
self._get_top_contributors_for_library(library_order),
|
||||
)
|
||||
]
|
||||
top_contributors = self._get_top_contributors_overall()
|
||||
return {
|
||||
"commit_count": commit_count,
|
||||
"top_contributors": top_contributors,
|
||||
"library_data": library_data,
|
||||
"top_libraries": top_libraries,
|
||||
"library_count": Library.objects.all().count(),
|
||||
}
|
||||
|
||||
|
||||
class CreateReportForm(CreateReportFullForm):
|
||||
"""Form for creating a report for a specific release."""
|
||||
|
||||
version = ModelChoiceField(
|
||||
queryset=Version.objects.active()
|
||||
.exclude(name__in=["develop", "master", "head"])
|
||||
.order_by("-name")
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.fields[
|
||||
"library_1"
|
||||
].help_text = (
|
||||
"If none are selected, the top 5 for this release will be auto-selected."
|
||||
)
|
||||
|
||||
def _get_top_contributors_for_version(self):
|
||||
return (
|
||||
CommitAuthor.objects.filter(
|
||||
commit__library_version__version=self.cleaned_data["version"]
|
||||
)
|
||||
.annotate(commit_count=Count("commit"))
|
||||
.values("name", "avatar_url", "commit_count", "github_profile_url")
|
||||
.order_by("-commit_count")[:10]
|
||||
)
|
||||
|
||||
def _get_top_libraries_for_version(self):
|
||||
return (
|
||||
Library.objects.filter(
|
||||
library_version=LibraryVersion.objects.filter(
|
||||
library=OuterRef("id"), version=self.cleaned_data["version"]
|
||||
)[:1],
|
||||
)
|
||||
.annotate(commit_count=Count("library_version__commit"))
|
||||
.order_by("-commit_count")[:5]
|
||||
)
|
||||
|
||||
def _get_library_version_counts(self, libraries, library_order):
|
||||
return sorted(
|
||||
list(
|
||||
@@ -173,6 +247,7 @@ class CreateReportForm(Form):
|
||||
.values(
|
||||
"name",
|
||||
"avatar_url",
|
||||
"github_profile_url",
|
||||
"commit_count",
|
||||
"commit__library_version__library_id",
|
||||
)
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
{% block object-tools-items %}
|
||||
{{ block.super }}
|
||||
<li><a href="{% url 'admin:update_libraries' %}" class="addlink">{% trans "Update Library Data" %}</a></li>
|
||||
<li><a href="{% url 'admin:library_report_form' %}" class="addlink">{% trans "Get Release Report" %}</a></li>
|
||||
<li><a href="{% url 'admin:release_report_form' %}" class="addlink">{% trans "Get Release Report" %}</a></li>
|
||||
<li><a href="{% url 'admin:library_report_full_form' %}" class="addlink">{% trans "Get Library Report" %}</a></li>
|
||||
{% endblock %}
|
||||
</ul>
|
||||
{% endblock %}
|
||||
|
||||
54
templates/admin/library_report_base.html
Normal file
54
templates/admin/library_report_base.html
Normal file
@@ -0,0 +1,54 @@
|
||||
{% load static humanize avatar_tags %}
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>
|
||||
{% block title %}Boost{% endblock %}
|
||||
</title>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="description" content="{% block description %}{% endblock %}" />
|
||||
<meta name="keywords" content="{% block keywords %}{% endblock %}" />
|
||||
<meta name="author"
|
||||
content="{% block author %}Boost C++ Libraries{% endblock %}" />
|
||||
<link rel="shortcut icon"
|
||||
href="{% static 'img/Boost_Symbol_Transparent.svg' %}"
|
||||
type="image/x-icon" />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans:ital,wght@0,100..900;1,100..900&display=swap"
|
||||
rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+Mono&display=swap"
|
||||
rel="stylesheet">
|
||||
<link rel="stylesheet"
|
||||
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
|
||||
<link rel="stylesheet"
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.css" />
|
||||
<!-- TODO bring this local if we like it -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
|
||||
<script src="{% static 'js/boost-gecko/main.062e4862.js' %}" defer></script>
|
||||
{% block extra_head %}
|
||||
<link href="{% static 'css/styles.css' %}" rel="stylesheet" />
|
||||
{% endblock %}
|
||||
{% block css %}
|
||||
<style>
|
||||
@page {
|
||||
margin: 0;
|
||||
size: 300mm 180mm;
|
||||
}
|
||||
|
||||
.pdf-page {
|
||||
padding: 5mm;
|
||||
height: 180mm;
|
||||
width: 300mm;
|
||||
page-break-after: always;
|
||||
}
|
||||
</style>
|
||||
{% endblock css %}
|
||||
</head>
|
||||
<body>
|
||||
{% block content %}
|
||||
{% endblock content %}
|
||||
</body>
|
||||
</html>
|
||||
@@ -3,11 +3,11 @@
|
||||
{% block content %}
|
||||
{{ block.super }}
|
||||
<div class='container mx-auto'>
|
||||
<h1>Generate Report for Release</h1>
|
||||
<h1>Generate Report</h1>
|
||||
<div>
|
||||
<form action="">
|
||||
{{ form.as_p }}
|
||||
<input class="default" type="submit" />
|
||||
<input name="submit" value="Submit" class="default" type="submit" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,70 +1,17 @@
|
||||
{% load static humanize avatar_tags %}
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>
|
||||
{% block title %}Boost{% endblock %}
|
||||
</title>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="description" content="{% block description %}{% endblock %}" />
|
||||
<meta name="keywords" content="{% block keywords %}{% endblock %}" />
|
||||
<meta name="author"
|
||||
content="{% block author %}Boost C++ Libraries{% endblock %}" />
|
||||
<link rel="shortcut icon"
|
||||
href="{% static 'img/Boost_Symbol_Transparent.svg' %}"
|
||||
type="image/x-icon" />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans:ital,wght@0,100..900;1,100..900&display=swap"
|
||||
rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+Mono&display=swap"
|
||||
rel="stylesheet">
|
||||
<link rel="stylesheet"
|
||||
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
|
||||
<link rel="stylesheet"
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.css" />
|
||||
<!-- TODO bring this local if we like it -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
|
||||
<script src="{% static 'js/boost-gecko/main.062e4862.js' %}" defer></script>
|
||||
{% block extra_head %}
|
||||
<link href="{% static 'css/styles.css' %}" rel="stylesheet" />
|
||||
{% endblock %}
|
||||
{% block css %}
|
||||
{% endblock css %}
|
||||
<style>
|
||||
@page {
|
||||
margin: 0;
|
||||
size: 300mm 180mm;
|
||||
}
|
||||
|
||||
.pdf-page {
|
||||
padding: 5mm;
|
||||
height: 180mm;
|
||||
width: 300mm;
|
||||
page-break-after: always;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
{% extends "admin/library_report_base.html" %}
|
||||
{% load humanize avatar_tags %}
|
||||
{% block content %}
|
||||
{% with bg_color='bg-gradient-to-tr from-[#7ac3e6]/50 to-[#d9b05e]/50' %}
|
||||
<body>
|
||||
<div>
|
||||
<div class="pdf-page grid grid-cols-2 gap-x-4 items-center justify-items-center {{ bg_color }}">
|
||||
<div>
|
||||
<h1>Boost</h1>
|
||||
<div>{{ commit_count|intcomma }} commits up through {{ version.display_name }}</div>
|
||||
</div>
|
||||
<div>There were {{ version_commit_count|intcomma }} commits in {{ version.display_name }}</div>
|
||||
</div>
|
||||
<div class="pdf-page grid grid-cols-2 gap-x-4 items-center justify-items-center {{ bg_color }}">
|
||||
<div class="flex flex-col">
|
||||
<h1 class="mx-auto">Boost {{ version.display_name }}</h1>
|
||||
<div class="mx-auto mb-4">{{ version_commit_count|intcomma }} Commits Across {{ library_count }} Repositories</div>
|
||||
<h1 class="mx-auto">Boost</h1>
|
||||
<div class="mx-auto mb-4">{{ commit_count|intcomma }} in all releases across all {{ library_count }} libraries</div>
|
||||
<div class="flex gap-x-2">
|
||||
<div>
|
||||
<div class="grid grid-cols-5 gap-2">
|
||||
{% for author in top_contributors_release_overall %}
|
||||
{% for author in top_contributors %}
|
||||
<div class="flex flex-col gap-y-2 w-20 items-center">
|
||||
{% avatar commitauthor=author %}
|
||||
<div class="w-full flex flex-col">
|
||||
@@ -91,20 +38,11 @@
|
||||
<div>{{ item.library.description }}</div>
|
||||
</div>
|
||||
<div class="flex flex-col gap-y-8">
|
||||
<h4>There were {{ item.version_count.commit_count }} commits in release {{ version.display_name }}</h4>
|
||||
{% if item.new_contributors_count.count > 1 %}
|
||||
<div>
|
||||
There were {{ item.new_contributors_count.count }} new contributors this release!
|
||||
</div>
|
||||
{% elif item.new_contributors_count.count == 1 %}
|
||||
<div>
|
||||
There was {{ item.new_contributors_count.count }} new contributor this release!
|
||||
</div>
|
||||
{% endif %}
|
||||
<h4>There are {{ item.full_count.commit_count|intcomma }} commits across all releases</h4>
|
||||
<div>
|
||||
<div class="mb-2">Top Contributors</div>
|
||||
<div class="grid grid-cols-5 gap-2 flex-wrap">
|
||||
{% for author in item.top_contributors_release %}
|
||||
{% for author in item.top_contributors %}
|
||||
<div class="flex flex-col gap-y-2 w-20 items-center">
|
||||
{% avatar commitauthor=author %}
|
||||
<div class="w-full flex flex-col justify-center items-center">
|
||||
@@ -126,7 +64,7 @@
|
||||
var options = {
|
||||
series: [{
|
||||
name: 'Commits',
|
||||
data: [{% for library in top_libraries_for_version %}{{library.commit_count}}, {% endfor %}]
|
||||
data: [{% for library in top_libraries %}{{library.commit_count}}, {% endfor %}]
|
||||
}],
|
||||
chart: {
|
||||
height: 300,
|
||||
@@ -154,7 +92,7 @@
|
||||
}
|
||||
},
|
||||
xaxis: {
|
||||
categories: [{% for library in top_libraries_for_version %} "{{ library.name }}", {% endfor %}],
|
||||
categories: [{% for library in top_libraries %} "{{ library.name }}", {% endfor %}],
|
||||
position: 'bottom',
|
||||
axisBorder: {
|
||||
show: false
|
||||
@@ -182,6 +120,5 @@
|
||||
const chart = new ApexCharts(document.querySelector("#top-committed-libraries-chart"), options);
|
||||
chart.render();
|
||||
</script>
|
||||
</body>
|
||||
{% endwith %}
|
||||
</html>
|
||||
{% endblock content %}
|
||||
139
templates/admin/release_report_detail.html
Normal file
139
templates/admin/release_report_detail.html
Normal file
@@ -0,0 +1,139 @@
|
||||
{% extends "admin/library_report_base.html" %}
|
||||
{% load humanize avatar_tags %}
|
||||
{% block content %}
|
||||
{% with bg_color='bg-gradient-to-tr from-[#7ac3e6]/50 to-[#d9b05e]/50' %}
|
||||
<div>
|
||||
<div class="pdf-page grid grid-cols-2 gap-x-4 items-center justify-items-center {{ bg_color }}">
|
||||
<div>
|
||||
<h1>Boost</h1>
|
||||
<div>{{ commit_count|intcomma }} commits up through {{ version.display_name }}</div>
|
||||
</div>
|
||||
<div>There were {{ version_commit_count|intcomma }} commits in {{ version.display_name }}</div>
|
||||
</div>
|
||||
<div class="pdf-page grid grid-cols-2 gap-x-4 items-center justify-items-center {{ bg_color }}">
|
||||
<div class="flex flex-col">
|
||||
<h1 class="mx-auto">Boost {{ version.display_name }}</h1>
|
||||
<div class="mx-auto mb-4">{{ version_commit_count|intcomma }} Commits Across {{ library_count }} Repositories</div>
|
||||
<div class="flex gap-x-2">
|
||||
<div>
|
||||
<div class="grid grid-cols-5 gap-2">
|
||||
{% for author in top_contributors_release_overall %}
|
||||
<div class="flex flex-col gap-y-2 w-20 items-center">
|
||||
{% avatar commitauthor=author %}
|
||||
<div class="w-full flex flex-col">
|
||||
<div class="text-[0.6rem] overflow-ellipsis overflow-hidden whitespace-nowrap w-full text-center">
|
||||
{{ author.name }}
|
||||
</div>
|
||||
<div class="text-[0.6rem] mx-auto">({{ author.commit_count }})</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<h3 class="mx-auto">Most Committed Libraries</h3>
|
||||
<div id="top-committed-libraries-chart" class="w-full text-center"></div>
|
||||
</div>
|
||||
</div>
|
||||
{% for item in library_data %}
|
||||
<div class="pdf-page grid grid-cols-2 gap-x-4 items-center justify-items-center {{ bg_color }}">
|
||||
<div>
|
||||
<h3>{{ item.library.name }}</h3>
|
||||
<div>{{ item.library.description }}</div>
|
||||
</div>
|
||||
<div class="flex flex-col gap-y-8">
|
||||
<h4>There were {{ item.version_count.commit_count }} commits in release {{ version.display_name }}</h4>
|
||||
{% if item.new_contributors_count.count > 1 %}
|
||||
<div>
|
||||
There were {{ item.new_contributors_count.count }} new contributors this release!
|
||||
</div>
|
||||
{% elif item.new_contributors_count.count == 1 %}
|
||||
<div>
|
||||
There was {{ item.new_contributors_count.count }} new contributor this release!
|
||||
</div>
|
||||
{% endif %}
|
||||
<div>
|
||||
<div class="mb-2">Top Contributors</div>
|
||||
<div class="grid grid-cols-5 gap-2 flex-wrap">
|
||||
{% for author in item.top_contributors_release %}
|
||||
<div class="flex flex-col gap-y-2 w-20 items-center">
|
||||
{% avatar commitauthor=author %}
|
||||
<div class="w-full flex flex-col justify-center items-center">
|
||||
<div class="text-[0.6rem] overflow-ellipsis overflow-hidden whitespace-nowrap w-full text-center">
|
||||
{{ author.name }}
|
||||
</div>
|
||||
<div class="text-[0.6rem]">({{ author.commit_count }})</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="pdf-page {{ bg_color }}" style="page-break-after: avoid;">This is the last page</div>
|
||||
<script>
|
||||
var options = {
|
||||
series: [{
|
||||
name: 'Commits',
|
||||
data: [{% for library in top_libraries_for_version %}{{library.commit_count}}, {% endfor %}]
|
||||
}],
|
||||
chart: {
|
||||
height: 300,
|
||||
type: 'bar',
|
||||
foreColor: '#373d3f',
|
||||
background: '#ffffff00',
|
||||
toolbar: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
plotOptions: {
|
||||
bar: {
|
||||
borderRadius: 2,
|
||||
dataLabels: {
|
||||
position: 'top', // top, center, bottom
|
||||
},
|
||||
}
|
||||
},
|
||||
dataLabels: {
|
||||
offsetY: -16,
|
||||
enabled: true,
|
||||
style: {
|
||||
fontSize: '11px',
|
||||
colors: ["rgb(49, 74, 87)"],
|
||||
}
|
||||
},
|
||||
xaxis: {
|
||||
categories: [{% for library in top_libraries_for_version %} "{{ library.name }}", {% endfor %}],
|
||||
position: 'bottom',
|
||||
axisBorder: {
|
||||
show: false
|
||||
},
|
||||
axisTicks: {
|
||||
show: false
|
||||
},
|
||||
tooltip: {
|
||||
enabled: true,
|
||||
}
|
||||
},
|
||||
yaxis: {
|
||||
axisBorder: {
|
||||
show: true
|
||||
},
|
||||
axisTicks: {
|
||||
show: true,
|
||||
},
|
||||
labels: {
|
||||
show: true,
|
||||
}
|
||||
},
|
||||
};
|
||||
// SS: putting this in the window object, a bit hacky, to be able to access it in the light/dark switcher - probably a better way
|
||||
const chart = new ApexCharts(document.querySelector("#top-committed-libraries-chart"), options);
|
||||
chart.render();
|
||||
</script>
|
||||
{% endwith %}
|
||||
{% endblock content %}
|
||||
Reference in New Issue
Block a user