Project

General

Profile

Feature #12122 » gantt-progress-line-html-r10659.diff

Toshi MARUYAMA, 2012-10-17 11:40

View differences:

app/views/gantts/show.html.erb
1
<% content_for :header_tags do %>
2
  <%= javascript_include_tag 'raphael' %>
3
  <%= javascript_include_tag 'gantt_progress_line' %>
4
<% end %>
5
<%= javascript_tag do %>
6
  $(document).ready(drawGanttLinesHandler);
7
  $(window).resize(drawGanttLinesHandler);
8
<% end %>
1 9
<% @gantt.view = self %>
2 10
<h2><%= @query.new_record? ? l(:label_gantt) : h(@query.name) %></h2>
3 11

  
......
228 236
    style += "width:10px;"
229 237
    style += "border-left: 1px dashed red;"
230 238
  %>
231
  <%= content_tag(:div, '&nbsp;'.html_safe, :style => style) %>
239
  <%= content_tag(:div, '&nbsp;'.html_safe, :style => style, :id => 'today_red_line') %>
232 240
<% end %>
233

  
241
<%
242
  style  = ""
243
  style += "position: absolute;"
244
  style += "height: #{g_height}px;"
245
  style += "top: #{headers_height + 1}px;"
246
  style += "left: 0px;"
247
  style += "width: #{g_width - 1}px;"
248
%>
249
<%= content_tag(:div, '', :style => style, :id => "gantt_lines") %>
234 250
</div>
235 251
</td>
236 252
</tr>
lib/redmine/helpers/gantt.rb
288 288
          html_class << 'icon icon-package '
289 289
          html_class << (version.behind_schedule? ? 'version-behind-schedule' : '') << " "
290 290
          html_class << (version.overdue? ? 'version-overdue' : '')
291
          html_class << ' version-closed' unless version.open?
292
          if version.start_date && version.due_date && version.completed_pourcent
293
            progress_date = calc_progress_date(version.start_date,
294
                                               version.due_date, version.completed_pourcent)
295
            html_class << ' behind-start-date' if progress_date < self.date_from
296
            html_class << ' over-end-date' if progress_date > self.date_to
297
          end
291 298
          s = view.link_to_version(version).html_safe
292 299
          subject = view.content_tag(:span, s,
293 300
                                     :class => html_class).html_safe
294
          html_subject(options, subject, :css => "version-name")
301
          html_subject(options, subject, :css => "version-name",
302
                       :id => "version-#{version.id}")
295 303
        when :image
296 304
          image_subject(options, version.to_s_with_project)
297 305
        when :pdf
......
312 320
          label = h("#{version.project} -") + label unless @project && @project == version.project
313 321
          case options[:format]
314 322
          when :html
315
            html_task(options, coords, :css => "version task", :label => label, :markers => true)
323
            html_task(options, coords, :css => "version task",
324
                      :label => label, :markers => true, :version => version)
316 325
          when :image
317 326
            image_task(options, coords, :label => label, :markers => true, :height => 3)
318 327
          when :pdf
......
335 344
          css_classes << ' issue-overdue' if issue.overdue?
336 345
          css_classes << ' issue-behind-schedule' if issue.behind_schedule?
337 346
          css_classes << ' icon icon-issue' unless Setting.gravatar_enabled? && issue.assigned_to
347
          css_classes << ' issue-closed' if issue.closed?
348
          if issue.start_date && issue.due_before && issue.done_ratio
349
            progress_date = calc_progress_date(issue.start_date,
350
                                               issue.due_before, issue.done_ratio)
351
            css_classes << ' behind-start-date' if progress_date < self.date_from
352
            css_classes << ' over-end-date' if progress_date > self.date_to
353
          end
338 354
          s = "".html_safe
339 355
          if issue.assigned_to.present?
340 356
            assigned_string = l(:field_assigned_to) + ": " + issue.assigned_to.name
......
346 362
          s << view.link_to_issue(issue).html_safe
347 363
          subject = view.content_tag(:span, s, :class => css_classes).html_safe
348 364
          html_subject(options, subject, :css => "issue-subject",
349
                       :title => issue.subject) + "\n"
365
                       :title => issue.subject, :id => "issue-#{issue.id}") + "\n"
350 366
        when :image
351 367
          image_subject(options, issue.subject)
352 368
        when :pdf
......
609 625
            coords[:bar_end] = self.date_to - self.date_from + 1
610 626
          end
611 627
          if progress
612
            progress_date = start_date + (end_date - start_date + 1) * (progress / 100.0)
628
            progress_date = calc_progress_date(start_date, end_date, progress)
613 629
            if progress_date > self.date_from && progress_date > start_date
614 630
              if progress_date < self.date_to
615 631
                coords[:bar_progress_end] = progress_date - self.date_from
......
636 652
        coords
637 653
      end
638 654

  
655
      def calc_progress_date(start_date, end_date, progress)
656
        start_date + (end_date - start_date + 1) * (progress / 100.0)
657
      end
658

  
639 659
      # Sorts a collection of issues by start_date, due_date, id for gantt rendering
