diff options
author | Jean-Philippe Lang <jp_lang@yahoo.fr> | 2007-03-25 17:11:46 +0000 |
---|---|---|
committer | Jean-Philippe Lang <jp_lang@yahoo.fr> | 2007-03-25 17:11:46 +0000 |
commit | 0ef114e00641a3cdb8771675a30cae31177b2d61 (patch) | |
tree | c07f0919f4b010a9262ba04b52ecb32f5a8c7dd1 /app | |
parent | 887f11435b4d18ccb5d6e0e39893935f93c903c9 (diff) | |
download | redmine-0ef114e00641a3cdb8771675a30cae31177b2d61.tar.gz redmine-0ef114e00641a3cdb8771675a30cae31177b2d61.zip |
added simple svn statistics graphs, rendered using SVG::Graph
git-svn-id: http://redmine.rubyforge.org/svn/trunk@380 e93f8b46-1217-0410-a6f0-8f06a7374b81
Diffstat (limited to 'app')
-rw-r--r-- | app/controllers/repositories_controller.rb | 109 | ||||
-rw-r--r-- | app/models/changeset.rb | 7 | ||||
-rw-r--r-- | app/models/repository.rb | 1 | ||||
-rw-r--r-- | app/views/repositories/show.rhtml | 4 | ||||
-rw-r--r-- | app/views/repositories/stats.rhtml | 11 |
5 files changed, 129 insertions, 3 deletions
diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb index 94b81080f..276b88162 100644 --- a/app/controllers/repositories_controller.rb +++ b/app/controllers/repositories_controller.rb @@ -15,10 +15,15 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +require 'SVG/Graph/Bar' +require 'SVG/Graph/BarHorizontal' + class RepositoriesController < ApplicationController layout 'base' - before_filter :find_project, :authorize - + before_filter :find_project + before_filter :authorize, :except => [:stats, :graph] + before_filter :check_project_privacy, :only => [:stats, :graph] + def show # get entries for the browse frame @entries = @repository.scm.entries('') @@ -64,6 +69,25 @@ class RepositoriesController < ApplicationController show_error and return unless @diff end + def stats + end + + def graph + data = nil + case params[:graph] + when "commits_per_month" + data = graph_commits_per_month(@repository) + when "commits_per_author" + data = graph_commits_per_author(@repository) + end + if data + headers["Content-Type"] = "image/svg+xml" + send_data(data, :type => "image/svg+xml", :disposition => "inline") + else + render_404 + end + end + private def find_project @project = Project.find(params[:id]) @@ -80,4 +104,85 @@ private flash.now[:notice] = l(:notice_scm_error) render :nothing => true, :layout => true end + + def graph_commits_per_month(repository) + @date_to = Date.today + @date_from = @date_to << 12 + commits_by_day = repository.changesets.count(:all, :group => :commit_date, :conditions => ["commit_date BETWEEN ? AND ?", @date_from, @date_to]) + commits_by_month = [0] * 12 + commits_by_day.each {|c| commits_by_month[c.first.to_date.months_ago] += c.last } + + changes_by_day = repository.changes.count(:all, :group => :commit_date) + changes_by_month = [0] * 12 + changes_by_day.each {|c| changes_by_month[c.first.to_date.months_ago] += c.last } + + fields = [] + month_names = l(:actionview_datehelper_select_month_names_abbr).split(',') + 12.times {|m| fields << month_names[((Date.today.month - 1 - m) % 12)]} + + graph = SVG::Graph::Bar.new( + :height => 300, + :width => 500, + :fields => fields.reverse, + :stack => :side, + :scale_integers => true, + :step_x_labels => 2, + :show_data_values => false, + :graph_title => l(:label_commits_per_month), + :show_graph_title => true + ) + + graph.add_data( + :data => commits_by_month[0..11].reverse, + :title => l(:label_revision_plural) + ) + + graph.add_data( + :data => changes_by_month[0..11].reverse, + :title => l(:label_change_plural) + ) + + graph.burn + end + + def graph_commits_per_author(repository) + commits_by_author = repository.changesets.count(:all, :group => :committer) + commits_by_author.sort! {|x, y| x.last <=> y.last} + + fields = commits_by_author.collect {|r| r.first} + data = commits_by_author.collect {|r| r.last} + + fields = fields + [""]*(10 - fields.length) if fields.length<10 + data = data + [0]*(10 - data.length) if data.length<10 + + graph = SVG::Graph::BarHorizontal.new( + :height => 300, + :width => 500, + :fields => fields, + :stack => :side, + :scale_integers => true, + :show_data_values => false, + :rotate_y_labels => false, + :graph_title => l(:label_commits_per_author), + :show_graph_title => true + ) + + graph.add_data( + :data => data, + :title => l(:label_revision_plural) + ) + + graph.burn + end + end + +class Date + def months_ago(date = Date.today) + (date.year - self.year)*12 + (date.month - self.month) + end + + def weeks_ago(date = Date.today) + (date.year - self.year)*52 + (date.cweek - self.cweek) + end +end
\ No newline at end of file diff --git a/app/models/changeset.rb b/app/models/changeset.rb index fa60f1db8..00775f337 100644 --- a/app/models/changeset.rb +++ b/app/models/changeset.rb @@ -19,7 +19,12 @@ class Changeset < ActiveRecord::Base belongs_to :repository has_many :changes, :dependent => :delete_all - validates_presence_of :repository_id, :revision, :committed_on + validates_presence_of :repository_id, :revision, :committed_on, :commit_date validates_numericality_of :revision, :only_integer => true validates_uniqueness_of :revision, :scope => :repository_id + + def committed_on=(date) + self.commit_date = date + super + end end diff --git a/app/models/repository.rb b/app/models/repository.rb index 19b12f372..465c4ba62 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -18,6 +18,7 @@ class Repository < ActiveRecord::Base belongs_to :project has_many :changesets, :dependent => :destroy, :order => 'revision DESC' + has_many :changes, :through => :changesets has_one :latest_changeset, :class_name => 'Changeset', :foreign_key => :repository_id, :order => 'revision DESC' attr_protected :root_url diff --git a/app/views/repositories/show.rhtml b/app/views/repositories/show.rhtml index e7d71cb79..04a58b4c9 100644 --- a/app/views/repositories/show.rhtml +++ b/app/views/repositories/show.rhtml @@ -1,3 +1,7 @@ +<div class="contextual"> +<%= link_to l(:label_statistics), {:action => 'stats', :id => @project}, :class => 'icon icon-stats' %> +</div> + <h2><%= l(:label_repository) %></h2> <h3><%= l(:label_browse) %></h3> diff --git a/app/views/repositories/stats.rhtml b/app/views/repositories/stats.rhtml new file mode 100644 index 000000000..7a9423f8c --- /dev/null +++ b/app/views/repositories/stats.rhtml @@ -0,0 +1,11 @@ +<h2><%= l(:label_statistics) %></h2>
+
+<table width="100%">
+<tr><td>
+<%= tag("embed", :width => 500, :height => 300, :type => "image/svg+xml", :src => url_for(:controller => 'repositories', :action => 'graph', :id => @project, :graph => "commits_per_month")) %>
+</td><td>
+<%= tag("embed", :width => 500, :height => 300, :type => "image/svg+xml", :src => url_for(:controller => 'repositories', :action => 'graph', :id => @project, :graph => "commits_per_author")) %>
+</td></tr>
+</table>
+<br />
+<p><%= link_to l(:button_back), :action => 'show', :id => @project %></p>
\ No newline at end of file |