Modified graphs to ahve a 4 color scheme, but it isn't the full palette of selectrici...
author<jlsharps@mit.edu> <>
Wed, 15 Aug 2007 21:46:20 +0000 (17:46 -0400)
committer<jlsharps@mit.edu> <>
Wed, 15 Aug 2007 21:46:20 +0000 (17:46 -0400)
, that will be on next commit. LAso modified several voting methods within RubyVote to have
more useful instance variables and accessors available in the results class. the quickvote
results view has been updated to include a partial for displaying a condorcet vote table, w
hich is strangely appearing below the footer on the results page, it seems to be displaying
 the correct data however.

.bzrignore
app/controllers/graph_controller.rb
app/views/quickvote/_pref_table.rhtml [new file with mode: 0644]
app/views/quickvote/results.rhtml
lib/rubyvote/condorcet.rb
lib/rubyvote/election.rb
lib/rubyvote/positional.rb

index 50c7c5ba8cc8ca7b0f3545691aeffc39ad617653..1e24ca1b87d4ae5f09a2ecb818ea9d3fadf41bdc 100644 (file)
@@ -5,3 +5,4 @@ server.log
 test.log
 tmp
 public/engine_files
+.DS_Store
index 825688476485d114f1583cdb6774c6962e40528d..bbd5cd79f9f4934d0e9f878046e8f88851a41155 100644 (file)
@@ -7,13 +7,19 @@ class GraphController < ApplicationController
       size = "700x400"
       @graph = options[:graph_type].new(size)
 
-      @graph.theme = { :background_colors => ['#73BF26', '#ffffff'] }
+      @graph.theme = { :colors => ['#000000', '#00FFFF', '#FFCC00', '#990033'],
+                       :background_colors => ['#74ce00', '#ffffff'] }
       @graph.font = File.expand_path('/usr/X11R6/lib/X11/fonts/TTF/Vera.ttf',
                                    RAILS_ROOT)
       
       # fill in the data with the optional data name
-      #Check to see if multiple datasets, if so, fill them all!     
-      if options[:data].size > 1 && options[:data].all?  {|i| i.is_a?(Array)}
+      #Check to see if multiple datasets, if so, fill them all!
+      if options[:data].is_a?(Hash) 
+        options[:data].each_pair do |name, array|
+          @graph.data( name, array)
+        end
+      #if each dataset nameless, will have only multiple arrays    
+      elsif options[:data].size > 1 && options[:data].all?  {|i| i.is_a?(Array)}
         options[:data].each do |array|
           @graph.data( options.fetch(:data_name, "Data"), array)
         end
@@ -73,10 +79,10 @@ class GraphController < ApplicationController
 
   def borda_bar
     @election = Election.find(params[:id])
-    pref_tally = make_preference_tally(@election)
+    #pref_tally = make_preference_tally(@election)
     
-    @borda_result = BordaVote.new(pref_tally).result
-    data, labels = get_borda_points(@borda_result)
+    #@borda_result = BordaVote.new(pref_tally).result
+    data, labels = get_borda_points(@election.borda_result)
     
     graph = GruffGraff.new( :graph_type => Gruff::Bar,
                             :data_name => @election.name,
@@ -87,16 +93,22 @@ class GraphController < ApplicationController
                             :x_axis_label => "Candidate")
     send_data(*graph.output)
   end
-  def choices_positions
+  #Acording to Tufte, small, concomparitive, highly labeled data sets usually
+  # belong in tables. The following is a bar graph...but would it be better
+  #as a table?
+  def choices_positions 
     @election = Election.find(params[:id])
     pref_tally = make_preference_tally(@election)
     
     fulldata, labels = get_positions_info(@election)
