backlog 0.5.8 → 0.5.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,7 @@
1
+ == 0.5.9 2007-08-06
2
+
3
+ * Aligned burn down graphs to even numbers
4
+
1
5
  == 0.5.8 2007-08-06
2
6
 
3
7
  * Fixed bug in daily_work_sheet
@@ -108,82 +108,11 @@ class PeriodsController < ApplicationController
108
108
 
109
109
  def send_burn_down_chart(size)
110
110
  period = Period.find(params[:id])
111
- g = Gruff::Line.new(size)
112
- g.theme_37signals
113
- g.title = l(:burn_down_chart) + " " + period.to_s
114
- g.font = '/usr/share/fonts/bitstream-vera/Vera.ttf'
115
- g.legend_font_size = 14
116
- g.hide_dots = true
117
- g.colors = %w{blue orange}
118
- if period.track_work?
119
- g.colors += %w{green}
120
- end
121
- if previous_period = period.higher_item
122
- g.colors += %w{grey grey}
123
- end
124
- if period.active?
125
- g.colors += %w{lightblue #d7a790}
126
- end
127
-
128
- recorded_dates = period.recorded_dates
129
- observed_todo_data = get_todo_data(recorded_dates, period)
130
- actual_todo_data = get_todo_data(recorded_dates, period, true)
131
- g.data("#{l :todo} (#{l :obs})", observed_todo_data)
132
- g.data("#{l :calc}", actual_todo_data)
133
- g.data(l(:done), get_work_data(recorded_dates, period)) if period.track_work?
134
- if previous_period = period.higher_item
135
- g.data("#{l :previous} #{l :obs}", get_todo_data(previous_period.dates, previous_period))
136
- g.data("#{l :calc}", get_todo_data(previous_period.dates, previous_period, true))
137
- end
138
-
139
- if period.active?
140
- g.data(l(:projection), projection_data(observed_todo_data, period))
141
- g.data(l(:projection), projection_data(actual_todo_data, period))
142
- end
143
-
144
- g.minimum_value = 0
145
-
146
- all_dates = period.dates
147
- labels = {0 => all_dates.first.to_s, all_dates.length-1 => all_dates.last.to_s}
148
- labels.merge({all_dates.index(Date.today) => Date.today.to_s}) if all_dates.index(Date.today) && (all_dates.index(Date.today) / all_dates.length) > 0.10
149
- g.labels = labels
150
-
151
- # g.draw_vertical_legend
152
-
153
- g.maximum_value = g.maximum_value.to_i
154
-
111
+ g = period.burn_down_graph(size)
155
112
  send_data(g.to_blob,
156
113
  :disposition => 'inline',
157
114
  :type => 'image/png',
158
115
  :filename => "burn_down_chart.png")
159
116
  end
160
117
 
161
- def get_todo_data(dates, period, actual=false)
162
- dates.map { |date| period.estimate_data(date, actual) }
163
- end
164
-
165
- def get_work_data(dates, period)
166
- dates.map { |date| period.work_data(date) }
167
- end
168
-
169
- def projection_data(observed_todo_data, period)
170
- if observed_todo_data.length <= 1
171
- velocity = 0
172
- else
173
- velocity = (observed_todo_data[-1] - observed_todo_data[0]).to_f / (observed_todo_data.length-1)
174
- end
175
- projection_data = period.dates.map do |date|
176
- if date < Date.today
177
- nil
178
- else
179
- if observed_todo_data.length == 1
180
- observed_todo_data[0]
181
- else
182
- value = observed_todo_data[0] + (date-period.start_on).to_f*velocity
183
- value >= 0 ? value : 0
184
- end
185
- end
186
- end
187
- end
188
-
189
118
  end
@@ -1,14 +1,16 @@
1
1
  class Period < ActiveRecord::Base
2
+ include Localization
3
+
2
4
  belongs_to :party
3
5
  acts_as_list :scope => :party, :order => :position
4
6
  has_many :tasks, :order => 'position, finished_at', :dependent => :destroy
5
7
  validates_associated :party
6
8
  validates_uniqueness_of :position, :scope => :party_id
7
-
9
+
8
10
  def validate
9
11
  errors.add "A period cannot end before it starts" unless end_on >= start_on
10
12
  end
11
-
13
+
12
14
  def self.find_active_or_future
13
15
  find(:all, :conditions => "end_on >= '#{Date.today.strftime '%Y-%m-%d'}'")
14
16
  end
@@ -16,11 +18,11 @@ class Period < ActiveRecord::Base
16
18
  def completed_tasks
17
19
  tasks.select {|task| task.completed?}
18
20
  end
19
-
21
+
20
22
  def open_tasks
21
23
  tasks.select {|task| task.active?}
22
24
  end
23
-
25
+
24
26
  def most_frequent_backlog
25
27
  all_backlogs = tasks.map {|t| t.backlog}.compact
26
28
  return nil if all_backlogs.empty?
@@ -35,7 +37,7 @@ class Period < ActiveRecord::Base
35
37
  def active?(check_tasks = false)
36
38
  start_on <= Date.today && (end_on >= Date.today || (check_tasks && tasks.select {|task| task.active?}.size > 0))
37
39
  end
38
-
40
+
39
41
  def future?
40
42
  start_on >= Date.today
41
43
  end
@@ -47,7 +49,7 @@ class Period < ActiveRecord::Base
47
49
  def passed?
48
50
  end_on < Date.today
49
51
  end
50
-
52
+
51
53
  def estimate_data(date, actual=false)
52
54
  total = BigDecimal('0')
53
55
  tasks.each do |task|
@@ -55,7 +57,7 @@ class Period < ActiveRecord::Base
55
57
  end
56
58
  total
57
59
  end
58
-
60
+
59
61
  def work_data(date)
60
62
  total = BigDecimal('0')
61
63
  tasks.each do |task|
@@ -63,7 +65,7 @@ class Period < ActiveRecord::Base
63
65
  end
64
66
  total
65
67
  end
66
-
68
+
67
69
  def required_speed
68
70
  todo = estimate_data(Date.today)
69
71
  remaining_days = end_on - Date.today
@@ -77,21 +79,21 @@ class Period < ActiveRecord::Base
77
79
  todo * (-remaining_days)
78
80
  end
79
81
  end
80
-
82
+
81
83
  def to_s
82
84
  name
83
85
  end
84
-
86
+
85
87
  def name
86
88
  "#{party.name}##{position}"
87
89
  end
88
-
90
+
89
91
  def dates
90
92
  all_dates = []
91
93
  start_on.upto(end_on) {|date| all_dates << date}
92
94
  return all_dates
93
95
  end
94
-
96
+
95
97
  def recorded_dates
96
98
  dates = []
97
99
  if start_on > Date.today
@@ -153,9 +155,84 @@ class Period < ActiveRecord::Base
153
155
  def invoice?
154
156
  not backlogs.find {|backlog| backlog.enable_invoicing?}.nil?
155
157
  end
156
-
158
+
157
159
  def backlogs
158
160
  tasks.map {|task| task.backlog}.uniq
159
161
  end
160
162
 
163
+ def burn_down_graph(size)
164
+ g = Gruff::Line.new(size)
165
+ g.theme_37signals
166
+ g.title = l(:burn_down_chart) + " " + name
167
+ g.font = '/usr/share/fonts/bitstream-vera/Vera.ttf'
168
+ g.legend_font_size = 14
169
+ g.hide_dots = true
170
+ g.colors = %w{blue orange}
171
+ if track_work?
172
+ g.colors += %w{green}
173
+ end
174
+ if previous_period = higher_item
175
+ g.colors += %w{grey grey}
176
+ end
177
+ if active?
178
+ g.colors += %w{lightblue #d7a790}
179
+ end
180
+
181
+ recorded_dates = self.recorded_dates
182
+ observed_todo_data = get_todo_data(recorded_dates)
183
+ actual_todo_data = get_todo_data(recorded_dates, true)
184
+ g.data("#{l :todo} (#{l :obs})", observed_todo_data)
185
+ g.data("#{l :calc}", actual_todo_data)
186
+ g.data(l(:done), get_work_data(recorded_dates)) if track_work?
187
+ if previous_period = higher_item
188
+ g.data("#{l :previous} #{l :obs}", previous_period.get_todo_data(previous_period.dates))
189
+ g.data("#{l :calc}", previous_period.get_todo_data(previous_period.dates, true))
190
+ end
191
+
192
+ if active?
193
+ g.data(l(:projection), projection_data(observed_todo_data))
194
+ g.data(l(:projection), projection_data(actual_todo_data))
195
+ end
196
+
197
+ g.minimum_value = 0
198
+
199
+ all_dates = dates
200
+ labels = {0 => all_dates.first.to_s, all_dates.length-1 => all_dates.last.to_s}
201
+ labels.merge({all_dates.index(Date.today) => Date.today.to_s}) if all_dates.index(Date.today) && (all_dates.index(Date.today) / all_dates.length) > 0.10
202
+ g.labels = labels
203
+
204
+ # g.draw_vertical_legend
205
+
206
+ g.maximum_value = (g.maximum_value.to_s[0..0].to_i + 1) * (10**Math::log10(g.maximum_value.to_i).to_i)
207
+ g
208
+ end
209
+
210
+ def get_todo_data(dates, actual=false)
211
+ dates.map { |date| estimate_data(date, actual) }
212
+ end
213
+
214
+ def get_work_data(dates)
215
+ dates.map { |date| work_data(date) }
216
+ end
217
+
218
+ def projection_data(observed_todo_data)
219
+ if observed_todo_data.length <= 1
220
+ velocity = 0
221
+ else
222
+ velocity = (observed_todo_data[-1] - observed_todo_data[0]).to_f / (observed_todo_data.length-1)
223
+ end
224
+ projection_data = dates.map do |date|
225
+ if date < Date.today
226
+ nil
227
+ else
228
+ if observed_todo_data.length == 1
229
+ observed_todo_data[0]
230
+ else
231
+ value = observed_todo_data[0] + (date-start_on).to_f*velocity
232
+ value >= 0 ? value : 0
233
+ end
234
+ end
235
+ end
236
+ end
237
+
161
238
  end
metadata CHANGED
@@ -3,7 +3,7 @@ rubygems_version: 0.9.4
3
3
  specification_version: 1
4
4
  name: backlog
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.5.8
6
+ version: 0.5.9
7
7
  date: 2007-08-06 00:00:00 +02:00
8
8
  summary: Application to aid collecting, processing, organizing, reviewing and doing tasks.
9
9
  require_paths: