added simple svn statistics graphs, rendered using SVG::Graph
git-svn-id: http://redmine.rubyforge.org/svn/trunk@380 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
1 parent
887f11435b
commit
0ef114e006
25 files changed
+3897
-3
No files matched your search
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
Reference in new issue
Block a user