-    labels = @candidates
+    legend = Hash.new
+    
+    @election.candidates.each_with_index do |candidate, index|
+      legend[candidate.name] = fulldata[index]
+    end
+    
     graph = GruffGraff.new( :graph_type => Gruff::Bar,
-                            :data_name => @election.name,
-                            :data => fulldata,
+                            :data => legend,
                             :interval_labels => labels,
                             :title => "Times Voted in Each Position",
                             :y_axis_label => "Number of Times Ranked",
@@ -133,7 +145,7 @@ class GraphController < ApplicationController
         rank_labels[i] = (i+1).to_s
       end
     end
-   
+    
     return buckets2.values, rank_labels
     
   end
@@ -236,8 +248,6 @@ class GraphController < ApplicationController
   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
 
diff --git a/app/views/quickvote/_pref_table.rhtml b/app/views/quickvote/_pref_table.rhtml
new file mode 100644 (file)
index 0000000..dfcb6cc
--- /dev/null
@@ -0,0 +1,19 @@
+<% candidates = @election.candidates.sort.collect {|candidate| candidate.id} -%>
+<table class="voterbox">
+  <tr>
+       <td> </td>
+       <% candidates.each do |candidate| -%>
+         <th><%= candidate -%></th>
+       <% end -%>
+<% candidates.each do |winner| -%>
+  <tr>
+       <th><%= winner %></th>
+  <% candidates.each do |loser| -%> 
+    <% if winner == loser -%>
+      <td> -- </td>
+    <% else %>         
+      <td><%= @election.condorcet_result.matrix[winner][loser] %></td>
+    <% end -%>
+  <% end -%>
+ </tr>
+<%end -%>
\ No newline at end of file
index 98a71e54c97cdf8f05368832506b5b5ba8f5327d..5626636c7000b0a29aa9de1c07bb2c24d6529a8e 100644 (file)
@@ -145,7 +145,6 @@ by several other names.</p>
 <div class="clearbox"></div>
 
 <h2>Voters</h2>
-
 <table class="voterbox">
 <tr>
 <th>IP Address</th>
@@ -168,8 +167,9 @@ by several other names.</p>
 <% end %>
 </table>
 
+<%= render :partial => 'pref_table' %>
+
 <%= image_tag( graph_url( :action => 'votes_per_day', :id => @election ) ) %><br />
 <%= image_tag( graph_url( :action => 'votes_per_interval', :id => @election ))%><br />
 <%= image_tag( graph_url( :action => 'borda_bar', :id => @election ) ) %><br />
 <%= image_tag( graph_url( :action => 'choices_positions', :id => @election ) ) %>
-
index aaa504477373e07735b6eab9b7c847db0c68232a..bf4e548da45bcbb6d9c3ebfa57269d065bf09b6a 100644 (file)
@@ -32,7 +32,7 @@
 ## the CloneproofSSDVote classes but should not be used directly.
 
 class CondorcetVote < ElectionVote
-
+  
   attr_accessor :results
 
   def initialize(votes=nil)
@@ -144,15 +144,17 @@ end
 ## directly.
 
 class CondorcetResult < ElectionResult
+  attr_reader :matrix
+  
   def initialize(voteobj=nil)
     unless voteobj and voteobj.kind_of?( CondorcetVote )
       raise ArgumentError, "You must pass a CondorcetVote array.", caller
     end
     super(voteobj)
+    @matrix = voteobj.votes
   end
 
   protected
-
   def defeats(candidates=nil, votes=nil)
     candidates = @election.candidates unless candidates
     votes = @election.votes unless votes
index 42f18bb6c9fa7470e34c46051787573b377fdce2..efb8dd8aae1ce56abc9896853a32eaf5c0f562da 100644 (file)
@@ -140,7 +140,8 @@ end
 
 class PluralityResult < ElectionResult
   attr_reader :ranked_candidates
-
+  attr_reader :points
+  
   def initialize(voteobj=nil)
     super(voteobj)
 
@@ -151,6 +152,8 @@ class PluralityResult < ElectionResult
       b[1] <=> a[1]
     end.collect {|a| a[0]}
     
+    @points = self.election.votes
+    
     # winners are anyone who has the same number of votes as the
     # first person
     @winners = @ranked_candidates.find_all do |i|
index 3de3fb29ae6f20b0371eedacb41471ff73be279f..dc0b63aca3811bdb07e2fdcfb4f4107d5d53b0d3 100644 (file)
@@ -38,7 +38,7 @@ class BordaVote < ElectionVote
     end
     super(votes)
   end
-
+   
   def tally_vote(vote)
     points = candidates.length - 1
     vote.each do |candidate|
@@ -51,7 +51,7 @@ class BordaVote < ElectionVote
       points -= 1
     end
   end
-
+  
   def verify_vote(vote=nil)
     vote.instance_of?( Array ) and
       vote == vote.uniq
@@ -64,11 +64,12 @@ end
 
 class BordaResult < ElectionResult
   attr_reader :ranked_candidates
+  attr_reader :points
   
   def initialize(voteobj=nil)
     super(voteobj)
     votes = @election.votes
-
+    
     @ranked_candidates = votes.sort do |a, b|
       b[1] <=> a[1]
     end.collect {|i| i[0]}
@@ -76,6 +77,8 @@ class BordaResult < ElectionResult
     @winners = @ranked_candidates.find_all do |i|
       votes[i] == votes[@ranked_candidates[0]]
     end
+    
+    @points = self.election.votes
   end
 
 end

Benjamin Mako Hill || Want to submit a patch?