NDOJ/templates/problem/voting-stats.html
2022-03-11 22:34:32 -06:00

146 lines
No EOL
4.9 KiB
HTML

<style>
.vote-stats-background {
background-color: rgb(255,255,255);
padding: 20px;
border-radius: 25px;
justify-content: center;
align-items: center;
margin: auto;
text-align: center;
}
.canvas {
border: 1px;
border: solid;
border: #000000;
}
.vote-stats-value {
margin-right: 1em;
}
.vote-stats-info {
font-weight: 500;
}
</style>
<a href="#" class="form-button" id="id_vote_stats_button">{{ _('Statistics') }}</a>
<div class="vote-stats-background" id="id_vote_stats" style="display: none;">
<script src={{ static('libs/chart.js/Chart.js') }}></script>
<span class="vote-stats-info">{{ _('Voting Statistics') }}</span>
<br/>
<canvas class="canvas" id="id_vote_chart"></canvas>
<span id="id_no_votes_error" class="vote-stats-info no_votes_error">{{ _('No Votes Available!') }}</span>
<br/>
<div id="id_has_votes_footer" class="has_votes_footer">
<span class="vote-stats-info">{{ _('Median:') }}</span>
<span class="vote-stats-value median_vote" id="id_median_vote"></span>
<span class="vote-stats-info">{{ _('Mean:') }}</span>
<span class="vote-stats-value mean_vote" id="id_mean_vote"></span>
<span class="vote-stats-info">{{ _('Total:') }}</span>
<span class="vote-stats-value total_vote" id="id_num_of_votes"></span>
</div>
</div>
<script>
let voteChart = null;
let allVotes = {{ all_votes }};
function reload_vote_graph() {
if (voteChart !== null) voteChart.destroy();
if (allVotes.length === 0) {
$('.canvas').hide();
$('.has_votes_footer').hide();
$('.no_votes_error').show();
} else {
$('.canvas').show();
$('.has_votes_footer').show();
$('.no_votes_error').hide();
allVotes.sort(function(a, b){return a - b});
// Give the graph some padding on both sides.
let min_points = {{ min_possible_vote }};
let max_points = {{ max_possible_vote }};
let xlabels = [];
let voteFreq = [];
for (let i = min_points; i <= max_points; i += 100) {
xlabels.push(i);
voteFreq.push(0);
}
let max_number_of_votes = 0;
let total_votes = 0;
let mean = 0;
for (let i = 0; i < allVotes.length; i++) {
// Assume the allVotes is valid.
voteFreq[(allVotes[i] - min_points) / 100]++;
max_number_of_votes = Math.max(max_number_of_votes, voteFreq[(allVotes[i] - min_points) / 100]);
mean += allVotes[i];
total_votes++;
}
mean = mean / total_votes;
let half = Math.floor(total_votes / 2);
let median = allVotes[half];
if (total_votes % 2 === 0) {
median = (median + allVotes[half - 1]) / 2;
}
$('.mean_vote').prop('innerText', mean.toFixed(2));
$('.median_vote').prop('innerText', median.toFixed(2));
$('.total_vote').prop('innerText', total_votes);
const voteData = {
labels: xlabels,
datasets: [{
data: voteFreq,
backgroundColor: 'pink',
}]
};
const voteDataConfig = {
type: 'bar',
data: voteData,
options: {
legend: {
display: false
},
responsive: true,
scales: {
yAxes: [{
ticks: {
precision: 0,
suggestedMax: Math.ceil(max_number_of_votes * 1.2),
beginAtZero: true,
}
}],
xAxes: [{
ticks: {
beginAtZero: false,
}
}]
}
}
};
voteChart = new Chart($('.featherlight-inner .canvas'), voteDataConfig);
}
}
function updateUserVote(prev_voted_points, voted_points) {
let index = allVotes.indexOf(prev_voted_points);
if (index > -1) {
allVotes.splice(index, 1);
}
allVotes.push(voted_points);
}
function deleteUserVote(prev_voted_points) {
allVotes.splice(allVotes.indexOf(prev_voted_points), 1);
}
$(function() {
$('#id_vote_stats_button').featherlight('#id_vote_stats', {
afterOpen: reload_vote_graph,
})
});
</script>