Removes stats controller

This commit is contained in:
Chrisbr 2014-08-18 14:33:12 +02:00
parent ed55e2bf3a
commit 4189d5251b
23 changed files with 0 additions and 1498 deletions

View file

@ -1,232 +0,0 @@
module Admin
class StatsController < Admin::BaseController
load_and_authorize_resource
load_and_authorize_resource :conference, find_by: :short_title
def index
@registrations = @conference.registrations.includes(:user)
@registrations = @registrations.order('registrations.created_at ASC')
@registered = @conference.registrations.count
@attendees = @conference.registrations.where('attended = ?', true).count
@pre_registered = @conference.registrations
@pre_registered = @pre_registered.where('created_at < ?', @conference.start_date).count
@pre_registered_attended = @conference.registrations.where('created_at < ? AND attended = ?',
@conference.start_date, true).count
@registered_with_partner = @conference.registrations.where('attending_with_partner = ?',
true).count
@attended_with_partner = @conference.registrations.where(
'attending_with_partner = ? AND attended = ?', true, true).count
@handicapped_access = @conference.registrations.where(handicapped_access_required: true).count
@handicapped_access_attended = @conference.registrations.where(handicapped_access_required:
true)
@handicapped_access_attended = @handicapped_access_attended.where(attended: true).count
@suggested_hotel_stay = @conference.registrations.where('using_affiliated_lodging = ?',
true).count
@events = @conference.events
# Events charts
@machine_states = [['confirmed'], ['cancelled'], ['rejected'], ['withdrawn'],
['new', 'review'], ['unconfirmed', 'accepted']]
# Types distribution per state
@type_state = {}
@machine_states.each do |state|
@type_state[state[0]] = var_state_func(@conference.event_types, 'event_type', state)
end
# Tracks distribution per state
@no_track_all = @events.where(track_id: nil)
@no_track_new = @events.where(track_id: nil).where(state: ['new', 'review'])
@no_track_unconfirmed = @events.where(track_id: nil).where(state: 'unconfirmed')
@no_track_confirmed = @events.where(track_id: nil).where(state: 'confirmed')
@track_state = {}
@machine_states.each do |state|
@track_state[state[0]] = var_state_func(@conference.tracks, 'track', state)
end
# Events_time chart
if @events.count > 0
start_date = @events.minimum('created_at').strftime('%Y-%m-%d')
end_date = @events.maximum('created_at').strftime('%Y-%m-%d')
unless start_date.nil? || end_date.nil?
@events_time = var_time(start_date, end_date, @events, 'created_at')
end
end
# Code for the table in events
@mystates = []
@mytypes = []
@eventstats = {}
@totallength = 0
# Get totals per state
@events.state_machine.states.map.each do |mystate|
length = 0
events_mystate = @events.where('state' => mystate.name)
if events_mystate.count > 0
@mystates << mystate
events_mystate.each do |myevent|
length += myevent.event_type.length
end
@eventstats["#{mystate.name}"] = { 'count' => events_mystate.count, 'length' => length }
end
end
@conference.event_types.each do |mytype|
events_mytype = @events.where('event_type_id' => mytype.id)
if events_mytype.count > 0
@mytypes << mytype
end
end
@mytypes.each do |mytype|
@mystates.each do |mystate|
events_mytype = @events.where('event_type_id' => mytype.id)
events_mytype_mystate = events_mytype.where('state' => mystate.name)
typelength = 0
if events_mytype_mystate.count > 0
events_mytype_mystate.each do |myevent|
typelength += myevent.event_type.length
@totallength += myevent.event_type.length
end
if @eventstats[mytype.title].nil?
@eventstats[mytype.title] = { 'count' => events_mytype.count,
'length' => events_mytype.count * mytype.length }
end
tmp = { "#{mystate.name}" => { 'type_state_count' => events_mytype_mystate.count,
'type_state_length' => typelength } }
@eventstats[mytype.title].merge!(tmp)
end
end
end
@eventstats['totallength'] = @totallength
# SPEAKERS stats
@speakers = User.joins(:events).where('events.conference_id = ? AND events.state LIKE ?',
@conference.id, 'confirmed').uniq
@speaker_fields_user = %w(name email affiliation)
@speaker_fields_reg = %w(arrival departure)
# TICKETS stats
@supporter_levels = @conference.supporter_levels
@tickets = @conference.registrations.joins(supporter_registration: :supporter_level)
@tickets = @tickets.where('supporter_levels.title NOT LIKE ? ', '%Free%')
@tickets_time = []
if @conference.registration_start_date && @conference.end_date && @registered > 0 && @supporter_levels
start_date = @conference.registration_start_date
end_date = @conference.end_date
levels = []
@conference.supporter_levels.each do |level|
@tickets_time << { 'key' => level.title, 'values' => [] }
levels << ["#{level.title}"]
end
(start_date..end_date).each do |day|
if @tickets.where('supporter_registrations.created_at LIKE ?', "%#{day}%").where(
'supporter_levels.title' => levels).count != 0
@conference.supporter_levels.each do |level|
day_ticket_count = @tickets.where('supporter_registrations.created_at LIKE ?
AND supporter_levels.title LIKE ?',
"%#{day}%", "%#{level.title}%").count
index = @tickets_time.index { |v| v['key'] == "#{level.title}" }
@tickets_time[index]['values'] << { 'label' => "#{day}", 'value' => day_ticket_count }
end
end
end
end
@tickets_distribution = []
@tickets_time.each do |ticket|
value = ticket['values'].map { |x| x['value'] }.sum
percent = (value.to_f / @tickets.count * 100).round(2)
@tickets_distribution << { 'status' => ticket['key'],
'value' => value, 'percent' => percent }
end
# OTHER_INFO chart / To be 'Questions'
@other_info = [
{ 'status' => 'with partner (registered)', 'value' => @registered_with_partner },
{ 'status' => 'with partner (attended)', 'value' => @attended_with_partner },
{ 'status' => 'handicapped (registered)', 'value' => @handicapped_access },
{ 'status' => 'handicapped (attended)', 'value' => @handicapped_access_attended },
{ 'status' => 'stay at suggested hotel', 'value' => @suggested_hotel_stay }
]
# REGISTRATIONS, registered_time
if @conference.registration_start_date && @conference.end_date && @registered > 0
start_date = @conference.registration_start_date
end_date = @conference.end_date
@registered_time = var_time(start_date, end_date, @registrations, 'created_at')
end
respond_to do |format|
format.html
format.json { render json: @tickets_time.to_json }
end
end
# FUNCTIONS
def var_time(start_date, end_date, var, field)
result = []
(start_date..end_date).each do |day|
day_var_count = var.where("#{field} LIKE ?", "%#{day}%").count
if day_var_count != 0
result << { 'status' => "#{day}", 'value' => day_var_count }
end
end
result
end
def var_state_func(vars, field, mystate)
result = []
vars.each do |myvar|
# Find events per track and state
value = @conference.events.where("#{field}_id" => myvar.id).where(state: mystate).count
# Find all events in that state
total = @conference.events.where(state: mystate).count
status = "#{myvar.name}"
percent = 0 # rubocop:disable Lint/UselessAssignment
if value != 0
percent = (value.to_f / total * 100).round(2)
result << { 'status' => status, 'value' => value, 'percent' => percent }
end
end
# Get no of events for which the field is not set (So that pie shows half piece for 50%)
sum = result.inject(0) { |s, hash| s + hash['value'] }
value = total - sum
if sum != 0 && value != 0
percent = (value.to_f / total * 100).round(2)
result << { 'status' => "no #{field} set", 'value' => value, 'percent' => percent }
end
result
end
def speaker_reg(speaker)
speaker.registrations.where('conference_id = ? AND user_id = ?',
@conference.id, speaker.id).first
end
def speaker_diet(reg)
@conference.dietary_choices.find(reg.dietary_choice_id)
end
def diet_count(diet)
@conference.registrations.where('dietary_choice_id = ?', diet)
end
def social_event_count(event)
@conference.registrations.joins(:social_events).where(
'registrations_social_events.social_event_id = ?', event).count
end
helper_method :speaker_reg
helper_method :speaker_diet
helper_method :diet_count
helper_method :social_event_count
end
end

