Project

General

Profile

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

Toshi MARUYAMA, 2012-12-03 14:22

View differences:

lib/redmine/helpers/gantt.rb
289 289
          html_class << 'icon icon-package '
290 290
          html_class << (version.behind_schedule? ? 'version-behind-schedule' : '') << " "
291 291
          html_class << (version.overdue? ? 'version-overdue' : '')
292
          html_class << ' version-closed' unless version.open?
293
          if version.start_date && version.due_date && version.completed_pourcent
294
            progress_date = calc_progress_date(version.start_date,
295
                                               version.due_date, version.completed_pourcent)
296
            html_class << ' behind-start-date' if progress_date < self.date_from
297
            html_class << ' over-end-date' if progress_date > self.date_to
298
          end
292 299
          s = view.link_to_version(version).html_safe
293 300
          subject = view.content_tag(:span, s,
294 301
                                     :class => html_class).html_safe
295
          html_subject(options, subject, :css => "version-name")
302
          html_subject(options, subject, :css => "version-name",
303
                       :id => "version-#{version.id}")
296 304
        when :image
297 305
          image_subject(options, version.to_s_with_project)
298 306
        when :pdf
......
313 321
          label = h("#{version.project} -") + label unless @project && @project == version.project
314 322
          case options[:format]
315 323
          when :html
316
            html_task(options, coords, :css => "version task", :label => label, :markers => true)
324
            html_task(options, coords, :css => "version task",
325
                      :label => label, :markers => true, :version => version)
317 326
          when :image
318 327
            image_task(options, coords, :label => label, :markers => true, :height => 3)
319 328
          when :pdf
......
336 345
          css_classes << ' issue-overdue' if issue.overdue?
337 346
          css_classes << ' issue-behind-schedule' if issue.behind_schedule?
338 347
          css_classes << ' icon icon-issue' unless Setting.gravatar_enabled? && issue.assigned_to
348
          css_classes << ' issue-closed' if issue.closed?
349
          if issue.start_date && issue.due_before && issue.done_ratio
350
            progress_date = calc_progress_date(issue.start_date,
351
                                               issue.due_before, issue.done_ratio)
352
            css_classes << ' behind-start-date' if progress_date < self.date_from
353
            css_classes << ' over-end-date' if progress_date > self.date_to
354
          end
339 355
          s = "".html_safe
340 356
          if issue.assigned_to.present?
341 357
            assigned_string = l(:field_assigned_to) + ": " + issue.assigned_to.name
......
347 363
          s << view.link_to_issue(issue).html_safe
348 364
          subject = view.content_tag(:span, s, :class => css_classes).html_safe
349 365
          html_subject(options, subject, :css => "issue-subject",
350
                       :title => issue.subject) + "\n"
366
                       :title => issue.subject, :id => "issue-#{issue.id}") + "\n"
351 367
        when :image
352 368
          image_subject(options, issue.subject)
353 369
        when :pdf
......
611 627
            coords[:bar_end] = self.date_to - self.date_from + 1
612 628
          end
613 629
          if progress
614
            progress_date = start_date + (end_date - start_date + 1) * (progress / 100.0)
630
            progress_date = calc_progress_date(start_date, end_date, progress)
615 631
            if progress_date > self.date_from && progress_date > start_date
616 632
              if progress_date < self.date_to
617 633
                coords[:bar_progress_end] = progress_date - self.date_from
......
638 654
        coords
639 655
      end
640 656

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

  
641 661
      # Sorts a collection of issues by start_date, due_date, id for gantt rendering
642 662
      def sort_issues!(issues)
643 663
        issues.sort! { |a, b| gantt_issue_compare(a, b) }
......
678 698
      def html_subject(params, subject, options={})
679 699
        style = "position: absolute;top:#{params[:top]}px;left:#{params[:indent]}px;"
680 700
        style << "width:#{params[:subject_width] - params[:indent]}px;" if params[:subject_width]
681
        output = view.content_tag('div', subject,
701
        output = view.content_tag(:div, subject,
682 702
                                  :class => options[:css], :style => style,
683
                                  :title => options[:title])
703
                                  :title => options[:title],
704
                                  :id => options[:id])
684 705
        @subjects << output
685 706
        output
686 707
      end
......
714 735
          style << "top:#{params[:top]}px;"
715 736
          style << "left:#{coords[:bar_start]}px;"
716 737
          style << "width:#{width}px;"
738
          html_id = "task-todo-issue-#{options[:issue].id}" if options[:issue]
739
          html_id = "task-todo-version-#{options[:version].id}" if options[:version]
717 740
          output << view.content_tag(:div, '&nbsp;'.html_safe,
718 741
                                     :style => style,
719
                                     :class => "#{options[:css]} task_todo")
742
                                     :class => "#{options[:css]} task_todo",
743
                                     :id => html_id)
720 744
          if coords[:bar_late_end]
721 745
            width = coords[:bar_late_end] - coords[:bar_start] - 2
722 746
            style = ""
......
733 757
            style << "top:#{params[:top]}px;"
734 758
            style << "left:#{coords[:bar_start]}px;"
735 759
            style << "width:#{width}px;"
760
            html_id = "task-done-issue-#{options[:issue].id}" if options[:issue]
761
            html_id = "task-done-version-#{options[:version].id}" if options[:version]
736 762
            output << view.content_tag(:div, '&nbsp;'.html_safe,
737 763
                                       :style => style,
738
                                       :class => "#{options[:css]} task_done")
764
                                       :class => "#{options[:css]} task_done",
765
                                       :id => html_id)
739 766
          end
740 767
        end
741 768
        # Renders the markers
app/views/gantts/show.html.erb
12 12
    <%= render :partial => 'queries/filters', :locals => {:query => @query} %>
13 13
  </div>
14 14
</fieldset>
15
<fieldset id="filters" class="collapsible">
16
  <legend onclick="toggleFieldset(this);"><%= l(:label_display) %></legend>
17
  <div>
18
    <label>
19
      <%= check_box_tag "draw_progress_line", 0, params[:draw_progress_line] %>
20
      <%= l(:label_gantt_progress_line) %>
21
    </label>
22
  </div>
23
</fieldset>
15 24

  
16 25
<p class="contextual">
17 26
  <%= gantt_zoom_link(@gantt, :in) %>
config/locales/en.yml
889 889
  label_cross_project_tree: With project tree
890 890
  label_cross_project_hierarchy: With project hierarchy
891 891
  label_cross_project_system: With all projects
892
  label_gantt_progress_line: Progress line
892 893

  
893 894
  button_login: Login
894 895
  button_submit: Submit
config/locales/ja.yml
840 840
  label_git_report_last_commit: ファイルとディレクトリの最新コミットを表示する
841 841
  label_parent_revision: 親
842 842
  label_child_revision: 子
843
  label_gantt_progress_line: イナズマ線
843 844

  
844 845
  button_login: ログイン
845 846
  button_submit: 送信
app/views/gantts/show.html.erb
1
<% content_for :header_tags do %>
2
  <%= javascript_include_tag 'raphael' %>
3
  <%= javascript_include_tag 'gantt' %>
4
<% end %>
5
<%= javascript_tag do %>
6
  $(document).ready(drawGanttHandler);
7
  $(window).resize(drawGanttHandler);
8
  $(function() {
9
    $("#draw_progress_line").change(drawGanttHandler);
10
  });
11
<% end %>
1 12
<% @gantt.view = self %>
2 13
<h2><%= @query.new_record? ? l(:label_gantt) : h(@query.name) %></h2>
3 14

  
......
111 122
</td>
112 123

  
113 124
<td>
114
<div style="position:relative;height:<%= t_height + 24 %>px;overflow:auto;">
125
<div style="position:relative;height:<%= t_height + 24 %>px;overflow:auto;" id="gantt_area">
115 126
<%
116 127
  style  = ""
117 128
  style += "width: #{g_width - 1}px;"
......
238 249
    style += "width:10px;"
239 250
    style += "border-left: 1px dashed red;"
240 251
  %>
241
  <%= content_tag(:div, '&nbsp;'.html_safe, :style => style) %>
252
  <%= content_tag(:div, '&nbsp;'.html_safe, :style => style, :id => 'today_line') %>
