diff --git a/app/controllers/graphs_controller.rb b/app/controllers/graphs_controller.rb
index c6d0755..01bfa04 100755
--- a/app/controllers/graphs_controller.rb
+++ b/app/controllers/graphs_controller.rb
@@ -3,10 +3,56 @@ require 'SVG/Graph/TimeSeries'
class GraphsController < ApplicationController
before_filter :find_version, :only => [:target_version_graph]
- before_filter :find_issues, :only => [:old_issues, :issue_age_graph]
+ before_filter :find_open_issues, :only => [:old_issues, :issue_age_graph]
+ before_filter :find_all_issues, :only => [:issue_growth_graph, :issue_growth]
helper IssuesHelper
+ def issue_growth
+ end
+
+ # Displays projects by total issues over time
+ def issue_growth_graph
+
+ # Initialize the graph
+ graph = SVG::Graph::TimeSeries.new({
+ :height => 300,
+ :min_y_value => 0,
+ :no_css => true,
+ :show_x_guidelines => true,
+ :scale_x_integers => true,
+ :scale_y_integers => true,
+ :show_data_points => false,
+ :show_data_values => false,
+ :stagger_x_labels => true,
+ :style_sheet => "/plugin_assets/redmine_graphs/stylesheets/issue_growth.css",
+ :timescale_divisions => "1 weeks",
+ :width => 800,
+ :x_label_format => "%b %d"
+ })
+
+ # Group issues
+ issues_by_project = @issues.group_by {|issue| issue.project }
+ projects_by_size = issues_by_project.collect { |project, issues| [project, issues.size] }.sort { |a,b| b[1]<=>a[1] }[0..5]
+
+ # Generate the created_on line
+ projects_by_size.each do |project, size|
+ issues_by_created_on = issues_by_project[project].group_by {|issue| issue.created_on.to_date }.sort
+ created_count = 0
+ created_on_line = Hash.new
+ issues_by_created_on.each { |created_on, issues| created_on_line[(created_on-1).to_s] = created_count; created_count += issues.size; created_on_line[created_on.to_s] = created_count }
+ created_on_line[Date.today.to_s] = created_count
+ graph.add_data({
+ :data => created_on_line.sort.flatten,
+ :title => project.name
+ })
+ end
+
+ # Compile the graph
+ headers["Content-Type"] = "image/svg+xml"
+ send_data(graph.burn, :type => "image/svg+xml", :disposition => "inline")
+ end
+
def old_issues
@issues_by_created_on = @issues.sort {|a,b| a.created_on<=>b.created_on}
@issues_by_updated_on = @issues.sort {|a,b| a.updated_on<=>b.updated_on}
@@ -128,7 +174,7 @@ class GraphsController < ApplicationController
private
- def find_issues
+ def find_open_issues
@project = Project.find(params[:project_id]) unless params[:project_id].blank?
deny_access unless User.current.allowed_to?(:view_issues, @project, :global => true)
@issues = Issue.visible.find(:all, :include => [:status], :conditions => ["#{IssueStatus.table_name}.is_closed=?", false]) if @project.nil?
@@ -136,6 +182,15 @@ class GraphsController < ApplicationController
rescue ActiveRecord::RecordNotFound
render_404
end
+
+ def find_all_issues
+ @project = Project.find(params[:project_id]) unless params[:project_id].blank?
+ deny_access unless User.current.allowed_to?(:view_issues, @project, :global => true) if @project.nil?
+ @issues = Issue.visible.find(:all, :include => [:project])
+ @issues = @project.issues unless @project.nil?
+ rescue ActiveRecord::RecordNotFound
+ render_404
+ end
def find_version
@version = Version.find(params[:id])
diff --git a/app/views/graphs/issue_growth.html.erb b/app/views/graphs/issue_growth.html.erb
new file mode 100755
index 0000000..86ebeff
--- /dev/null
+++ b/app/views/graphs/issue_growth.html.erb
@@ -0,0 +1,3 @@
+
<%= l(:label_graphs_issue_growth) %>
+<%= tag("embed", :width => "100%", :height => 300, :type => "image/svg+xml", :src => url_for(:controller => 'graphs', :action => 'issue_growth_graph')) if @project.nil? %>
+<%= tag("embed", :width => "100%", :height => 300, :type => "image/svg+xml", :src => url_for(:controller => 'graphs', :action => 'issue_growth_graph', :project_id => @project.id)) unless @project.nil? %>
\ No newline at end of file
diff --git a/assets/stylesheets/issue_growth.css b/assets/stylesheets/issue_growth.css
new file mode 100755
index 0000000..2029028
--- /dev/null
+++ b/assets/stylesheets/issue_growth.css
@@ -0,0 +1,6 @@
+.line1 { stroke: #C00 !important; stroke-width: 4px !important; stroke-opacity: 0.8 !important; } .key1 { fill: #C00 !important; }
+.line2 { stroke: #CC0 !important; stroke-width: 4px !important; stroke-opacity: 0.8 !important; } .key2 { fill: #CC0 !important; }
+.line3 { stroke: #0C0 !important; stroke-width: 4px !important; stroke-opacity: 0.8 !important; } .key3 { fill: #0C0 !important; }
+.line4 { stroke: #0CC !important; stroke-width: 4px !important; stroke-opacity: 0.8 !important; } .key4 { fill: #0CC !important; }
+.line5 { stroke: #00C !important; stroke-width: 4px !important; stroke-opacity: 0.8 !important; } .key5 { fill: #00C !important; }
+.line6 { stroke: #C0C !important; stroke-width: 4px !important; stroke-opacity: 0.8 !important; } .key6 { fill: #C0C !important; }
\ No newline at end of file
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 4d84ca6..02782ca 100755
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -1,4 +1,5 @@
en:
label_graphs_total_vs_closed_issues: Total issues vs. Closed issues
- label_graphs_old_issues: Old issues
+ label_graphs_old_issues: Open aging issues
+ label_graphs_issue_growth: Total issues over time
\ No newline at end of file
diff --git a/init.rb b/init.rb
index 91a2468..fb8f39b 100755
--- a/init.rb
+++ b/init.rb
@@ -1,7 +1,7 @@
require 'redmine'
require_dependency 'target_version_graph_hook'
-require_dependency 'old_issues_graph_hook'
+require_dependency 'issues_sidebar_graph_hook'
Redmine::Plugin.register :redmine_graphs do
name 'Redmine Graphs plugin'
diff --git a/lib/issues_sidebar_graph_hook.rb b/lib/issues_sidebar_graph_hook.rb
new file mode 100755
index 0000000..11cd513
--- /dev/null
+++ b/lib/issues_sidebar_graph_hook.rb
@@ -0,0 +1,13 @@
+# Provides a link to the issue age graph on the issue index page
+class IssuesSidebarGraphHook < Redmine::Hook::ViewListener
+ def view_issues_sidebar_issues_bottom(context = { })
+ output = "Graphs
"
+ output << link_to(l(:label_graphs_old_issues), {:controller => 'graphs', :action => 'old_issues'}) if context[:project].nil?
+ output << link_to(l(:label_graphs_old_issues), {:controller => 'graphs', :action => 'old_issues', :project_id => context[:project]}) unless context[:project].nil?
+ output << "
"
+ output << link_to(l(:label_graphs_issue_growth), {:controller => 'graphs', :action => 'issue_growth'}) if context[:project].nil?
+ output << link_to(l(:label_graphs_issue_growth), {:controller => 'graphs', :action => 'issue_growth', :project_id => context[:project]}) unless context[:project].nil?
+ output << "
"
+ return output
+ end
+end
\ No newline at end of file
diff --git a/lib/old_issues_graph_hook.rb b/lib/old_issues_graph_hook.rb
deleted file mode 100755
index 4c10732..0000000
--- a/lib/old_issues_graph_hook.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# Provides a link to the issue age graph on the issue index page
-class OldIssuesGraphHook < Redmine::Hook::ViewListener
- def view_issues_sidebar_issues_bottom(context = { })
- output = link_to l(:label_graphs_old_issues), :controller => 'graphs', :action => 'old_issues' if context[:project].nil?
- output = link_to l(:label_graphs_old_issues), :controller => 'graphs', :action => 'old_issues', :project_id => context[:project] unless context[:project].nil?
- output << "
"
- return output
- end
-end
\ No newline at end of file