View file

@ -1,41 +0,0 @@
-if @events.count > 0
%h2{:style => "text-align: center"}
= "Events (#{@events.count})"
.row-fluid
%h3
%u Types per event state
- if !@conference.event_types.empty?
= render :partial => "events_types"
- else
%h4
%i There are no tracks defined for this conference!
.row-fluid
%h3
%u Tracks per event state
- if @no_track_all.count > 0
%i= " (#{pluralize(@no_track_all.count, 'event')} not assigned to a track)"
- if !@conference.tracks.empty?
= render :partial => "events_tracks"
- else
%h4
%i There are no tracks defined for this conference!
.row-fluid
.span12
%h3 Proposal Submissions over time
.row-fluid
.span12#events_time
= render :partial => "events_time"
.row-fluid
.span12
%br
%h3 Overview of all events
.row-fluid
.span12#events_table
= render :partial => "events_table"
- else
%h5 There are no submitted events yet.

View file

@ -1,34 +0,0 @@
%table.table.table-bordered.table-striped
%thead
%th
- @mystates.each do |state|
%th{:colspan => 2, :style => "text-align:center"}
State "#{state.name}"
%th{:colspan => 2, :style => "text-align:center"}
Total
%br
No & Time
%tr
%td
%b Total
- @mystates.each do |mystate|
%td
%b
= @eventstats["#{mystate.name}"]["count"]
%td
%b
#{@eventstats["#{mystate.name}"]["length"] / 60} h #{@eventstats["#{mystate.name}"]["length"] - @eventstats["#{mystate.name}"]["length"] / 60 * 60} m
%td
%b= @events.count
%td
%b= show_time(@eventstats["totallength"])
- @mytypes.each do |mytype|
%tr
%td= "#{mytype.title} (#{show_time(mytype.length)})"
- @mystates.each do |mystate|
%td= @eventstats["#{mytype.title}"]["#{mystate.name}"]["type_state_count"] unless @eventstats["#{mytype.title}"]["#{mystate.name}"] == nil
%td= show_time(@eventstats["#{mytype.title}"]["#{mystate.name}"]["type_state_length"]) unless @eventstats["#{mytype.title}"]["#{mystate.name}"] == nil
%td= @eventstats["#{mytype.title}"]["count"]
%td= show_time(@eventstats["#{mytype.title}"]["length"])

View file

