line.font = File.expand_path('/usr/X11R6/lib/X11/fonts/TTF/Vera.ttf',
RAILS_ROOT)
- line.data("#{@election.name}", data )
+ line.data( "#{@election.name}", data )
line.labels = labels
line.x_axis_label = "Date"
line.y_axis_label = "Number of Votes"
line.minimum_value = 0.0
- line.draw
send_data(line.to_blob, :disposition => 'inline', :type => 'image/png')
end
#will place votes in a fixed number of intervals, and shows votes over time
def votes_per_interval
@election = Election.find(params[:id])
- data, labels = get_votes_per_interval_data(@election)
+ data, labels, scale = get_votes_per_interval_data(@election)
line = Gruff::Line.new("700x400")
line.theme = { :background_colors => ['#73BF26', '#ffffff'] }
line.data("#{@election.name}", data )
line.labels = labels
- line.x_axis_label = "Intervals"
+ line.x_axis_label = scale
line.y_axis_label = "Number of Votes"
line.minimum_value = 0.0
- line.draw
send_data(line.to_blob, :disposition => 'inline', :type => 'image/png')
end
def borda_bar
@election = Election.find(params[:id])
+ pref_tally = make_preference_tally(@election)
+
+ @borda_result = BordaVote.new(pref_tally).result
+ data, labels = get_borda_points(@borda_result)
- #Get the list of candidates from the election, and calculate how RubyVote
- #gave each one points
- @election.candidates.each do |candidate|
+ bar = Gruff::Bar.new("700x400")
+ bar.theme = { :background_colors => ['#73BF26', '#ffffff'] }
+ bar.title = "Points Per Candidate"
+ bar.font = File.expand_path('/usr/X11R6/lib/X11/fonts/TTF/Vera.ttf',
+ RAILS_ROOT)
+
+ bar.data("#{@election.name}", data)
+ bar.labels = labels
- #Tabulate how many points each candidate received
- #Make the name of each candidate a label under the correspoding column
- #done!
+ bar.y_axis_label = "Points"
+ bar.x_axis_label = "Candidate"
+ bar.minimum_value = 0.0
+ send_data(bar.to_blob, :disposition => 'inline', :type => 'image/png')
end
-
private
-
+
# generate the data and labels for each graph
def get_votes_per_day_data(election)
voter_days = Array.new
labels_hash = Hash.new
buckets = Hash.new
total_per_interval = Array.new
+ interval_type = ""
starttime = election.startdate
timedelta = Time.now - starttime
labels_hash[0] = starttime.min.to_s
labels_hash[(numcols/2)-1] = (starttime + (timedelta/2)).min.to_s
labels_hash[numcols-1] = Time.now.min.to_s
+ interval_type = "Minutes"
elsif timedelta < 2.days #more than 2 hours means use hours for labels
labels_hash[0] = starttime.hour.to_s
labels_hash[(numcols/2)-1] = (starttime + (timedelta/2)).hour.to_s
labels_hash[numcols-1] = Time.now.hour.to_s
+ interval_type = "Hours"
else #more than 2 days means use dates for labels
labels_hash[0] = (Date.parse(starttime.to_s)).to_s
labels_hash[(numcols/2)-1] = (Date.parse(starttime + (timedelta/2))).to_s
labels_hash[numcols-1] = (Date.today).to_s
+ interval_type = "Days"
end
# Make sure to return an array for data and hash for labels
- return total_per_interval, labels_hash
+ return total_per_interval, labels_hash, interval_type
+ end
+
+ def get_borda_points(result)
+ #points holds how mnay points each candidate has received in array form
+ #becasue Gruff::Bar#data takes only an array
+ points = Array.new
+ labels = Hash.new
+
+ #Populate points with an sorted array from election.votes hash
+ #biggest to smallest will go from left to right
+ points = result.election.votes.sort do |a, b|
+ b[1] <=> a[1]
+ end.collect {|i| i[1]}
+
+ #make the labels
+ result.ranked_candidates.each_with_index do |candidate, index|
+ labels[index] = Candidate.find(candidate).name
+ end
+
+ return points, labels
+ end
+
+ #most vote result objects require an array of vote arrays, which this will make
+ def make_preference_tally(election)
+ preference_tally = Array.new
+ @election.voters.each do |voter|
+ next unless voter.voted?
+ preference_tally << voter.vote.rankings.sort.collect \
+ { |ranking| ranking.candidate.id }
+ end
+ return preference_tally
end
end
# if the voter has not voted we destroy them
if @voter and not @voter.voted?
@voter.destroy
- @voter = nil
+ @voter = nil
end
# if the voter does not exist or has has been destroyed, lets
@voter = QuickVoter.new
@voter.election = QuickVote.find_all( [ "name = ?", params[:votename] ] )[0]
@voter.session_id = session.session_id
-
- # create new vote and make it the defaulted sorted list
+
+ # create new vote and make it the defaulted sorted list
@voter.vote = Vote.new
- @voter.save
- @voter.vote.set_defaults!
- @voter.reload
+ @voter.save
+ @voter.vote.set_defaults!
+ @voter.reload
end
else
redirect_to :controller => 'site'
# find out who the voter is for this election
@voter = QuickVoter.find_all(["session_id = ? and election_id = ?",
- session.session_id, election.id])[0]
-
+ session.session_id, election.id])[0]
+
if not @voter
# we have not seen this voter before. something is wrong, try
# again
redirect_to quickvote_url( :votename => params[:votename] )
- elsif @voter.voted?
+ elsif @voter.voted?
# this person has already voted, we try again
flash[:notice] = "You have already voted!"
redirect_to quickvote_url( :votename => params[:votename] )
@voter.ipaddress = request.env["REMOTE_ADDR"]
@voter.save
- # save the time the vote was made for statistical use, it doesn't
- #work here unless I use a method that will save it to the db
+ # save the time the vote was made for statistical use
@voter.vote.time = Time.now
# toggle the confirmation bit
###############################################################
def results
- @election = QuickVote.find_all( ["name = ?", params[:votename]] )[0]
+ @election = QuickVote.find_all(["name = ?", params[:votename]] )[0]
# initalize the tallies to empty arrays
preference_tally = Array.new