Merge pull request #173 from ChrisBr/new_dashboard

Implements event submissions over time chart
This commit is contained in:
Christian Bruckmayer
2014-05-30 10:23:23 +02:00
12 changed files with 215 additions and 9 deletions

View File

@@ -59,6 +59,7 @@ gem 'axlsx_rails'
# Use d3js for building our statistics
gem 'd3_rails'
gem 'chart-js-rails'
# We use coveralls for measuring test coverage
gem 'coveralls', require: false

View File

@@ -63,6 +63,8 @@ GEM
celluloid-io (0.15.0)
celluloid (>= 0.15.0)
nio4r (>= 0.5.0)
chart-js-rails (0.0.6)
railties (> 3.1)
climate_control (0.0.3)
activesupport (>= 3.0)
cocaine (0.5.4)
@@ -313,6 +315,7 @@ DEPENDENCIES
cancan
capybara
capybara-webkit
chart-js-rails
cocoon
coveralls
d3_rails

View File

@@ -18,8 +18,10 @@
//= require jquery.dataTables
//= require cocoon
//= require bootstrap
//= require osem
//= require Chart
//= require d3
//= require osem
//= require dashboard
$(document).ready(function() {
$('a[disabled=disabled]').click(function(event){

View File

@@ -0,0 +1,80 @@
$(function() {
var t;
function size(animate){
if (animate == undefined){
animate = false;
}
clearTimeout(t);
t = setTimeout(function(){
$("canvas").each(function(i,el){
$(el).attr({
"width":$(el).parent().width(),
"height":$(el).parent().outerHeight()
});
});
redraw(animate);
var m = 0;
$(".widget").height("");
$(".widget").each(function(i,el){ m = Math.max(m,$(el).height()); });
$(".widget").height(m);
}, 30);
}
function redraw(animation){
var options = {};
if (!animation){
options.animation = false;
} else {
options.animation = true;
}
var chart_data = create_dataset();
var weeks = $('.submissionsChart').data('weeks');
var data = {
labels : weeks,
datasets : chart_data
}
var canvas = document.getElementById("chart");
var ctx = canvas.getContext("2d");
new Chart(ctx).Line(data, options);
}
function create_dataset(){
var selected = getSelectedConferences();
var chart_data = $('.submissionsChart').data('chart');
var conferences = $('.submissionsChart').data('conferences');
var result = [];
for(var i in conferences){
if(selected.indexOf(conferences[i].short_title) >= 0){
var options = {};
options.fillColor = "rgba(255,255,255,0.0)";
options.strokeColor = conferences[i].color;
options.data = chart_data[conferences[i].short_title];
result.push(options)
}
}
return result
}
function getSelectedConferences(){
var selected = []
$('.conferenceCheckboxes input').each(function(){
if($(this).is(":checked")) {
selected.push($(this).attr('name'));
}
})
return selected;
}
$('.conferenceCheckboxes input').change(function(){
redraw(false);
});
$(window).on('resize', function(){ size(false); });
size(true);
});

View File

@@ -50,3 +50,8 @@ body > #messages {
display: block;
}
}
.conferenceCheckboxes div {
display: inline-block;
padding: 0px 10px 0px 0px;
}

View File

@@ -2,8 +2,21 @@ class Admin::ConferenceController < ApplicationController
before_filter :verify_organizer
def index
@conferences = Conference.all
if @conferences.count == 0
@conferences = Conference.select('id, short_title, color, start_date')
# Event submissions over time
@weeks = CallForPapers.max_weeks
@result = {}
@conferences.each do |c|
submission = c.get_submissions_per_week(@weeks)
@result[c.short_title] = submission
end
@weeks = @weeks > 0 ? (1..@weeks).to_a : 1
# Redirect to new form if there is no conference
if Conference.count == 0
redirect_to new_admin_conference_path
return
end

View File

@@ -7,4 +7,20 @@ class CallForPapers < ActiveRecord::Base
validates_presence_of :start_date, :end_date, :hard_deadline
validates :rating, :numericality => { :greater_than_or_equal_to => 0, :less_than_or_equal_to => 10 }
def self.max_weeks
all = CallForPapers.all
result = [0]
all.each do |cfp|
result.push(cfp.end_week - cfp.start_week)
end
result.max
end
def start_week
start_date.strftime('%W').to_i
end
def end_week
end_date.strftime('%W').to_i
end
end

View File

@@ -124,6 +124,43 @@ class Conference < ActiveRecord::Base
return false
end
##
# Returns an array with the summarized event submissions per week.
# ====Params:
# * +weeks+ -> Integer with number of weeks. This is necessary to compare conferences.
#
# ====Returns
# * +Array+ -> e.g. [0, 3, 3, 5] -> first week 0 events, second week 3 events.
def get_submissions_per_week(weeks)
result = []
if call_for_papers && events
submissions = events.select('id, created_at').group_by { |t| t.week }
start_week = call_for_papers.start_week
sum = 0
(0..weeks - 1).each do |week|
if submissions["#{week + start_week}"]
sum += submissions["#{week + start_week}"].length
end
result.push(sum)
end
else
result = Array.new(weeks, 0)
end
result
end
##
# Checks if the conference is pending.
#
# ====Returns
# * +false+ -> If the conference start date is in the past.
# * +true+ -> If the conference start date is in the future.
def pending?
start_date > Date.today
end
private
##

View File

@@ -174,6 +174,10 @@ class Event < ActiveRecord::Base
end
end
def week
created_at.strftime('%W')
end
private
def abstract_limit

View File

@@ -1,7 +1,22 @@
.row
%h1 Global Dashboard
%hr
.row
%ul
- @conferences.each do |conference|
%li= link_to conference.title, admin_conference_path(conference.short_title)
.col-md-12
.well
.row
.text-center
%h4 Event submissions over time
.row
.submissionsChart{"data-chart"=>"#{@result.to_json}", "data-conferences"=>"#{@conferences.to_json}", "data-weeks"=>"#{@weeks.to_json}"}
%canvas#chart
.row
.text-center
weeks
.row
.conferenceCheckboxes
- @conferences.each do |conference|
%div
%span{"style"=>"border-bottom: 3px solid #{conference.color};"}
- if conference.pending?
%input{"type"=>"checkbox", "name"=>"#{conference.short_title}", "checked"=>"checked"}
- else
%input{"type"=>"checkbox", "name"=>"#{conference.short_title}"}
#{conference.short_title}

View File

@@ -147,11 +147,22 @@ describe Admin::ConferenceController do
describe 'GET #index' do
context 'with more than 0 conferences' do
it 'populates an array with conferences' do
conference
con2 = create(:conference)
get :index
expect(assigns(:conferences)).to match_array([conference, con2])
end
it 'assigns cfp_max an array with maximum weeks' do
conference
date = Date.new(2014, 05, 28)
conference.call_for_papers = create(:call_for_papers,
start_date: date,
end_date: date + 14)
get :index
expect(assigns(:weeks)).to match_array([1, 2])
end
it 'renders the index template' do
conference
get :index

View File

@@ -6,6 +6,25 @@ describe Conference do
let(:subject) { create(:conference) }
describe '#pending?' do
context 'is pending' do
it '#pending? is true' do
subject.start_date = Date.today + 10
expect(subject.pending?).to be true
end
end
context 'is not pending' do
it '#pending? is false' do
subject.start_date = Date.today - 10
expect(subject.pending?).to be false
end
end
end
describe '#registration_open?' do
context 'closed registration' do