@ -1,71 +0,0 @@
<script>
var events = '<%= h @events.count%>';
var data = <%=raw @events_time.to_json %>;
var valueLabelWidth = 10; // space reserved for value labels (right)
var barHeight = 24; // height of one bar
var barLabelWidth = 100; // space reserved for bar labels
var barLabelPadding = 8; // padding between bar and bar labels (left)
var gridLabelHeight = 18; // space reserved for gridline labels
var gridChartOffset = 3; // space between start of grid and first bar
var maxBarWidth = 420; // width of the bar with the max value
var color = d3.scale.category20();
// accessor functions
var barLabel = function(d) { return d['status']; };
var barValue = function(d) { return d['value'] / events * 100; };
var barValues = function(d) { return d['value']; };
// scales
var yScale = d3.scale.ordinal().domain(d3.range(0, data.length)).rangeBands([0, data.length * barHeight]);
var y = function(d, i) { return yScale(i); };
var yText = function(d, i) { return y(d, i) + yScale.rangeBand() / 2; };
var yMax = d3.max(data, function(d){ return barValue(d) + 15; });
var x = d3.scale.linear().domain([0, yMax]).range([0, maxBarWidth]);
var width = maxBarWidth + barLabelWidth + valueLabelWidth;
// svg container element
var chart = d3.select('#events_time').append("svg")
.attr('width', maxBarWidth + barLabelWidth + valueLabelWidth)
.attr('height', gridLabelHeight + gridChartOffset + data.length * barHeight);
// bar labels
var labelsContainer = chart.append('g')
.attr('transform', 'translate(' + (barLabelWidth - barLabelPadding) + ',' + (gridLabelHeight + gridChartOffset) + ')');
labelsContainer.selectAll('text').data(data).enter().append('text')
.attr('y', yText)
.attr('stroke', 'none')
.attr('fill', 'black')
.attr("dy", ".35em") // vertical-align: middle
.attr('text-anchor', 'end')
.text(barLabel);
// bars
var barsContainer = chart.append('g')
.attr('transform', 'translate(' + barLabelWidth + ',' + (gridLabelHeight + gridChartOffset) + ')');
barsContainer.selectAll("rect").data(data).enter().append("rect")
.attr('y', y)
.attr('height', yScale.rangeBand())
.attr('width', function(d) { return x(barValue(d)); })
.attr('stroke', 'white')
.attr('fill', function(d) { return color(barValue(d)); });
// bar value labels
barsContainer.selectAll("text").data(data).enter().append("text")
.attr("x", 5)
.attr("y", yText)
.attr("dx", 3) // padding-left
.attr("dy", ".35em") // vertical-align: middle
.attr("text-anchor", "start") // text-align: right
.attr("fill", "black")
.attr("stroke", "none")
.text(function(d) { return d3.round(barValues(d), 2) + " (" + d3.round(barValue(d), 0) + "%)"; });
// start line
barsContainer.append("line")
.attr("y1", -gridChartOffset)
.attr("y2", yScale.rangeExtent()[1] + gridChartOffset)
.style("stroke", "#000");
</script>

View file

@ -1,35 +0,0 @@
.row-fluid
- if !@track_state['new'].empty?
.span4
%h4 New Submissions
- if @no_track_new.count > 0
%h5= "#{pluralize(@no_track_new.count, 'event')} not assigned to a track"
- else
%h5
.row-fluid
.span12#events_tracks_new
= render :partial => "events_tracks_new"
- if !@track_state['unconfirmed'].empty?
.span4
%h4 Accepted (Unconfirmed)
- if @no_track_unconfirmed.count > 0
%h5= "#{pluralize(@no_track_unconfirmed.count, 'event')} not assigned to a track"
- else
%h5 All events assigned to track!
.row-fluid
.span12#events_tracks_unconfirmed
= render :partial => "events_tracks_unconfirmed"
- if !@track_state['confirmed'].empty?
.span4
%h4 Accepted (Confirmed)
- if @no_track_confirmed.count > 0
%h5= "#{pluralize(@no_track_confirmed.count, 'event')} not assigned to a track"
- else
%h5 All events assigned to track!
.row-fluid
.span12#events_tracks_confirmed
= render :partial => "events_tracks_confirmed"

View file

@ -1,79 +0,0 @@
<style>
.arc path {
stroke: #fff;
}
</style>
<script>
var width = 250,
height = 250,
radius = Math.min(width, height) / 2;
var color = d3.scale.ordinal()
.range(["#5254a3", "#6b6ecf", "#9c9ede "]);
var arc = d3.svg.arc()
.outerRadius(radius - 10)
.innerRadius(0);
var pie = d3.layout.pie()
.sort(null)
.value(function(d) { return d.value; });
// Where to put the chart
var svg = d3.select("#events_tracks_confirmed").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var data = <%=raw @track_state['confirmed'].to_json%>;
var g = svg.selectAll(".arc")
.data(pie(data))
.enter().append("g")
.attr("class", "arc");
g.append("path")
.attr("d", arc)
.style("fill", function(d) { return color(d.data.status); });
// Put text inside every piece of the pie-chart
g.append("text")
.attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")"; })
.attr("dy", ".35em")
.style("text-anchor", "middle")
.text(function(d) { return d.data.status; });
// Title of chart
svg.append("text")
.attr("class", "title")
.attr("x", radius)
.attr("y", -radius+10)
.text("% of pre-registered");
// Create & position legend
var legend = d3.select("#events_tracks_confirmed").append("svg")
.attr("class", "legend")
.attr("width", radius*2)
.attr("height", radius)
.selectAll("g")
.data(color.domain().slice().reverse())
.enter().append("g")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("rect")
.attr("width", 18)
.attr("height", 18)
.style("fill", color);
legend.append("text")
.attr("x", 24)
.attr("y", 9)
.attr("dy", ".15em")
.text(function(d) { return d + " (" + data.filter(function(v){return v.status === d;})[0].value + " or " + data.filter(function(v){return v.status === d;})[0].percent + "%)" ; });
</script>

