Loading stats/admin.py +10 −0 Changes for stats/admin.py: 10 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -46,6 +46,12 @@ def statistics(request, election_id): 'percentage': round((voted / total * 100), 2) if total > 0 else 0 }) remote_count = Participation.objects.filter(election=election, is_remote=True).count() stationary_count = total_participated - remote_count; remote_percentage = round((remote_count / total_participated * 100), 2) stationary_percentage = round((stationary_count / total_participated * 100), 2) context.update({ 'request': request, 'election_id': election_id, Loading @@ -54,6 +60,10 @@ def statistics(request, election_id): 'total_participated': total_participated, 'total_eligible': total_eligible, 'stats_by_class': stats_by_class, 'remote_count': remote_count, 'stationary_count': stationary_count, 'remote_percentage': remote_percentage, 'stationary_percentage': stationary_percentage, }) return render(request, 'stats/statistics.html', context) No newline at end of file stats/templates/stats/statistics.html +55 −1 Changes for stats/templates/stats/statistics.html: 55 added lines, 1 removed line. Original line number Diff line number Diff line Loading @@ -58,14 +58,36 @@ </tbody> </table> <div style="border-radius: 8px; text-align: center; border: 1px solid #ddd;"> <div style="padding: 20px; border-radius: 8px; border: 1px solid #ddd; margin-bottom: 30px;"> <h3 style="text-align: center;">Frekwencja w klasach (%)</h3> <div style="height: 40vh; width: 100%;"> <canvas id="attendance-bar-chart"></canvas> </div> </div> <div style="display: flex; gap: 20px; margin-bottom: 30px;"> <div style="border-radius: 8px; text-align: center; border: 1px solid #ddd; flex: 1;"> <h3>Ogólna frekwencja</h3> <p style="font-size: 2.5em; font-weight: bold; color: #417690;">{{ overall_attendance }}%</p> <p>{{ total_participated }} / {{ total_eligible }} oddanych głosów</p> </div> <div style="border-radius: 8px; text-align: center; border: 1px solid #ddd; flex: 1;"> <h3>Tryb oddania głosów</h3> <p>Zdalnie: <strong>{{ remote_count }} ({{ remote_percentage }}%)</strong></p> <p>Stacjonarnie: <strong>{{ stationary_count }} ({{ stationary_percentage }}%)</strong></p> </div> </div> </div> {{ stats_by_class|json_script:"attendance-data-json" }} <script> function getStats() { const element = document.getElementById('stats-data'); return JSON.parse(element.TextContent); } async function getElectionData() { const apiUrl = "{{ request.scheme }}://{{ request.get_host }}{% url 'vote:api_internal_results' %}?election_id={{ election_id }}"; Loading Loading @@ -138,11 +160,43 @@ totalCell.innerText = total; } function initializeAttendanceChart() { const data = JSON.parse(document.getElementById('attendance-data-json').textContent); const labels = data.map(item => item.class_name); const percentages = data.map(item => item.percentage); const ctx = document.getElementById('attendance-bar-chart').getContext('2d'); new Chart(ctx, { type: 'bar', data: { labels: labels, datasets: [{ label: 'Frekwencja (%)', data: percentages, borderWidth: 1 }] }, options: { responsive: true, maintainAspectRatio: false, scales: { y: { beginAtZero: true, max: 100 } }, plugins: { legend: { display: false } } } }); } async function displayResults() { const data = await getElectionData(); initializeChart(data); initializeTable(data); initializeAttendanceChart(); } displayResults(); Loading Loading
stats/admin.py +10 −0 Changes for stats/admin.py: 10 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -46,6 +46,12 @@ def statistics(request, election_id): 'percentage': round((voted / total * 100), 2) if total > 0 else 0 }) remote_count = Participation.objects.filter(election=election, is_remote=True).count() stationary_count = total_participated - remote_count; remote_percentage = round((remote_count / total_participated * 100), 2) stationary_percentage = round((stationary_count / total_participated * 100), 2) context.update({ 'request': request, 'election_id': election_id, Loading @@ -54,6 +60,10 @@ def statistics(request, election_id): 'total_participated': total_participated, 'total_eligible': total_eligible, 'stats_by_class': stats_by_class, 'remote_count': remote_count, 'stationary_count': stationary_count, 'remote_percentage': remote_percentage, 'stationary_percentage': stationary_percentage, }) return render(request, 'stats/statistics.html', context) No newline at end of file
stats/templates/stats/statistics.html +55 −1 Changes for stats/templates/stats/statistics.html: 55 added lines, 1 removed line. Original line number Diff line number Diff line Loading @@ -58,14 +58,36 @@ </tbody> </table> <div style="border-radius: 8px; text-align: center; border: 1px solid #ddd;"> <div style="padding: 20px; border-radius: 8px; border: 1px solid #ddd; margin-bottom: 30px;"> <h3 style="text-align: center;">Frekwencja w klasach (%)</h3> <div style="height: 40vh; width: 100%;"> <canvas id="attendance-bar-chart"></canvas> </div> </div> <div style="display: flex; gap: 20px; margin-bottom: 30px;"> <div style="border-radius: 8px; text-align: center; border: 1px solid #ddd; flex: 1;"> <h3>Ogólna frekwencja</h3> <p style="font-size: 2.5em; font-weight: bold; color: #417690;">{{ overall_attendance }}%</p> <p>{{ total_participated }} / {{ total_eligible }} oddanych głosów</p> </div> <div style="border-radius: 8px; text-align: center; border: 1px solid #ddd; flex: 1;"> <h3>Tryb oddania głosów</h3> <p>Zdalnie: <strong>{{ remote_count }} ({{ remote_percentage }}%)</strong></p> <p>Stacjonarnie: <strong>{{ stationary_count }} ({{ stationary_percentage }}%)</strong></p> </div> </div> </div> {{ stats_by_class|json_script:"attendance-data-json" }} <script> function getStats() { const element = document.getElementById('stats-data'); return JSON.parse(element.TextContent); } async function getElectionData() { const apiUrl = "{{ request.scheme }}://{{ request.get_host }}{% url 'vote:api_internal_results' %}?election_id={{ election_id }}"; Loading Loading @@ -138,11 +160,43 @@ totalCell.innerText = total; } function initializeAttendanceChart() { const data = JSON.parse(document.getElementById('attendance-data-json').textContent); const labels = data.map(item => item.class_name); const percentages = data.map(item => item.percentage); const ctx = document.getElementById('attendance-bar-chart').getContext('2d'); new Chart(ctx, { type: 'bar', data: { labels: labels, datasets: [{ label: 'Frekwencja (%)', data: percentages, borderWidth: 1 }] }, options: { responsive: true, maintainAspectRatio: false, scales: { y: { beginAtZero: true, max: 100 } }, plugins: { legend: { display: false } } } }); } async function displayResults() { const data = await getElectionData(); initializeChart(data); initializeTable(data); initializeAttendanceChart(); } displayResults(); Loading