Project

General

Profile

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

Toshi MARUYAMA, 2013-01-09 10:48

View differences:

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", params[:draw_progress_line], false %>
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) %>
......
229 238
    style += "width:10px;"
230 239
    style += "border-left: 1px dashed red;"
231 240
  %>
232
  <%= content_tag(:div, '&nbsp;'.html_safe, :style => style) %>
241
  <%= content_tag(:div, '&nbsp;'.html_safe, :style => style, :id => 'today_line') %>
233 242
<% end %>
234 243
<%
235 244
  style  = ""
......
279 288
  var issue_relation_type = <%= raw Redmine::Helpers::Gantt::DRAW_TYPES.to_json %>;
280 289
  $(document).ready(drawGanttHandler);
281 290
  $(window).resize(drawGanttHandler);
291
  $(function() {
292
    $("#draw_progress_line").change(drawGanttHandler);
293
  });
282 294
<% end %>
config/locales/en.yml
883 883
  label_cross_project_tree: With project tree
884 884
  label_cross_project_hierarchy: With project hierarchy
885 885
  label_cross_project_system: With all projects
886
  label_gantt_progress_line: Progress line
886 887

  
887 888
  button_login: Login
888 889
  button_submit: Submit
config/locales/ja.yml
834 834
  label_git_report_last_commit: ファイルとディレクトリの最新コミットを表示する
835 835
  label_parent_revision: 親
836 836
  label_child_revision: 子
837
  label_gantt_progress_line: イナズマ線
837 838

  
838 839
  button_login: ログイン
839 840
  button_submit: 送信
lib/redmine/helpers/gantt.rb
308 308
          html_class << 'icon icon-package '
309 309
          html_class << (version.behind_schedule? ? 'version-behind-schedule' : '') << " "
310 310
          html_class << (version.overdue? ? 'version-overdue' : '')
311
          html_class << ' version-closed' unless version.open?
312
          if version.start_date && version.due_date && version.completed_pourcent
313
            progress_date = calc_progress_date(version.start_date,
314
                                               version.due_date, version.completed_pourcent)
315
            html_class << ' behind-start-date' if progress_date < self.date_from
316
            html_class << ' over-end-date' if progress_date > self.date_to
317
          end
311 318
          s = view.link_to_version(version).html_safe
312 319
          subject = view.content_tag(:span, s,
313 320
                                     :class => html_class).html_safe
314
          html_subject(options, subject, :css => "version-name")
321
          html_subject(options, subject, :css => "version-name",
322
                       :id => "version-#{version.id}")
315 323
        when :image
316 324
          image_subject(options, version.to_s_with_project)
317 325
        when :pdf
......
332 340
          label = h("#{version.project} -") + label unless @project && @project == version.project
333 341
          case options[:format]
334 342
          when :html
335
            html_task(options, coords, :css => "version task", :label => label, :markers => true)
343
            html_task(options, coords, :css => "version task",
344
                      :label => label, :markers => true, :version => version)
336 345
          when :image
337 346
            image_task(options, coords, :label => label, :markers => true, :height => 3)
338 347
          when :pdf
......
354 363
          css_classes << ' issue-overdue' if issue.overdue?
355 364
          css_classes << ' issue-behind-schedule' if issue.behind_schedule?
356 365
          css_classes << ' icon icon-issue' unless Setting.gravatar_enabled? && issue.assigned_to
366
          css_classes << ' issue-closed' if issue.closed?
367
          if issue.start_date && issue.due_before && issue.done_ratio
368
            progress_date = calc_progress_date(issue.start_date,
369
                                               issue.due_before, issue.done_ratio)
370
            css_classes << ' behind-start-date' if progress_date < self.date_from
371
            css_classes << ' over-end-date' if progress_date > self.date_to
372
          end
357 373
          s = "".html_safe
358 374
          if issue.assigned_to.present?
359 375
            assigned_string = l(:field_assigned_to) + ": " + issue.assigned_to.name
......
365 381
          s << view.link_to_issue(issue).html_safe
366 382
          subject = view.content_tag(:span, s, :class => css_classes).html_safe
367 383
          html_subject(options, subject, :css => "issue-subject",
368
                       :title => issue.subject) + "\n"
384
                       :title => issue.subject, :id => "issue-#{issue.id}") + "\n"
369 385
        when :image
370 386
          image_subject(options, issue.subject)
371 387
        when :pdf
......
628 644
            coords[:bar_end] = self.date_to - self.date_from + 1