View file

@ -1,79 +0,0 @@
<style>
.arc path {
stroke: #fff;
}
</style>
<script>
var width = 250,
height = 250,
radius = Math.min(width, height) / 2;
var color = d3.scale.ordinal()
.range(["#5254a3", "#6b6ecf", "#9c9ede "]);
var arc = d3.svg.arc()
.outerRadius(radius - 10)
.innerRadius(0);
var pie = d3.layout.pie()
.sort(null)
.value(function(d) { return d.value; });
// Where to put the chart
var svg = d3.select("#events_tracks_new").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var data = <%=raw @track_state['new'].to_json%>;
var g = svg.selectAll(".arc")
.data(pie(data))
.enter().append("g")
.attr("class", "arc");
g.append("path")
.attr("d", arc)
.style("fill", function(d) { return color(d.data.status); });
// Put text inside every piece of the pie-chart
g.append("text")
.attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")"; })
.attr("dy", ".35em")
.style("text-anchor", "middle")
.text(function(d) { return d.data.status; });
// Title of chart
svg.append("text")
.attr("class", "title")
.attr("x", radius)
.attr("y", -radius+10)
.text("% of pre-registered");
// Create & position legend
var legend = d3.select("#events_tracks_new").append("svg")
.attr("class", "legend")
.attr("width", radius*2)
.attr("height", radius)
.selectAll("g")
.data(color.domain().slice().reverse())
.enter().append("g")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("rect")
.attr("width", 18)
.attr("height", 18)
.style("fill", color);
legend.append("text")
.attr("x", 24)
.attr("y", 9)
.attr("dy", ".15em")
.text(function(d) { return d + " (" + data.filter(function(v){return v.status === d;})[0].value + " or " + data.filter(function(v){return v.status === d;})[0].percent + "%)" ; });
</script>

View file

@ -1,79 +0,0 @@
<style>
.arc path {
stroke: #fff;
}
</style>
<script>
var width = 250,
height = 250,
radius = Math.min(width, height) / 2;
var color = d3.scale.ordinal()
.range(["#5254a3", "#6b6ecf", "#9c9ede "]);
var arc = d3.svg.arc()
.outerRadius(radius - 10)
.innerRadius(0);
var pie = d3.layout.pie()
.sort(null)
.value(function(d) { return d.value; });
// Where to put the chart
var svg = d3.select("#events_tracks_unconfirmed").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var data = <%=raw @track_state['unconfirmed'].to_json%>;
var g = svg.selectAll(".arc")
.data(pie(data))
.enter().append("g")
.attr("class", "arc");
g.append("path")
.attr("d", arc)
.style("fill", function(d) { return color(d.data.status); });
// Put text inside every piece of the pie-chart
g.append("text")
.attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")"; })
.attr("dy", ".35em")
.style("text-anchor", "middle")
.text(function(d) { return d.data.status; });
// Title of chart
svg.append("text")
.attr("class", "title")
.attr("x", radius)
.attr("y", -radius+10)
.text("% of pre-registered");
// Create & position legend
var legend = d3.select("#events_tracks_unconfirmed").append("svg")
.attr("class", "legend")
.attr("width", radius*2)
.attr("height", radius)
.selectAll("g")
.data(color.domain().slice().reverse())
.enter().append("g")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("rect")
.attr("width", 18)
.attr("height", 18)
.style("fill", color);
legend.append("text")
.attr("x", 24)
.attr("y", 9)
.attr("dy", ".15em")
.text(function(d) { return d + " (" + data.filter(function(v){return v.status === d;})[0].value + " or " + data.filter(function(v){return v.status === d;})[0].percent + "%)" ; });
</script>

View file

@ -1,19 +0,0 @@
.row-fluid
- if !@type_state['new'].empty?
.span4
%h4 New Submissions: #{@type_state['new'].map{|x| x["value"]}.sum}
.row-fluid
.span12#events_types_new
= render :partial => "events_types_new"
- if !@type_state['unconfirmed'].empty?
.span4
%h4 Accepted (Unconfirmed): #{@type_state['unconfirmed'].map{|x| x["value"]}.sum}
.row-fluid
.span12#events_types_unconfirmed
= render :partial => "events_types_unconfirmed"
- if !@type_state['confirmed'].empty?
.span4
%h4 Accepted (Confirmed): #{@type_state['confirmed'].map{|x| x["value"]}.sum}
.row-fluid
.span12#events_types_confirmed
= render :partial => "events_types_confirmed"

View file

@ -1,78 +0,0 @@
<style>
.arc path {
stroke: #fff;
}
</style>
<script>
var width = 250,
height = 250,
radius = Math.min(width, height) / 2;
var color = d3.scale.category20();
var arc = d3.svg.arc()
.outerRadius(radius - 10)
.innerRadius(0);
var pie = d3.layout.pie()
.sort(null)
.value(function(d) { return d.value; });
// Where to put the chart
var svg = d3.select("#events_types_confirmed").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var data = <%=raw @type_state['confirmed'].to_json%>;
var g = svg.selectAll(".arc")
.data(pie(data))
.enter().append("g")
.attr("class", "arc");
g.append("path")
.attr("d", arc)
.style("fill", function(d) { return color(d.data.status); });
// Put text inside every piece of the pie-chart
g.append("text")
.attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")"; })
.attr("dy", ".35em")
.style("text-anchor", "middle")
.text(function(d) { return d.data.status; });
// Title of chart
svg.append("text")
.attr("class", "title")
.attr("x", radius)
.attr("y", -radius+10)
.text("% of pre-registered");
// Create & position legend
var legend = d3.select("#events_types_confirmed").append("svg")
.attr("class", "legend")
.attr("width", radius*2)
.attr("height", radius)
.selectAll("g")
.data(color.domain().slice().reverse())
.enter().append("g")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("rect")
.attr("width", 18)
.attr("height", 18)
.style("fill", color);
legend.append("text")
.attr("x", 24)
.attr("y", 9)
.attr("dy", ".15em")
.text(function(d) { return d + " (" + data.filter(function(v){return v.status === d;})[0].value + " or " + data.filter(function(v){return v.status === d;})[0].percent + "%)" ; });
</script>

