summaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
authorJean-Philippe Lang <jp_lang@yahoo.fr>2007-03-25 17:11:46 +0000
committerJean-Philippe Lang <jp_lang@yahoo.fr>2007-03-25 17:11:46 +0000
commit0ef114e00641a3cdb8771675a30cae31177b2d61 (patch)
treec07f0919f4b010a9262ba04b52ecb32f5a8c7dd1 /app
parent887f11435b4d18ccb5d6e0e39893935f93c903c9 (diff)
downloadredmine-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.rb109
-rw-r--r--app/models/changeset.rb7
-rw-r--r--app/models/repository.rb1
-rw-r--r--app/views/repositories/show.rhtml4
-rw-r--r--app/views/repositories/stats.rhtml11
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