6 :license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses |
6 :license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses |
7 """ |
7 """ |
8 __docformat__ = "restructuredtext en" |
8 __docformat__ = "restructuredtext en" |
9 _ = unicode |
9 _ = unicode |
10 |
10 |
|
11 from math import floor |
|
12 |
11 from logilab.mtconverter import xml_escape |
13 from logilab.mtconverter import xml_escape |
12 |
14 |
|
15 from cubicweb.utils import make_uid |
13 from cubicweb.selectors import implements |
16 from cubicweb.selectors import implements |
14 from cubicweb.interfaces import IProgress, IMileStone |
17 from cubicweb.interfaces import IProgress, IMileStone |
15 from cubicweb.schema import display_name |
18 from cubicweb.schema import display_name |
16 from cubicweb.view import EntityView |
19 from cubicweb.view import EntityView |
17 from cubicweb.web.htmlwidgets import ProgressBarWidget |
|
18 |
20 |
19 |
21 |
20 class ProgressTableView(EntityView): |
22 class ProgressTableView(EntityView): |
21 """The progress table view is able to display progress information |
23 """The progress table view is able to display progress information |
22 of any object implement IMileStone. |
24 of any object implement IMileStone. |
180 """displays a progress bar""" |
182 """displays a progress bar""" |
181 __regid__ = 'progressbar' |
183 __regid__ = 'progressbar' |
182 title = _('progress bar') |
184 title = _('progress bar') |
183 __select__ = implements(IProgress) |
185 __select__ = implements(IProgress) |
184 |
186 |
|
187 precision = 0.1 |
|
188 red_threshold = 1.1 |
|
189 orange_threshold = 1.05 |
|
190 yellow_threshold = 1 |
|
191 |
|
192 @classmethod |
|
193 def overrun(cls, entity): |
|
194 """overrun = done + todo - """ |
|
195 if entity.done + entity.todo > entity.revised_cost: |
|
196 overrun = entity.done + entity.todo - entity.revised_cost |
|
197 else: |
|
198 overrun = 0 |
|
199 if overrun < cls.precision: |
|
200 overrun = 0 |
|
201 return overrun |
|
202 |
|
203 @classmethod |
|
204 def overrun_percentage(cls, entity): |
|
205 """pourcentage overrun = overrun / budget""" |
|
206 if entity.revised_cost == 0: |
|
207 return 0 |
|
208 else: |
|
209 return cls.overrun(entity) * 100. / entity.revised_cost |
|
210 |
185 def cell_call(self, row, col): |
211 def cell_call(self, row, col): |
186 self._cw.add_css('cubicweb.iprogress.css') |
212 self._cw.add_css('cubicweb.iprogress.css') |
187 self._cw.add_js('cubicweb.iprogress.js') |
213 self._cw.add_js('cubicweb.iprogress.js') |
188 entity = self.cw_rset.get_entity(row, col) |
214 entity = self.cw_rset.get_entity(row, col) |
189 widget = ProgressBarWidget(entity.done, entity.todo, |
215 done = entity.done |
190 entity.revised_cost) |
216 todo = entity.todo |
191 self.w(widget.render()) |
217 budget = entity.revised_cost |
192 |
218 if budget == 0: |
|
219 pourcent = 100 |
|
220 else: |
|
221 pourcent = done*100./budget |
|
222 if pourcent > 100.1: |
|
223 color = 'red' |
|
224 elif todo+done > self.red_threshold*budget: |
|
225 color = 'red' |
|
226 elif todo+done > self.orange_threshold*budget: |
|
227 color = 'orange' |
|
228 elif todo+done > self.yellow_threshold*budget: |
|
229 color = 'yellow' |
|
230 else: |
|
231 color = 'green' |
|
232 if pourcent < 0: |
|
233 pourcent = 0 |
|
234 |
|
235 if floor(done) == done or done>100: |
|
236 done_str = '%i' % done |
|
237 else: |
|
238 done_str = '%.1f' % done |
|
239 if floor(budget) == budget or budget>100: |
|
240 budget_str = '%i' % budget |
|
241 else: |
|
242 budget_str = '%.1f' % budget |
|
243 |
|
244 title = u'%s/%s = %i%%' % (done_str, budget_str, pourcent) |
|
245 short_title = title |
|
246 if self.overrun_percentage(entity): |
|
247 title += u' overrun +%sj (+%i%%)' % (self.overrun(entity), |
|
248 self.overrun_percentage(entity)) |
|
249 overrun = self.overrun(entity) |
|
250 if floor(overrun) == overrun or overrun>100: |
|
251 overrun_str = '%i' % overrun |
|
252 else: |
|
253 overrun_str = '%.1f' % overrun |
|
254 short_title += u' +%s' % overrun_str |
|
255 # write bars |
|
256 maxi = max(done+todo, budget) |
|
257 if maxi == 0: |
|
258 maxi = 1 |
|
259 |
|
260 cid = make_uid('progress_bar') |
|
261 self._cw.html_headers.add_onload('draw_progressbar("canvas%s", %i, %i, %i, "%s");' % |
|
262 (cid, |
|
263 int(100.*done/maxi), int(100.*(done+todo)/maxi), |
|
264 int(100.*budget/maxi), color), |
|
265 jsoncall=self._cw.json_request) |
|
266 self.w(u'%s<br/>' |
|
267 u'<canvas class="progressbar" id="canvas%s" width="100" height="10"></canvas>' |
|
268 % (short_title.replace(' ',' '), cid)) |