View file

@ -1,78 +0,0 @@
<style>
.arc path {
stroke: #fff;
}
</style>
<script>
var width = 250,
height = 250,
radius = Math.min(width, height) / 2;
var color = d3.scale.category20();
var arc = d3.svg.arc()
.outerRadius(radius - 10)
.innerRadius(0);
var pie = d3.layout.pie()
.sort(null)
.value(function(d) { return d.percent; });
// Where to put the chart
var svg = d3.select("#events_types_new").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var data = <%=raw @type_state['new'].to_json%>;
var g = svg.selectAll(".arc")
.data(pie(data))
.enter().append("g")
.attr("class", "arc");
g.append("path")
.attr("d", arc)
.style("fill", function(d) { return color(d.data.status); });
// Put text inside every piece of the pie-chart
g.append("text")
.attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")"; })
.attr("dy", ".35em")
.style("text-anchor", "middle")
.text(function(d) { return d.data.status; });
// Title of chart
svg.append("text")
.attr("class", "title")
.attr("x", radius)
.attr("y", -radius+10)
.text("% of pre-registered");
// Create & position legend
var legend = d3.select("#events_types_new").append("svg")
.attr("class", "legend")
.attr("width", radius*2)
.attr("height", radius)
.selectAll("g")
.data(color.domain().slice().reverse())
.enter().append("g")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("rect")
.attr("width", 18)
.attr("height", 18)
.style("fill", color);
legend.append("text")
.attr("x", 24)
.attr("y", 9)
.attr("dy", ".15em")
.text(function(d) { return d + " (" + data.filter(function(v){return v.status === d;})[0].value + " or " + data.filter(function(v){return v.status === d;})[0].percent + "%)" ; });
</script>

View file

@ -1,78 +0,0 @@
<style>
.arc path {
stroke: #fff;
}
</style>
<script>
var width = 250,
height = 250,
radius = Math.min(width, height) / 2;
var color = d3.scale.category20();
var arc = d3.svg.arc()
.outerRadius(radius - 10)
.innerRadius(0);
var pie = d3.layout.pie()
.sort(null)
.value(function(d) { return d.value; });
// Where to put the chart
var svg = d3.select("#events_types_unconfirmed").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var data = <%=raw @type_state['unconfirmed'].to_json%>;
var g = svg.selectAll(".arc")
.data(pie(data))
.enter().append("g")
.attr("class", "arc");
g.append("path")
.attr("d", arc)
.style("fill", function(d) { return color(d.data.status); });
// Put text inside every piece of the pie-chart
g.append("text")
.attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")"; })
.attr("dy", ".35em")
.style("text-anchor", "middle")
.text(function(d) { return d.data.status; });
// Title of chart
svg.append("text")
.attr("class", "title")
.attr("x", radius)
.attr("y", -radius+10)
.text("% of pre-registered");
// Create & position legend
var legend = d3.select("#events_types_unconfirmed").append("svg")
.attr("class", "legend")
.attr("width", radius*2)
.attr("height", radius)
.selectAll("g")
.data(color.domain().slice().reverse())
.enter().append("g")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("rect")
.attr("width", 18)
.attr("height", 18)
.style("fill", color);
legend.append("text")
.attr("x", 24)
.attr("y", 9)
.attr("dy", ".15em")
.text(function(d) { return d + " (" + data.filter(function(v){return v.status === d;})[0].value + " or " + data.filter(function(v){return v.status === d;})[0].percent + "%)" ; });
</script>

View file

