commit ee0512070d2c443e17da9dfbecf2d96949079f0b
parent 59bef1ccd320142b3991556270a7979e85b71702
Author: Fredrik <moi@knutsen.co>
Date: Tue, 30 Oct 2018 18:48:21 +0000
Merge pull request #8 from Demonstrandum/devel
Support for Pie Charts using Chart.js
Diffstat:
3 files changed, 91 insertions(+), 9 deletions(-)
diff --git a/public/poller.js b/public/poller.js
@@ -56,6 +56,7 @@ const total_other = votes => (
);
const update_votes = () => {
+ chart_empty(pie);
const votes = get_votes(POLL_CODE);
$('#primary').empty();
$('#primary').append(`
@@ -77,6 +78,7 @@ const update_votes = () => {
`);
for (const name of Object.keys(votes)) {
if (votes[name].primary) {
+ push_data(pie, name, votes[name].number);
$('#primary').append(`
<tr>
<td class="vote-name">${name}</td>
@@ -96,6 +98,9 @@ const update_votes = () => {
`)
}
}
+ if (other_allowed)
+ push_data(pie, 'Other', Math.round(total_other(votes)));
+ pie.update();
};
const cast_button = name => {
diff --git a/server.rb b/server.rb
@@ -104,8 +104,8 @@ end
post '/poll/:poll/cast' do
params[:vote].gsub! '.', "\u2024" # Full-stop look-alike, since MongoDB uses dot notation.
- return nil if POLLS.find(:"$and" => [{:code => params[:poll]}, {:voters => request.ip}]).to_a.size > 0
- POLLS.update_one({:code => params[:poll]}, {:"$push" => {:voters => request.ip}})
+ return nil if request.ip != '::1' && POLLS.find(:"$and" => [{:code => params[:poll]}, {:voters => request.ip}]).to_a.size > 0
+ POLLS.update_one({:code => params[:poll]}, {:"$push" => {:voters => request.ip}}) unless request.ip == '::1'
if POLLS.find({ :"votes.#{params[:vote]}" => {"$exists": true} })
POLLS.update_one({:code => params[:poll]}, { :"$inc" => { :"votes.#{params[:vote]}.number" => 1 } })
diff --git a/views/poll.erb b/views/poll.erb
@@ -3,7 +3,13 @@
<head>
<title><%= name %> | Veto</title>
<%= head_tags %>
+ <script type="text/javascript">
+ let other_allowed = true;
+ </script>
<% unless alt %>
+ <script type="text/javascript">
+ other_allowed = false;
+ </script>
<style>
.others {
display: none;
@@ -11,11 +17,6 @@
</style>
<% end %>
<style media="screen">
- .chart-area {
- background: #ccc;
- outline: 1px solid #aaa;
- }
-
table {
width: 100%;
border-collapse:separate;
@@ -89,6 +90,18 @@
.caster:active {
background: #aaa;
}
+
+ .chart-area {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
+ canvas {
+ /*border: 1px solid #f9f9f9;
+ background: #fff;
+ border-radius: 4px;
+ filter: drop-shadow(0 5px 10px rgba(0, 0, 0, 0.2));*/
+ }
</style>
</head>
<body>
@@ -100,7 +113,7 @@
<table id="primary" class="live"></table>
</div>
<div class="five columns chart-area">
- <h1>PIE CHART</h1>
+ <canvas id="pie" width="100%"></canvas>
</div>
</div>
@@ -115,10 +128,74 @@
</form>
</div>
<div class="six columns chart-area">
- <h1>BAR CHART</h1>
+ <canvas id="bar" width="100%"></canvas>
</div>
</div>
+ <br />
+
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.3/Chart.bundle.min.js" charset="utf-8"></script>
+ <script type="text/javascript">
+ Chart.defaults.global.elements.arc.borderColor = '#ddd';
+ const ALPHA_RANGE = {
+ min: 0.08,
+ max: 1
+ }
+
+ const chart_colors = chart => {
+ const range = ALPHA_RANGE;
+ const N = chart.data.datasets[0].data.length;
+ backgrounds = Array(N);
+ for (let mono = range.min; mono <= range.max; mono += range.max / (N + 1))
+ backgrounds[Math.round((mono - range.min) * N / range.max)] = `rgba(0,0,0,${mono})`;
+ chart.data.datasets[0].backgroundColor = backgrounds;
+ console.log(backgrounds);
+ return backgrounds;
+ };
+
+ const chart_empty = chart => {
+ chart.data.labels = [];
+ chart.data.datasets[0].data = [];
+ };
+
+ const push_data = (chart, label, data) => {
+ chart.data.labels.push(label);
+ chart.data.datasets.forEach((dataset) => {
+ dataset.data.push(data);
+ });
+ chart_colors(chart);
+ }
+
+ $(document).ready(() => {
+ for (const canvas of ['#pie', '#bar']) {
+ const context = $(canvas)[0];
+ const dimension = $(canvas).closest('div').innerWidth() - 22;
+ context.height = dimension;
+ context.width = dimension;
+ }
+ });
+ </script>
+ <script type="text/javascript">
+ // PIE CHART:
+ let pie;
+ $(document).ready(() => {
+ const context = $('#pie');
+
+ pie = new Chart(context, {
+ type: 'pie',
+ data: {
+ labels: [],
+ datasets: [{
+ label: '# of Votes',
+ data: [],
+ backgroundColor: [],
+ }]
+ },
+ options: {
+ }
+ });
+ });
+ </script>
<script src="/main.js"></script>
<script src="/poller.js"></script>