640 660
      def sort_issues!(issues)
641 661
        issues.sort! { |a, b| gantt_issue_compare(a, b, issues) }
......
676 696
      def html_subject(params, subject, options={})
677 697
        style = "position: absolute;top:#{params[:top]}px;left:#{params[:indent]}px;"
678 698
        style << "width:#{params[:subject_width] - params[:indent]}px;" if params[:subject_width]
679
        output = view.content_tag('div', subject,
699
        output = view.content_tag(:div, subject,
680 700
                                  :class => options[:css], :style => style,
681
                                  :title => options[:title])
701
                                  :title => options[:title],
702
                                  :id => options[:id])
682 703
        @subjects << output
683 704
        output
684 705
      end
......
712 733
          style << "top:#{params[:top]}px;"
713 734
          style << "left:#{coords[:bar_start]}px;"
714 735
          style << "width:#{width}px;"
736
          html_id = "task-todo-issue-#{options[:issue].id}" if options[:issue]
737
          html_id = "task-todo-version-#{options[:version].id}" if options[:version]
715 738
          output << view.content_tag(:div, '&nbsp;'.html_safe,
716 739
                                     :style => style,
717
                                     :class => "#{options[:css]} task_todo")
740
                                     :class => "#{options[:css]} task_todo",
741
                                     :id => html_id)
718 742
          if coords[:bar_late_end]
719 743
            width = coords[:bar_late_end] - coords[:bar_start] - 2
720 744
            style = ""
......
731 755
            style << "top:#{params[:top]}px;"
732 756
            style << "left:#{coords[:bar_start]}px;"
733 757
            style << "width:#{width}px;"
758
            html_id = "task-done-issue-#{options[:issue].id}" if options[:issue]
759
            html_id = "task-done-version-#{options[:version].id}" if options[:version]
734 760
            output << view.content_tag(:div, '&nbsp;'.html_safe,
735 761
                                       :style => style,
736
                                       :class => "#{options[:css]} task_done")
762
                                       :class => "#{options[:css]} task_done",
763
                                       :id => html_id)
737 764
          end
738 765
        end
739 766
        # Renders the markers
public/javascripts/gantt_progress_line.js
1
var draw_gantt_line = null;
2

  
3
function drawGanttLines(holder) {
4
  if(draw_gantt_line != null)
5
    draw_gantt_line.clear();
6
  else
7
    draw_gantt_line = Raphael(holder);
8
  var arr = new Array();
9
  var today_left = $('#today_red_line').position().left;
10
  arr.push({left: today_left, top: 0});
11
  var line_top   = $("#gantt_lines").position().top;
12
  var line_right = $("#gantt_lines").width();
13
  $.each($('div.issue-subject, div.version-name'), function(index, element) {
14
    var t0 = $(element).position().top - line_top ;
15
    var h = ($(element).height() / 9);
16
    var t1 = t0 - h;
17
    var t2 = t0 + (h * 8);
18
    var t  = t0 + (h * 3);
19
    var ci = $(element).children('span').hasClass('issue-closed');
20
    var cv = $(element).children('span').hasClass('version-closed');
21
    if (ci || cv) {
22
      arr.push({left: today_left, top: t});
23
    } else {
24
      var issue_done = $("#task-done-" + $(element).attr("id"));
25
      var is_behind_start = $(element).children('span').hasClass('behind-start-date');
26
      var is_over_end     = $(element).children('span').hasClass('over-end-date');
27
      if (is_over_end) {
28
        arr.push({left: line_right, top: t1, is_right_edge: true});
29
        arr.push({left: line_right, top: t2, is_right_edge: true, none_stroke: true});
30
      } else if (issue_done.size() > 0) {
31
        var l = issue_done.first().position().left +
32
                    issue_done.first().width();
33
        arr.push({left: l, top: t});
34
      } else if (is_behind_start) {
35
        arr.push({left: 0 , top: t1, is_left_edge: true});
36
        arr.push({left: 0 , top: t2, is_left_edge: true, none_stroke: true});
37
      } else {
38
        var l1 = today_left;
39
        var issue_todo = $("#task-todo-" + $(element).attr("id"));
40
        if (issue_todo.size() > 0){
41
          l1 = issue_todo.first().position().left;
42
        }
43
        arr.push({left: Math.min(today_left, l1), top: t});
44
      }
45
    }
46
  });
47
  var i;
48
  for(i = 1 ; i < arr.length ; i++) {
49
    if (!("none_stroke" in arr[i]) &&
50
        (!("is_right_edge" in arr[i - 1] && "is_right_edge" in arr[i]) &&
51
         !("is_left_edge" in arr[i - 1] && "is_left_edge" in arr[i]))
52
        ) {
53
      draw_gantt_line.path(["M",arr[i - 1].left, arr[i - 1].top, "L", arr[i].left, arr[i].top])
54
            .attr({stroke: "#ff0000", "stroke-width": 2});
55
    }
56
  }
57
}
58

  
59
function drawGanttLinesHandler() {
60
  drawGanttLines(document.getElementById('gantt_lines'));
61
}
(2-2/10)