242 253
<% end %>
243

  
254
<%
255
  style  = ""
256
  style += "position: absolute;"
257
  style += "height: #{g_height}px;"
258
  style += "top: #{headers_height + 1}px;"
259
  style += "left: 0px;"
260
  style += "width: #{g_width - 1}px;"
261
%>
262
<%= content_tag(:div, '', :style => style, :id => "gantt_draw_area") %>
244 263
</div>
245 264
</td>
246 265
</tr>
public/javascripts/gantt.js
1
var draw_gantt = null;
2
var draw_top;
3
var draw_right;
4
var draw_left;
5

  
6
function setDrawArea() {
7
  draw_top   = $("#gantt_draw_area").position().top;
8
  draw_right = $("#gantt_draw_area").width();
9
  draw_left  = $("#gantt_area").scrollLeft();
10
}
11

  
12
function getProgressLinesArray() {
13
  var arr = new Array();
14
  var today_left = $('#today_line').position().left;
15
  arr.push({left: today_left, top: 0});
16
  $.each($('div.issue-subject, div.version-name'), function(index, element) {
17
    var t = $(element).position().top - draw_top ;
18
    var h = ($(element).height() / 9);
19
    var element_top_upper  = t - h;
20
    var element_top_center = t + (h * 3);
21
    var element_top_lower  = t + (h * 8);
22
    var issue_closed   = $(element).children('span').hasClass('issue-closed');
23
    var version_closed = $(element).children('span').hasClass('version-closed');
24
    if (issue_closed || version_closed) {
25
      arr.push({left: today_left, top: element_top_center});
26
    } else {
27
      var issue_done = $("#task-done-" + $(element).attr("id"));
28
      var is_behind_start = $(element).children('span').hasClass('behind-start-date');
29
      var is_over_end     = $(element).children('span').hasClass('over-end-date');
30
      if (is_over_end) {
31
        arr.push({left: draw_right, top: element_top_upper, is_right_edge: true});
32
        arr.push({left: draw_right, top: element_top_lower, is_right_edge: true, none_stroke: true});
33
      } else if (issue_done.size() > 0) {
34
        var done_left = issue_done.first().position().left +
35
                           issue_done.first().width();
36
        arr.push({left: done_left, top: element_top_center});
37
      } else if (is_behind_start) {
38
        arr.push({left: 0 , top: element_top_upper, is_left_edge: true});
39
        arr.push({left: 0 , top: element_top_lower, is_left_edge: true, none_stroke: true});
40
      } else {
41
        var todo_left = today_left;
42
        var issue_todo = $("#task-todo-" + $(element).attr("id"));
43
        if (issue_todo.size() > 0){
44
          todo_left = issue_todo.first().position().left;
45
        }
46
        arr.push({left: Math.min(today_left, todo_left), top: element_top_center});
47
      }
48
    }
49
  });
50
  return arr;
51
}
52

  
53
function drawGanttProgressLines() {
54
  var arr = getProgressLinesArray();
55
  var i;
56
  for(i = 1 ; i < arr.length ; i++) {
57
    if (!("none_stroke" in arr[i]) &&
58
        (!("is_right_edge" in arr[i - 1] && "is_right_edge" in arr[i]) &&
59
         !("is_left_edge"  in arr[i - 1] && "is_left_edge"  in arr[i]))
60
        ) {
61
      var x1 = (arr[i - 1].left == 0) ? 0 : arr[i - 1].left + draw_left;
62
      var x2 = (arr[i].left == 0)     ? 0 : arr[i].left     + draw_left;
63
      draw_gantt.path(["M", x1, arr[i - 1].top,
64
                       "L", x2, arr[i].top])
65
                   .attr({stroke: "#ff0000", "stroke-width": 2});
66
    }
67
  }
68
}
69

  
70
function drawGanttHandler() {
71
  var folder = document.getElementById('gantt_draw_area');
72
  if(draw_gantt != null)
73
    draw_gantt.clear();
74
  else
75
    draw_gantt = Raphael(folder);
76
  setDrawArea();
77
  if ($("#draw_progress_line").attr('checked'))
78
    drawGanttProgressLines();
79
}
(5-5/10)