Gantt: iterate over all objects only once for html and pdf rendering (#6348).

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@4472 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
Jean-Philippe Lang 2010-12-07 18:40:34 +00:00
parent bfa61c1ec4
commit b0a1a04008
2 changed files with 52 additions and 89 deletions

View File

@ -62,6 +62,8 @@ g_width = (@gantt.date_to - @gantt.date_from + 1)*zoom
# Collect the number of issues on Versions # Collect the number of issues on Versions
g_height = [(20 * (@gantt.number_of_rows + 6))+150, 206].max g_height = [(20 * (@gantt.number_of_rows + 6))+150, 206].max
t_height = g_height + headers_height t_height = g_height + headers_height
@gantt.render(:headers_height => headers_height, :top => headers_height + 8, :zoom => zoom, :g_width => g_width)
%> %>
<table width="100%" style="border:0; border-collapse: collapse;"> <table width="100%" style="border:0; border-collapse: collapse;">
<tr> <tr>
@ -72,7 +74,7 @@ t_height = g_height + headers_height
<div style="right:-2px;width:<%= subject_width %>px;height:<%= t_height %>px;border-left: 1px solid #c0c0c0;overflow:hidden;" class="gantt_hdr"></div> <div style="right:-2px;width:<%= subject_width %>px;height:<%= t_height %>px;border-left: 1px solid #c0c0c0;overflow:hidden;" class="gantt_hdr"></div>
<% top = headers_height + 8 %> <% top = headers_height + 8 %>
<%= @gantt.subjects(:headers_height => headers_height, :top => top, :g_width => g_width) %> <%= @gantt.subjects %>
</div> </div>
</td> </td>
@ -153,7 +155,7 @@ end %>
<% top = headers_height + 10 %> <% top = headers_height + 10 %>
<%= @gantt.lines(:top => top, :zoom => zoom, :g_width => g_width ) %> <%= @gantt.lines %>
<% <%
# #

View File

@ -67,6 +67,9 @@ module Redmine
@date_from = Date.civil(@year_from, @month_from, 1) @date_from = Date.civil(@year_from, @month_from, 1)
@date_to = (@date_from >> @months) - 1 @date_to = (@date_from >> @months) - 1
@subjects = ''
@lines = ''
end end
def common_params def common_params
@ -128,34 +131,32 @@ module Redmine
# Renders the subjects of the Gantt chart, the left side. # Renders the subjects of the Gantt chart, the left side.
def subjects(options={}) def subjects(options={})
options = {:indent => 4, :render => :subject, :format => :html}.merge(options) render(options.merge(:only => :subjects)) unless @subjects_rendered
@subjects
output = ''
if @project
output << render_project(@project, options)
else
Project.roots.visible.each do |project|
output << render_project(project, options)
end
end
output
end end
# Renders the lines of the Gantt chart, the right side # Renders the lines of the Gantt chart, the right side
def lines(options={}) def lines(options={})
options = {:indent => 4, :render => :line, :format => :html}.merge(options) render(options.merge(:only => :lines)) unless @lines_rendered
output = '' @lines
end
def render(options={})
options = {:indent => 4, :render => :subject, :format => :html}.merge(options)
@subjects = '' unless options[:only] == :lines
@lines = '' unless options[:only] == :subjects
if @project if @project
output << render_project(@project, options) render_project(@project, options)
else else
Project.roots.visible.each do |project| Project.roots.visible.each do |project|
output << render_project(project, options) render_project(project, options)
end end
end end
output @subjects_rendered = true unless options[:only] == :lines
@lines_rendered = true unless options[:only] == :subjects
end end
def render_project(project, options={}) def render_project(project, options={})
@ -163,15 +164,8 @@ module Redmine
options[:indent_increment] = 20 unless options.key? :indent_increment options[:indent_increment] = 20 unless options.key? :indent_increment
options[:top_increment] = 20 unless options.key? :top_increment options[:top_increment] = 20 unless options.key? :top_increment
output = '' subject_for_project(project, options) unless options[:only] == :lines
# Project Header line_for_project(project, options) unless options[:only] == :subjects
project_header = if options[:render] == :subject
subject_for_project(project, options)
else
# :line
line_for_project(project, options)
end
output << project_header if options[:format] == :html
options[:top] += options[:top_increment] options[:top] += options[:top_increment]
options[:indent] += options[:indent_increment] options[:indent] += options[:indent_increment]
@ -180,54 +174,36 @@ module Redmine
issues = project.issues.for_gantt.without_version.with_query(@query) issues = project.issues.for_gantt.without_version.with_query(@query)
sort_issues!(issues) sort_issues!(issues)
if issues if issues
issue_rendering = render_issues(issues, options) render_issues(issues, options)
output << issue_rendering if options[:format] == :html
end end
# Third, Versions # Third, Versions
project.versions.sort.each do |version| project.versions.sort.each do |version|
version_rendering = render_version(version, options) render_version(version, options)
output << version_rendering if options[:format] == :html
end end
# Fourth, subprojects # Fourth, subprojects
project.children.visible.each do |project| project.children.visible.each do |project|
subproject_rendering = render_project(project, options) render_project(project, options)
output << subproject_rendering if options[:format] == :html
end end
# Remove indent to hit the next sibling # Remove indent to hit the next sibling
options[:indent] -= options[:indent_increment] options[:indent] -= options[:indent_increment]
output
end end
def render_issues(issues, options={}) def render_issues(issues, options={})
output = ''
issues.each do |i| issues.each do |i|
issue_rendering = if options[:render] == :subject subject_for_issue(i, options) unless options[:only] == :lines
subject_for_issue(i, options) line_for_issue(i, options) unless options[:only] == :subjects
else
# :line
line_for_issue(i, options)
end
output << issue_rendering if options[:format] == :html
options[:top] += options[:top_increment] options[:top] += options[:top_increment]
end end
output
end end
def render_version(version, options={}) def render_version(version, options={})
output = ''
# Version header # Version header
version_rendering = if options[:render] == :subject subject_for_version(version, options) unless options[:only] == :lines
subject_for_version(version, options) line_for_version(version, options) unless options[:only] == :subjects
else
# :line
line_for_version(version, options)
end
output << version_rendering if options[:format] == :html
options[:top] += options[:top_increment] options[:top] += options[:top_increment]
@ -241,11 +217,9 @@ module Redmine
sort_issues!(issues) sort_issues!(issues)
# Indent issues # Indent issues
options[:indent] += options[:indent_increment] options[:indent] += options[:indent_increment]
output << render_issues(issues, options) render_issues(issues, options)
options[:indent] -= options[:indent_increment] options[:indent] -= options[:indent_increment]
end end
output
end end
def subject_for_project(project, options) def subject_for_project(project, options)
@ -263,7 +237,7 @@ module Redmine
'' ''
end end
output << "</small></div>" output << "</small></div>"
@subjects << output
output output
when :image when :image
@ -351,7 +325,7 @@ module Redmine
output << "<strong>#{h project } #{h project.completed_percent(:include_subprojects => true).to_i.to_s}%</strong>" output << "<strong>#{h project } #{h project.completed_percent(:include_subprojects => true).to_i.to_s}%</strong>"
output << "</div>" output << "</div>"
end end
@lines << output
output output
when :image when :image
options[:image].stroke('transparent') options[:image].stroke('transparent')
@ -399,7 +373,7 @@ module Redmine
'' ''
end end
output << "</small></div>" output << "</small></div>"
@subjects << output
output output
when :image when :image
options[:image].fill('black') options[:image].fill('black')
@ -486,7 +460,7 @@ module Redmine
output << "<strong>#{h version } #{h version.completed_pourcent.to_i.to_s}%</strong>" output << "<strong>#{h version } #{h version.completed_pourcent.to_i.to_s}%</strong>"
output << "</div>" output << "</div>"
end end
@lines << output
output output
when :image when :image
options[:image].stroke('transparent') options[:image].stroke('transparent')
@ -553,6 +527,7 @@ module Redmine
end end
output << "</div>" output << "</div>"
@subjects << output
output output
when :image when :image
options[:image].fill('black') options[:image].fill('black')
@ -625,6 +600,7 @@ module Redmine
output << '<span class="tip">' output << '<span class="tip">'
output << view.render_issue_tooltip(issue) output << view.render_issue_tooltip(issue)
output << "</span></div>" output << "</span></div>"
@lines << output
output output
when :image when :image
@ -938,18 +914,21 @@ module Redmine
# Tasks # Tasks
top = headers_heigth + y_start top = headers_heigth + y_start
pdf_subjects_and_lines(pdf, { options = {
:top => top, :top => top,
:zoom => zoom, :zoom => zoom,
:subject_width => subject_width, :subject_width => subject_width,
:g_width => g_width :g_width => g_width,
}) :indent => 0,
:indent_increment => 5,
:top_increment => 3,
:format => :pdf,
:pdf => pdf
}
render(options)
pdf.Line(15, top, subject_width+g_width, top) pdf.Line(15, top, subject_width+g_width, top)
pdf.Output pdf.Output
end end
private private
@ -964,24 +943,6 @@ module Redmine
cmp cmp
end end
end end
# Renders both the subjects and lines of the Gantt chart for the
# PDF format
def pdf_subjects_and_lines(pdf, options = {})
subject_options = {:indent => 0, :indent_increment => 5, :top_increment => 3, :render => :subject, :format => :pdf, :pdf => pdf}.merge(options)
line_options = {:indent => 0, :indent_increment => 5, :top_increment => 3, :render => :line, :format => :pdf, :pdf => pdf}.merge(options)
if @project
render_project(@project, subject_options)
render_project(@project, line_options)
else
Project.roots.each do |project|
render_project(project, subject_options)
render_project(project, line_options)
end
end
end
end end
end end
end end