@ -1,70 +0,0 @@
<script>
var registered = '<%= h @registrations.count%>';
var data = <%=raw @other_info.to_json %>;
var valueLabelWidth = 70; // space reserved for value labels (right)
var barHeight = 24; // height of one bar
var barLabelWidth = 210; // space reserved for bar labels
var barLabelPadding = 8; // padding between bar and bar labels (left)
var gridLabelHeight = 18; // space reserved for gridline labels
var gridChartOffset = 3; // space between start of grid and first bar
var maxBarWidth = 350; // width of the bar with the max value
var color = d3.scale.category20();
// accessor functions
var barLabel = function(d) { return d['status']; };
var barValue = function(d) { return d['value'] / registered * 100; };
var barValues = function(d) { return d['value']; };
// scales
var yScale = d3.scale.ordinal().domain(d3.range(0, data.length)).rangeBands([0, data.length * barHeight]);
var y = function(d, i) { return yScale(i); };
var yText = function(d, i) { return y(d, i) + yScale.rangeBand() / 2; };
var yMax = d3.max(data, function(d){ return barValue(d) + 15; });
var x = d3.scale.linear().domain([0, yMax]).range([0, maxBarWidth]);
// svg container element
var chart = d3.select('#other_info').append("svg")
.attr('width', maxBarWidth + barLabelWidth + valueLabelWidth)
.attr('height', gridLabelHeight + gridChartOffset + data.length * barHeight);
// bar labels
var labelsContainer = chart.append('g')
.attr('transform', 'translate(' + (barLabelWidth - barLabelPadding) + ',' + (gridLabelHeight + gridChartOffset) + ')');
labelsContainer.selectAll('text').data(data).enter().append('text')
.attr('y', yText)
.attr('stroke', 'none')
.attr('fill', 'black')
.attr("dy", ".35em") // vertical-align: middle
.attr('text-anchor', 'end')
.text(barLabel);
// bars
var barsContainer = chart.append('g')
.attr('transform', 'translate(' + barLabelWidth + ',' + (gridLabelHeight + gridChartOffset) + ')');
barsContainer.selectAll("rect").data(data).enter().append("rect")
.attr('y', y)
.attr('height', yScale.rangeBand())
.attr('width', function(d) { return x(barValue(d)); })
.attr('stroke', 'white')
.attr('fill', function(d) { return color(barLabel(d)); });
// bar value labels
barsContainer.selectAll("text").data(data).enter().append("text")
.attr("x", 5)
.attr("y", yText)
.attr("dx", 3) // padding-left
.attr("dy", ".35em") // vertical-align: middle
.attr("text-anchor", "start") // text-align: right
.attr("fill", "black")
.attr("stroke", "none")
.text(function(d) { return d3.round(barValues(d), 2) + " (" + d3.round(barValue(d), 0) + "%)"; });
// start line
barsContainer.append("line")
.attr("y1", -gridChartOffset)
.attr("y2", yScale.rangeExtent()[1] + gridChartOffset)
.style("stroke", "#000");
</script>

View file

@ -1,85 +0,0 @@
<style>
.arc path {
stroke: #fff;
}
</style>
<script>
var width = 250,
height = 250,
radius = Math.min(width, height) / 2;
var color = d3.scale.ordinal()
.range(["#9ECAE1", "#6baed6", "#DEEBF7"]);
var arc = d3.svg.arc()
.outerRadius(radius - 10)
.innerRadius(0);
var pie = d3.layout.pie()
.sort(null)
.value(function(d) { return d.value; });
// Where to put the chart
var svg = d3.select("#preregistered_onsite").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var total = '<%= h @registrations.count %>';
var pre_registered = '<%= h @pre_registered %>';
var onsite = '<%= h @registrations.count - @pre_registered %>';
var data = [
{"status":"onsite","value": onsite, "percent": d3.round(onsite / total * 100)},
{"status":"pre_registered","value":pre_registered, "percent": d3.round(pre_registered / total * 100)}
];
var g = svg.selectAll(".arc")
.data(pie(data))
.enter().append("g")
.attr("class", "arc");
g.append("path")
.attr("d", arc)
.style("fill", function(d) { return color(d.data.status); });
// Put text inside every piece of the pie-chart
g.append("text")
.attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")"; })
.attr("dy", ".35em")
.style("text-anchor", "middle")
.text(function(d) { return d.data.percent +"%"; });
// Title of chart
svg.append("text")
.attr("class", "title")
.attr("x", radius)
.attr("y", -radius+10)
.text("% of pre-registered");
// Create & position legend
var legend = d3.select("#preregistered_onsite").append("svg")
.attr("class", "legend")
.attr("width", radius * 2)
.attr("height", radius)
.selectAll("g")
.data(color.domain().slice().reverse())
.enter().append("g")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("rect")
.attr("width", 18)
.attr("height", 18)
.style("fill", color);
legend.append("text")
.attr("x", 24)
.attr("y", 9)
.attr("dy", ".15em")
.text(function(d) { return d + " (" + data.filter(function(v){return v.status === d;})[0].value + " or " + data.filter(function(v){return v.status === d;})[0].percent + "%)" ; });
</script>

View file

@ -1,85 +0,0 @@
<style>
.arc path {
stroke: #fff;
}
</style>
<script>
var width = 250,
height = 250,
radius = Math.min(width, height) / 2;
var color = d3.scale.ordinal()
.range(["#9ECAE1", "#6baed6", "#DEEBF7"]);
var arc = d3.svg.arc()
.outerRadius(radius - 10)
.innerRadius(0);
var pie = d3.layout.pie()
.sort(null)
.value(function(d) { return d.value; });
// Where to put the chart
var svg = d3.select("#registered_attended").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var registered = '<%= h @pre_registered%>';
var attended = '<%= h @pre_registered_attended %>';
var not_attended = '<%= h @pre_registered - @pre_registered_attended %>';
var data = [
{"status":"did not attend","value":not_attended, "percent": d3.round(not_attended / registered * 100)},
{"status":"attended","value": attended, "percent": d3.round(attended / registered * 100)}
];
var g = svg.selectAll(".arc")
.data(pie(data))
.enter().append("g")
.attr("class", "arc");
g.append("path")
.attr("d", arc)
.style("fill", function(d) { return color(d.data.status); });
// Put text inside every piece of the pie-chart
g.append("text")
.attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")"; })
.attr("dy", ".35em")
.style("text-anchor", "middle")
.text(function(d) { return d.data.percent +"%"; });
// Title of chart
svg.append("text")
.attr("class", "title")
.attr("x", radius)
.attr("y", -radius+10)
.text("% of pre-registered");
// Create & position legend
var legend = d3.select("#registered_attended").append("svg")
.attr("class", "legend")
.attr("width", radius*2)
.attr("height", radius)
.selectAll("g")
.data(color.domain().slice().reverse())
.enter().append("g")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("rect")
.attr("width", 18)
.attr("height", 18)
.style("fill", color);
legend.append("text")
.attr("x", 24)
.attr("y", 9)
.attr("dy", ".15em")
.text(function(d) { return d + " (" + data.filter(function(v){return v.status === d;})[0].value + " or " + data.filter(function(v){return v.status === d;})[0].percent + "%)" ; });
</script>

View file

@ -1,71 +0,0 @@
<script>
var registered = '<%= h @registrations.count%>';
var data = <%=raw @registered_time.to_json %>;
var valueLabelWidth = 10; // space reserved for value labels (right)
var barHeight = 24; // height of one bar
var barLabelWidth = 100; // space reserved for bar labels
var barLabelPadding = 8; // padding between bar and bar labels (left)
var gridLabelHeight = 18; // space reserved for gridline labels
var gridChartOffset = 3; // space between start of grid and first bar
var maxBarWidth = 420; // width of the bar with the max value
var color = d3.scale.category20();
// accessor functions
var barLabel = function(d) { return d['status']; };
var barValue = function(d) { return d['value'] / registered * 100; };
var barValues = function(d) { return d['value']; };
// scales
var yScale = d3.scale.ordinal().domain(d3.range(0, data.length)).rangeBands([0, data.length * barHeight]);
var y = function(d, i) { return yScale(i); };
var yText = function(d, i) { return y(d, i) + yScale.rangeBand() / 2; };
var yMax = d3.max(data, function(d){ return barValue(d) + 15; });
var x = d3.scale.linear().domain([0, yMax]).range([0, maxBarWidth]);
var width = maxBarWidth + barLabelWidth + valueLabelWidth;
// svg container element
var chart = d3.select('#registered_time').append("svg")
.attr('width', maxBarWidth + barLabelWidth + valueLabelWidth)
.attr('height', gridLabelHeight + gridChartOffset + data.length * barHeight);
// bar labels
var labelsContainer = chart.append('g')
.attr('transform', 'translate(' + (barLabelWidth - barLabelPadding) + ',' + (gridLabelHeight + gridChartOffset) + ')');
labelsContainer.selectAll('text').data(data).enter().append('text')
.attr('y', yText)
.attr('stroke', 'none')
.attr('fill', 'black')
.attr("dy", ".35em") // vertical-align: middle
.attr('text-anchor', 'end')
.text(barLabel);
// bars
var barsContainer = chart.append('g')
.attr('transform', 'translate(' + barLabelWidth + ',' + (gridLabelHeight + gridChartOffset) + ')');
barsContainer.selectAll("rect").data(data).enter().append("rect")
.attr('y', y)
.attr('height', yScale.rangeBand())
.attr('width', function(d) { return x(barValue(d)); })
.attr('stroke', 'white')
.attr('fill', function(d) { return color(barValue(d)); });
// bar value labels
barsContainer.selectAll("text").data(data).enter().append("text")
.attr("x", 5)
.attr("y", yText)
.attr("dx", 3) // padding-left
.attr("dy", ".35em") // vertical-align: middle
.attr("text-anchor", "start") // text-align: right
.attr("fill", "black")
.attr("stroke", "none")
.text(function(d) { return d3.round(barValues(d), 2) + " (" + d3.round(barValue(d), 0) + "%)"; });
// start line
barsContainer.append("line")
.attr("y1", -gridChartOffset)
.attr("y2", yScale.rangeExtent()[1] + gridChartOffset)
.style("stroke", "#000");
</script>

View file

@ -1,41 +0,0 @@
.row
.col-md-4
- if @registered > 0
- if @attendees > 0
%h4{:style => "text-indent: 25px"}= "Registrations - Attendees (#{(@attendees.to_f / @registered * 100).round }%)"
- else
%h4{:style => "text-indent: 25px"}= "Registrations - Attendees"
.row-fluid
.span12#registrations_attendees
= render :partial => "registrations_attendees"
- else
%h5 There are no registrations yet.
.col-md-4
- if @registered > 0
%h4{:style => "text-indent: 10px"}= "Attendance of pre-registered"
.row-fluid
.span12#registered_attended
= render :partial => "registered_attended"
.col-md-4
- if @registered > 0
%h4{:style => "text-indent: 25px"}= "% of pre-registered"
.row-fluid
.span12#preregistered_onsite
= render :partial => "preregistered_onsite"
.row
.col-md-6
- if @registered > 0
%h4= "Other Info"
.row-fluid
.span12#other_info
= render :partial => "other_info"
.col-md-6
- if @registered > 0
%h4{:style => "text-indent: 98px"}= "Registrations over time"
.row-fluid
.span12#registered_time
= render :partial => "registered_time"

View file

@ -1,77 +0,0 @@
<script>
var w = 250,
h = 250,
r = Math.min(w, h) / 2 - 10,
inner = 80,
color = d3.scale.category20c();
var registrations = '<%= h @registered %>';
var attendees = '<%= h @attendees %>';
var data = [
{"status":"Did Not Attend","value": registrations-attendees, "percent": ""},
{"status":"Attended","value": attendees, "percent": d3.round(attendees/registrations * 100)+"%"}
];
var vis = d3.select("#registrations_attendees")
.append("svg:svg")
.data([data])
.attr("width", w)
.attr("height", h)
.append("svg:g")
.attr("transform", "translate(" + r * 1.1 + "," + r * 1.1 + ")")
var textTop = vis.append("text")
.attr("dy", ".35em")
.style("text-anchor", "middle")
.attr("class", "textTop")
.text( "Registered: " + registrations)
.attr("y", -10),
textBottom = vis.append("text")
.attr("dy", ".35em")
.style("text-anchor", "middle")
.attr("class", "textBottom")
.text("Attended: " + attendees)
.attr("y", 10);
var arc = d3.svg.arc()
.innerRadius(inner)
.outerRadius(r);
var arcOver = d3.svg.arc()
.innerRadius(inner + 5)
.outerRadius(r + 5);
var pie = d3.layout.pie()
.value(function(d) { return d.value; });
var arcs = vis.selectAll("g.slice")
.data(pie)
.enter()
.append("svg:g")
.attr("class", "slice");
arcs.append("svg:path")
.attr("fill", function(d, i) { return color(i); } )
.attr("d", arc);
var legend = d3.select("#registrations_attendees").append("svg")
.attr("class", "legend")
.attr("width", r * 2)
.attr("height", r)
.selectAll("g")
.data(data)
.enter().append("g")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("rect")
.attr("width", 18)
.attr("height", 18)
.style("fill", function(d, i) { return color(i); });
legend.append("text")
.attr("x", 24)
.attr("y", 9)
.attr("dy", ".35em")
.text(function(d) { return "Total " + d.status + " (" + d.value + ")"; });
</script>

View file

@ -1,37 +0,0 @@
- count =0
%h3
Speakers (#{@speakers.length})
%table.table.table-striped.table-bordered.table-hover#speakertable
%thead
%th
ID
- (@speaker_fields_user + @speaker_fields_reg).each do |field|
%th
= field.capitalize
- @speakers.each do |speaker|
%tr
%td
= count +=1
- @speaker_fields_user.each do |field|
%td
= speaker.send(field.to_sym)
- @speaker_fields_reg.each do |field|
%td
- reg = speaker_reg(speaker)
- if !reg.nil?
- if field == "diet"
- if reg.dietary_choice_id
= speaker_diet(reg).title
%br
= reg.other_dietary_choice
- elsif field == 'arrival' || field == 'departure'
= getdatetime(reg, field)
- else
= reg.send(field.to_sym)
:javascript
$(document).ready(function(){
$('#speakertable').dataTable({
"bPaginate": false
});
});

View file

@ -1,22 +0,0 @@
- if @tickets.length > 0
.row-fluid
.span12
%h2
= "Non-Free Tickets (#{@tickets.count})"
.row-fluid
.span4
%h4 Ticket distribution
.row-fluid
.span12#tickets_distribution
= render :partial => "tickets_distribution"
.row-fluid
.span10
%h4 Ticket sales over time
.row-fluid
.span12#tickets_time
= render :partial => "tickets_time"
- else
- if @conference.use_supporter_levels
%h5 No tickets have been bought yet.
- else
%h5 There are no tickets set for this conference.

View file

@ -1,79 +0,0 @@
<style>
.arc path {
stroke: #fff;
}
</style>
<script>
var width = 250,
height = 250,
radius = Math.min(width, height) / 2;
var color = d3.scale.ordinal()
.range(["#9ECAE1", "#6baed6", "#DEEBF7"]);
var arc = d3.svg.arc()
.outerRadius(radius - 10)
.innerRadius(0);
var pie = d3.layout.pie()
.sort(null)
.value(function(d) { return d.value; });
// Where to put the chart
var svg = d3.select("#tickets_distribution").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var data = <%=raw @tickets_distribution.to_json %>;
var g = svg.selectAll(".arc")
.data(pie(data))
.enter().append("g")
.attr("class", "arc");
g.append("path")
.attr("d", arc)
.style("fill", function(d) { return color(d.data.status); });
// Put text inside every piece of the pie-chart
g.append("text")
.attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")"; })
.attr("dy", ".35em")
.style("text-anchor", "middle")
.text(function(d) { return d.data.percent +"%"; });
// Title of chart
svg.append("text")
.attr("class", "title")
.attr("x", radius)
.attr("y", -radius+10)
.text("% of pre-registered");
// Create & position legend
var legend = d3.select("#tickets_distribution").append("svg")
.attr("class", "legend")
.attr("width", radius * 2)
.attr("height", radius)
.selectAll("g")
.data(color.domain().slice().reverse())
.enter().append("g")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("rect")
.attr("width", 18)
.attr("height", 18)
.style("fill", color);
legend.append("text")
.attr("x", 24)
.attr("y", 9)
.attr("dy", ".15em")
.text(function(d) { return d + " (" + data.filter(function(v){return v.status === d;})[0].value + " or " + data.filter(function(v){return v.status === d;})[0].percent + "%)" ; });
</script>

View file

@ -1 +0,0 @@
(Not yet implemented)

View file

@ -1,27 +0,0 @@
.row
.col-md-12
%ul.nav.nav-tabs#myTab
%li.active
%a{:href=>"#registrations", "data-toggle"=>"tab"} Registrations
%li
%a{:href=>"#events", "data-toggle"=>"tab"} Events
%li
%a{:href=>"#speakers", "data-toggle"=>"tab"} Speakers
%li
%a{:href=>"#tickets", "data-toggle"=>"tab"} Tickets
.tab-content
.tab-pane.active#registrations
= render :partial => 'registrations'
.tab-pane#events
= render :partial => 'events'
.tab-pane#speakers
= render :partial => 'speakers'
.tab-pane#tickets
= render :partial => 'tickets'
:javascript
$('#myTab a').click(function (e) {
e.preventDefault();
$(this).tab('show');
})