629 645
          end
630 646
          if progress
631
            progress_date = start_date + (end_date - start_date + 1) * (progress / 100.0)
647
            progress_date = calc_progress_date(start_date, end_date, progress)
632 648
            if progress_date > self.date_from && progress_date > start_date
633 649
              if progress_date < self.date_to
634 650
                coords[:bar_progress_end] = progress_date - self.date_from
......
655 671
        coords
656 672
      end
657 673

  
674
      def calc_progress_date(start_date, end_date, progress)
675
        start_date + (end_date - start_date + 1) * (progress / 100.0)
676
      end
677

  
658 678
      # Sorts a collection of issues by start_date, due_date, id for gantt rendering
659 679
      def sort_issues!(issues)
660 680
        issues.sort! { |a, b| gantt_issue_compare(a, b) }
......
695 715
      def html_subject(params, subject, options={})
696 716
        style = "position: absolute;top:#{params[:top]}px;left:#{params[:indent]}px;"
697 717
        style << "width:#{params[:subject_width] - params[:indent]}px;" if params[:subject_width]
698
        output = view.content_tag('div', subject,
718
        output = view.content_tag(:div, subject,
699 719
                                  :class => options[:css], :style => style,
700
                                  :title => options[:title])
720
                                  :title => options[:title],
721
                                  :id => options[:id])
701 722
        @subjects << output
702 723
        output
703 724
      end
......
742 763
          style << "left:#{coords[:bar_start]}px;"
743 764
          style << "width:#{width}px;"
744 765
          html_id = "task-todo-issue-#{options[:issue].id}" if options[:issue]
766
          html_id = "task-todo-version-#{options[:version].id}" if options[:version]
745 767
          content_opt = {:style => style,
746 768
                         :class => "#{options[:css]} task_todo",
747 769
                         :id => html_id}
......
768 790
            style << "top:#{params[:top]}px;"
769 791
            style << "left:#{coords[:bar_start]}px;"
770 792
            style << "width:#{width}px;"
793
            html_id = "task-done-issue-#{options[:issue].id}" if options[:issue]
794
            html_id = "task-done-version-#{options[:version].id}" if options[:version]
771 795
            output << view.content_tag(:div, '&nbsp;'.html_safe,
772 796
                                       :style => style,
773
                                       :class => "#{options[:css]} task_done")
797
                                       :class => "#{options[:css]} task_done",
798
                                       :id => html_id)
774 799
          end
775 800
        end
776 801
        # Renders the markers
public/javascripts/gantt.js
98 98
  });
99 99
}
100 100

  
101
function getProgressLinesArray() {
102
  var arr = new Array();
103
  var today_left = $('#today_line').position().left;
104
  arr.push({left: today_left, top: 0});
105
  $.each($('div.issue-subject, div.version-name'), function(index, element) {
106
    var t = $(element).position().top - draw_top ;
107
    var h = ($(element).height() / 9);
108
    var element_top_upper  = t - h;
109
    var element_top_center = t + (h * 3);
110
    var element_top_lower  = t + (h * 8);
111
    var issue_closed   = $(element).children('span').hasClass('issue-closed');
112
    var version_closed = $(element).children('span').hasClass('version-closed');
113
    if (issue_closed || version_closed) {
114
      arr.push({left: today_left, top: element_top_center});
115
    } else {
116
      var issue_done = $("#task-done-" + $(element).attr("id"));
117
      var is_behind_start = $(element).children('span').hasClass('behind-start-date');
118
      var is_over_end     = $(element).children('span').hasClass('over-end-date');
119
      if (is_over_end) {
120
        arr.push({left: draw_right, top: element_top_upper, is_right_edge: true});
121
        arr.push({left: draw_right, top: element_top_lower, is_right_edge: true, none_stroke: true});
122
      } else if (issue_done.size() > 0) {
123
        var done_left = issue_done.first().position().left +
124
                           issue_done.first().width();
125
        arr.push({left: done_left, top: element_top_center});
126
      } else if (is_behind_start) {
127
        arr.push({left: 0 , top: element_top_upper, is_left_edge: true});
128
        arr.push({left: 0 , top: element_top_lower, is_left_edge: true, none_stroke: true});
129
      } else {
130
        var todo_left = today_left;
131
        var issue_todo = $("#task-todo-" + $(element).attr("id"));
132
        if (issue_todo.size() > 0){
133
          todo_left = issue_todo.first().position().left;
134
        }
135
        arr.push({left: Math.min(today_left, todo_left), top: element_top_center});
136
      }
137
    }
138
  });
139
  return arr;
140
}
141

  
142
function drawGanttProgressLines() {
143
  var arr = getProgressLinesArray();
144
  var color = $("#today_line")
145
                    .css("border-left-color");
146
  var i;
147
  for(i = 1 ; i < arr.length ; i++) {
148
    if (!("none_stroke" in arr[i]) &&
149
        (!("is_right_edge" in arr[i - 1] && "is_right_edge" in arr[i]) &&
150
         !("is_left_edge"  in arr[i - 1] && "is_left_edge"  in arr[i]))
151
        ) {
152
      var x1 = (arr[i - 1].left == 0) ? 0 : arr[i - 1].left + draw_left;
153
      var x2 = (arr[i].left == 0)     ? 0 : arr[i].left     + draw_left;
154
      draw_gantt.path(["M", x1, arr[i - 1].top,
155
                       "L", x2, arr[i].top])
156
                   .attr({stroke: color, "stroke-width": 2});
157
    }
158
  }
159
}
160

  
101 161
function drawGanttHandler() {
102 162
  var folder = document.getElementById('gantt_draw_area');
103 163
  if(draw_gantt != null)
......
105 165
  else
106 166
    draw_gantt = Raphael(folder);
107 167
  setDrawArea();
168
  if ($("#draw_progress_line").attr('checked'))
169
    drawGanttProgressLines();
108 170
  drawRelations();
109 171
}
app/views/gantts/show.html.erb
16 16
  <legend onclick="toggleFieldset(this);"><%= l(:label_display) %></legend>
17 17
  <div>
18 18
    <label>
19
      <%= check_box_tag "draw_rels", params["draw_rels"], true %>
20
      <%= l(:label_related_issues) %>
21
    </label>
22
    <label>
19 23
      <%= check_box_tag "draw_progress_line", params[:draw_progress_line], false %>
20 24
      <%= l(:label_gantt_progress_line) %>
21 25
    </label>
......
289 293
  $(document).ready(drawGanttHandler);
290 294
  $(window).resize(drawGanttHandler);
291 295
  $(function() {
296
    $("#draw_rels").change(drawGanttHandler);
292 297
    $("#draw_progress_line").change(drawGanttHandler);
293 298
  });
294 299
<% end %>
public/javascripts/gantt.js
167 167
  setDrawArea();
168 168
  if ($("#draw_progress_line").attr('checked'))
169 169
    drawGanttProgressLines();
170
  drawRelations();
170
  if ($("#draw_rels").attr('checked'))
171
    drawRelations();
171 172
}
app/views/gantts/show.html.erb
15 15
<fieldset id="filters" class="collapsible">
16 16
  <legend onclick="toggleFieldset(this);"><%= l(:label_display) %></legend>
17 17
  <div>
18
    <label>
19
      <%= check_box_tag "draw_rels", params["draw_rels"], true %>
20
      <%= l(:label_related_issues) %>
21
    </label>
22
    <label>
23
      <%= check_box_tag "draw_progress_line", params[:draw_progress_line], false %>
24
      <%= l(:label_gantt_progress_line) %>
25
    </label>
18
    <table>
19
      <tr>
20
        <td>
21
          <fieldset>
22
            <legend><%= l(:label_related_issues) %></legend>
23
            <label>
24
              <%= check_box_tag "draw_rels", params["draw_rels"], true %>
25
              <% rels = [IssueRelation::TYPE_BLOCKS, IssueRelation::TYPE_PRECEDES] %>
26
              <% rels.each do |rel| %>
27
                <% color = Redmine::Helpers::Gantt::DRAW_TYPES[rel][:color] %>
28
                <%= content_tag(:span, '&nbsp;&nbsp;&nbsp;'.html_safe,
29
                                :style => "background-color: #{color}") %>
30
                <%= l(IssueRelation::TYPES[rel][:name]) %>
31
              <% end %>
32
            </label>
33
          </fieldset>
34
        </td>
35
        <td>
36
          <fieldset>
37
            <legend><%= l(:label_gantt_progress_line) %></legend>
38
            <label>
39
              <%= check_box_tag "draw_progress_line", params[:draw_progress_line], false %>
40
              <%= l(:label_display) %>
41
            </label>
42
          </fieldset>
43
        </td>
44
      </tr>
45
    </table>
26 46
  </div>
27 47
</fieldset>
28 48

  
(10-10/10)