57
by Martin Pitt
burndown-chart: directly read from DB, simplify |
1 |
#!/usr/bin/python
|
2 |
#
|
|
3 |
# Create a burndown chart from a work item database.
|
|
282
by Martin Pitt
add license file and copyright headers |
4 |
#
|
5 |
# Copyright (C) 2010, 2011 Canonical Ltd.
|
|
6 |
# License: GPL-3
|
|
57
by Martin Pitt
burndown-chart: directly read from DB, simplify |
7 |
|
144
by Colin Watson
fix pyflakes unhappiness (trailing whitespace, unused imports) |
8 |
import optparse, datetime, sys |
57
by Martin Pitt
burndown-chart: directly read from DB, simplify |
9 |
import report_tools |
10 |
||
1
by Martin Pitt
initial commit |
11 |
from pychart import * |
12 |
||
13 |
def date_to_ordinal(s): |
|
57
by Martin Pitt
burndown-chart: directly read from DB, simplify |
14 |
'''Turn yyyy-mm-dd strings to ordinals'''
|
240.1.27
by James Westby
Report on how many workitems have to be fixed. |
15 |
return report_tools.date_to_python(s).toordinal() |
57
by Martin Pitt
burndown-chart: directly read from DB, simplify |
16 |
|
1
by Martin Pitt
initial commit |
17 |
|
57
by Martin Pitt
burndown-chart: directly read from DB, simplify |
18 |
def ordinal_to_date(ordinal): |
19 |
'''Turn an ordinal date into a string'''
|
|
20 |
d = datetime.date.fromordinal(int(ordinal)) |
|
21 |
return d.strftime('%Y-%m-%d') |
|
22 |
||
1
by Martin Pitt
initial commit |
23 |
def format_date(ordinal): |
24 |
d = datetime.date.fromordinal(int(ordinal)) |
|
57
by Martin Pitt
burndown-chart: directly read from DB, simplify |
25 |
return '/a60{}' + d.strftime('%b %d, %y') |
26 |
||
205.1.17
by Clint Byrum
- changing link for users to their wi tracker page on team pages |
27 |
def do_chart(data, start_date, end_date, trend_start, title, filename, only_weekdays, inverted,noforeign): |
57
by Martin Pitt
burndown-chart: directly read from DB, simplify |
28 |
#set up default values
|
72
by Martin Pitt
use svg to avoid ghostscript, looks better too |
29 |
format = 'svg' |
57
by Martin Pitt
burndown-chart: directly read from DB, simplify |
30 |
height = 450 |
31 |
width = 1000 |
|
32 |
legend_x = 700 |
|
33 |
legend_y = 200 |
|
34 |
title_x = 300 |
|
35 |
title_y = 350 |
|
36 |
||
205.2.7
by Thierry Carrez
base lines on the day before, since current day is work in progress |
37 |
if inverted: |
38 |
legend_x=200 |
|
39 |
||
57
by Martin Pitt
burndown-chart: directly read from DB, simplify |
40 |
# Tell pychart to use colors
|
41 |
theme.use_color = True |
|
42 |
theme.default_font_size = 12 |
|
43 |
theme.reinitialize() |
|
44 |
||
144
by Colin Watson
fix pyflakes unhappiness (trailing whitespace, unused imports) |
45 |
# turn into pychart data model and calculate maximum number of WIs
|
209
by Martin Pitt
burndown-chart: start at 1 to avoid zero division |
46 |
max_items = 1 # start at 1 to avoid zero div |
205.2.9
by Thierry Carrez
Initialize lastactive |
47 |
lastactive = 0 |
57
by Martin Pitt
burndown-chart: directly read from DB, simplify |
48 |
pcdata = [] |
49 |
||
50 |
for date in xrange(date_to_ordinal(start_date), date_to_ordinal(end_date)+1): |
|
205.2.2
by Thierry Carrez
Code cleanup |
51 |
if (not only_weekdays or datetime.date.fromordinal(date).weekday() < 5): |
219
by Thierry Carrez
Fix error in --only-weekdays when milestone ends on a Sunday |
52 |
end_date = ordinal_to_date(date) |
205.2.1
by Thierry Carrez
Added inverted and only-weekdays options |
53 |
i = data.get(ordinal_to_date(date), {}) |
205.1.11
by Clint Byrum
merging with trunk |
54 |
count = i.get('done', 0) + i.get('todo', 0) + i.get('blocked', 0) + i.get('inprogress', 0) + i.get('postponed', 0) |
205.2.1
by Thierry Carrez
Added inverted and only-weekdays options |
55 |
if max_items < count: |
56 |
max_items = count |
|
205.1.17
by Clint Byrum
- changing link for users to their wi tracker page on team pages |
57 |
if noforeign: |
58 |
# This total is always higher
|
|
59 |
pcdata.append((date, i.get('todo', 0),0, |
|
60 |
i.get('blocked', 0),0, |
|
61 |
i.get('inprogress', 0),0, |
|
62 |
i.get('done',0),0, |
|
63 |
i.get('postponed',0),0, count)) |
|
64 |
else: |
|
65 |
pcdata.append((date, i.get('todo_teamonly', 0), i.get('todo', 0), |
|
66 |
i.get('blocked_teamonly', 0), i.get('blocked', 0), |
|
67 |
i.get('inprogress_teamonly', 0), i.get('inprogress', 0), |
|
68 |
i.get('done_teamonly', 0), i.get('done', 0), |
|
69 |
i.get('postponed_teamonly', 0), i.get('postponed', 0), count)) |
|
205.2.1
by Thierry Carrez
Added inverted and only-weekdays options |
70 |
if count > 0: |
71 |
lastactive = len(pcdata) - 1 |
|
57
by Martin Pitt
burndown-chart: directly read from DB, simplify |
72 |
|
73 |
# add some extra space to look nicer
|
|
74 |
max_items = int(max_items * 1.05) |
|
75 |
||
76 |
x_interval = len(pcdata)/20 |
|
73
by Martin Pitt
burndown-chart: automatically calculate a sensible y interval |
77 |
if max_items > 500: |
78 |
y_interval = max_items/200*10 |
|
240.1.32
by James Westby
Force minimum y interval to 1. |
79 |
elif max_items < 20: |
80 |
y_interval = 1 |
|
73
by Martin Pitt
burndown-chart: automatically calculate a sensible y interval |
81 |
else: |
82 |
y_interval = max_items/20 |
|
57
by Martin Pitt
burndown-chart: directly read from DB, simplify |
83 |
|
84 |
# create the chart object
|
|
144
by Colin Watson
fix pyflakes unhappiness (trailing whitespace, unused imports) |
85 |
chart_object.set_defaults(area.T, size=(width, height), |
57
by Martin Pitt
burndown-chart: directly read from DB, simplify |
86 |
y_range=(0, None), x_coord=category_coord.T(pcdata, 0)) |
87 |
||
88 |
# tell the chart object it will use a bar chart, and will
|
|
89 |
# use the data list for it's model
|
|
90 |
chart_object.set_defaults(bar_plot.T, data=pcdata) |
|
91 |
||
92 |
# create the chart area
|
|
93 |
# tell it to start at coords 0,0
|
|
94 |
# tell it the labels, and the tics, etc..
|
|
205.1.8
by Clint Byrum
only show user direct assigned items on personal page |
95 |
# HACK: to prevent 0 div
|
96 |
if max_items == 0: |
|
97 |
max_items = 1 |
|
57
by Martin Pitt
burndown-chart: directly read from DB, simplify |
98 |
ar = area.T(legend=legend.T(loc=(legend_x,legend_y)), loc=(0,0), |
99 |
x_axis=axis.X(label='Date', tic_interval=x_interval,format=format_date), |
|
100 |
y_axis=axis.Y(label='Work Items', tic_interval=y_interval), |
|
101 |
y_range=(0, max_items)) |
|
102 |
||
103 |
#initialize the blar_plot fill styles
|
|
104 |
bar_plot.fill_styles.reset() |
|
105 |
||
106 |
# create each set of data to plot
|
|
107 |
# note that index zero is the label col
|
|
108 |
# for each column of data, tell it what to use for the legend and
|
|
109 |
# what color to make the bar, no lines, and
|
|
110 |
# what plot to stack on
|
|
205.1.17
by Clint Byrum
- changing link for users to their wi tracker page on team pages |
111 |
|
112 |
# Suppressed when running w/o foreign numbers
|
|
113 |
if noforeign: |
|
114 |
tlabel = '' |
|
115 |
else: |
|
116 |
tlabel = ' (team)' |
|
117 |
||
205.2.2
by Thierry Carrez
Code cleanup |
118 |
if inverted: |
227.1.1
by Clint Byrum
fixing inverted chart missing foreign done items (good eyes ttx) |
119 |
plot1 = bar_plot.T(label='done' + tlabel, hcol=7) |
240.1.26
by James Westby
Some style updates to the burndowns and overview page. |
120 |
plot1.fill_style = fill_style.Plain(bgcolor=color.seagreen) |
227.1.1
by Clint Byrum
fixing inverted chart missing foreign done items (good eyes ttx) |
121 |
plot2 = bar_plot.T(label='done (foreign)', hcol=8) |
240.1.26
by James Westby
Some style updates to the burndowns and overview page. |
122 |
plot2.fill_style = fill_style.Plain(bgcolor=color.limegreen) |
205.2.2
by Thierry Carrez
Code cleanup |
123 |
|
205.1.17
by Clint Byrum
- changing link for users to their wi tracker page on team pages |
124 |
plot3 = bar_plot.T(label='inprogress' + tlabel, hcol=5, stack_on = plot2) |
240.1.26
by James Westby
Some style updates to the burndowns and overview page. |
125 |
plot3.fill_style = fill_style.Plain(bgcolor=color.gray65) |
205.1.11
by Clint Byrum
merging with trunk |
126 |
plot4 = bar_plot.T(label='inprogress (foreign)', hcol=6, stack_on = plot2) |
240.1.26
by James Westby
Some style updates to the burndowns and overview page. |
127 |
plot4.fill_style = fill_style.Plain(bgcolor=color.gray74) |
205.2.4
by Thierry Carrez
Merge latest HEAD, add newchart_teams trigger |
128 |
|
205.1.17
by Clint Byrum
- changing link for users to their wi tracker page on team pages |
129 |
plot5 = bar_plot.T(label='blocked' + tlabel, hcol=3, stack_on = plot4) |
240.1.26
by James Westby
Some style updates to the burndowns and overview page. |
130 |
plot5.fill_style = fill_style.Plain(bgcolor=color.red1) |
205.1.11
by Clint Byrum
merging with trunk |
131 |
plot6 = bar_plot.T(label='blocked (foreign)', hcol=4, stack_on = plot4) |
240.1.26
by James Westby
Some style updates to the burndowns and overview page. |
132 |
plot6.fill_style = fill_style.Plain(bgcolor=color.red3) |
205.1.11
by Clint Byrum
merging with trunk |
133 |
|
205.1.17
by Clint Byrum
- changing link for users to their wi tracker page on team pages |
134 |
plot7 = bar_plot.T(label='todo' + tlabel, hcol=1, stack_on = plot6) |
240.1.26
by James Westby
Some style updates to the burndowns and overview page. |
135 |
plot7.fill_style = fill_style.Plain(bgcolor=color.darkorange1) |
205.1.11
by Clint Byrum
merging with trunk |
136 |
plot8 = bar_plot.T(label='todo (foreign)', hcol=2, stack_on = plot6) |
240.1.26
by James Westby
Some style updates to the burndowns and overview page. |
137 |
plot8.fill_style = fill_style.Plain(bgcolor=color.orangered1) |
205.2.2
by Thierry Carrez
Code cleanup |
138 |
else: |
205.1.17
by Clint Byrum
- changing link for users to their wi tracker page on team pages |
139 |
plot1 = bar_plot.T(label='todo' + tlabel, hcol=1) |
240.1.26
by James Westby
Some style updates to the burndowns and overview page. |
140 |
plot1.fill_style = fill_style.Plain(bgcolor=color.darkorange1) |
205.2.2
by Thierry Carrez
Code cleanup |
141 |
plot2 = bar_plot.T(label='todo (foreign)', hcol=2) |
240.1.26
by James Westby
Some style updates to the burndowns and overview page. |
142 |
plot2.fill_style = fill_style.Plain(bgcolor=color.orangered1) |
205.2.2
by Thierry Carrez
Code cleanup |
143 |
|
205.1.17
by Clint Byrum
- changing link for users to their wi tracker page on team pages |
144 |
plot3 = bar_plot.T(label='blocked' + tlabel, hcol=3, stack_on = plot2) |
240.1.26
by James Westby
Some style updates to the burndowns and overview page. |
145 |
plot3.fill_style = fill_style.Plain(bgcolor=color.red1) |
205.1.11
by Clint Byrum
merging with trunk |
146 |
plot4 = bar_plot.T(label='blocked (foreign)', hcol=4, stack_on = plot2) |
240.1.26
by James Westby
Some style updates to the burndowns and overview page. |
147 |
plot4.fill_style = fill_style.Plain(bgcolor=color.red3) |
205.1.11
by Clint Byrum
merging with trunk |
148 |
|
205.1.17
by Clint Byrum
- changing link for users to their wi tracker page on team pages |
149 |
plot5 = bar_plot.T(label='inprogress' + tlabel, hcol=5, stack_on = plot4) |
240.1.26
by James Westby
Some style updates to the burndowns and overview page. |
150 |
plot5.fill_style = fill_style.Plain(bgcolor=color.gray65) |
205.1.11
by Clint Byrum
merging with trunk |
151 |
plot6 = bar_plot.T(label='inprogress (foreign)', hcol=6, stack_on = plot4) |
240.1.26
by James Westby
Some style updates to the burndowns and overview page. |
152 |
plot6.fill_style = fill_style.Plain(bgcolor=color.gray74) |
205.1.11
by Clint Byrum
merging with trunk |
153 |
|
205.1.17
by Clint Byrum
- changing link for users to their wi tracker page on team pages |
154 |
plot7 = bar_plot.T(label='done' + tlabel, hcol=7, stack_on = plot6) |
240.1.26
by James Westby
Some style updates to the burndowns and overview page. |
155 |
plot7.fill_style = fill_style.Plain(bgcolor=color.seagreen) |
205.1.11
by Clint Byrum
merging with trunk |
156 |
plot8 = bar_plot.T(label='done (foreign)', hcol=8, stack_on = plot6) |
240.1.26
by James Westby
Some style updates to the burndowns and overview page. |
157 |
plot8.fill_style = fill_style.Plain(bgcolor=color.limegreen) |
205.2.4
by Thierry Carrez
Merge latest HEAD, add newchart_teams trigger |
158 |
|
205.2.2
by Thierry Carrez
Code cleanup |
159 |
|
57
by Martin Pitt
burndown-chart: directly read from DB, simplify |
160 |
plot1.line_style = None |
161 |
plot2.line_style = None |
|
162 |
plot3.line_style = None |
|
92
by Martin Pitt
burndown-chart: show both team-only and foreign counts |
163 |
plot4.line_style = None |
164 |
plot5.line_style = None |
|
165 |
plot6.line_style = None |
|
205.1.3
by Clint Byrum
adding inprogress status support |
166 |
plot7.line_style = None |
167 |
plot8.line_style = None |
|
168 |
||
205.1.11
by Clint Byrum
merging with trunk |
169 |
|
205.1.17
by Clint Byrum
- changing link for users to their wi tracker page on team pages |
170 |
plot9 = bar_plot.T(label='postponed' + tlabel, hcol=9, stack_on = plot8) |
240.1.26
by James Westby
Some style updates to the burndowns and overview page. |
171 |
plot9.fill_style = fill_style.Plain(bgcolor=color.purple) |
205.1.9
by Clint Byrum
- adding blocked status |
172 |
plot9.line_style = None |
173 |
plot10 = bar_plot.T(label="postponed (foreign) ", hcol=10, stack_on = plot8) |
|
240.1.26
by James Westby
Some style updates to the burndowns and overview page. |
174 |
plot10.fill_style = fill_style.Plain(bgcolor=color.mediumorchid) |
205.1.9
by Clint Byrum
- adding blocked status |
175 |
plot10.line_style = None |
176 |
||
177 |
plot11 = bar_plot.T(label='total', hcol=9) |
|
205.1.15
by Clint Byrum
Re-showing data points accidentally hidden in burndown chart |
178 |
plot11.fill_style = None |
179 |
plot11.line_style = line_style.gray30 |
|
57
by Martin Pitt
burndown-chart: directly read from DB, simplify |
180 |
|
181 |
# create the canvas with the specified filename and file format
|
|
182 |
can = canvas.init(filename,format) |
|
183 |
||
184 |
# add the data to the area and draw it
|
|
205.1.17
by Clint Byrum
- changing link for users to their wi tracker page on team pages |
185 |
if noforeign: |
186 |
plot3.stack_on = plot1 |
|
187 |
plot5.stack_on = plot3 |
|
188 |
plot7.stack_on = plot5 |
|
189 |
plot9.stack_on = plot7 |
|
190 |
ar.add_plot(plot1, plot3, plot5, plot7, plot9) |
|
191 |
else: |
|
192 |
ar.add_plot(plot2, plot1, plot4, plot3, plot6, plot5, plot8, plot7, plot10, plot9) |
|
193 |
||
57
by Martin Pitt
burndown-chart: directly read from DB, simplify |
194 |
ar.draw() |
195 |
||
196 |
# create and arrow for the trend line
|
|
197 |
trend_line = arrow.T(head_style=1) |
|
198 |
# remove heads so arrow becomes a line
|
|
199 |
trend_line.head_len = 0 |
|
200 |
trend_line.thickness = 0 |
|
201 |
trend_line.line_style.width = 3 |
|
202 |
||
203 |
# set up the trend line position and draw it
|
|
205.2.1
by Thierry Carrez
Added inverted and only-weekdays options |
204 |
if inverted: |
205.2.7
by Thierry Carrez
base lines on the day before, since current day is work in progress |
205 |
if lastactive > 1: |
205.1.18
by Clint Byrum
- fixing burnup chart trend line |
206 |
trend_line.draw([(0, 0), (ar.x_pos(pcdata[lastactive-1][0]),ar.y_pos(pcdata[lastactive-1][8]))]) |
205.2.7
by Thierry Carrez
base lines on the day before, since current day is work in progress |
207 |
trend_line.line_style = line_style.black_dash1 |
205.2.1
by Thierry Carrez
Added inverted and only-weekdays options |
208 |
trend_line.line_style.width = 3 |
227
by Clint Byrum
fixing inverted chart line missing inprogress |
209 |
trend_line.draw([(ar.x_pos(pcdata[lastactive-1][0]),ar.y_pos(pcdata[lastactive-1][8])), (ar.x_pos(date_to_ordinal(end_date)),ar.y_pos(pcdata[lastactive][2]+pcdata[lastactive][4]+pcdata[lastactive][6]+pcdata[lastactive][8]))]) |
205.2.1
by Thierry Carrez
Added inverted and only-weekdays options |
210 |
else: |
205.2.2
by Thierry Carrez
Code cleanup |
211 |
if not trend_start: |
205.1.17
by Clint Byrum
- changing link for users to their wi tracker page on team pages |
212 |
if noforeign: |
243
by Martin Pitt
burndown-chart: fix trend line start to consider "in progress" and "blocked" items |
213 |
trend_start = pcdata[0][1] + pcdata[0][3] + pcdata[0][5] |
205.1.17
by Clint Byrum
- changing link for users to their wi tracker page on team pages |
214 |
else: |
243
by Martin Pitt
burndown-chart: fix trend line start to consider "in progress" and "blocked" items |
215 |
trend_start = pcdata[0][2] + pcdata[0][4] + pcdata[0][6] |
205.2.1
by Thierry Carrez
Added inverted and only-weekdays options |
216 |
trend_line.draw([(0, ar.y_pos(trend_start)), (ar.x_pos(date_to_ordinal(end_date)), 0)]) |
217 |
||
57
by Martin Pitt
burndown-chart: directly read from DB, simplify |
218 |
# title
|
219 |
tb = text_box.T(loc=(title_x, title_y), text=title, line_style=None) |
|
72
by Martin Pitt
use svg to avoid ghostscript, looks better too |
220 |
tb.fill_style = None |
57
by Martin Pitt
burndown-chart: directly read from DB, simplify |
221 |
tb.draw() |
222 |
||
223 |
#
|
|
224 |
# main
|
|
225 |
#
|
|
226 |
||
227 |
# argv parsing
|
|
228 |
optparser = optparse.OptionParser() |
|
229 |
optparser.add_option('-d', '--database', |
|
230 |
help='Path to database', dest='database', metavar='PATH') |
|
231 |
optparser.add_option('-t', '--team', |
|
232 |
help='Restrict report to a particular team', dest='team') |
|
233 |
optparser.add_option('-m', '--milestone', |
|
234 |
help='Restrict report to a particular milestone', dest='milestone') |
|
235 |
optparser.add_option('-o', '--output', |
|
236 |
help='Output file', dest='output') |
|
237 |
optparser.add_option('--trend-start', type='int', |
|
238 |
help='Explicitly set start of trend line', dest='trendstart') |
|
205.1.8
by Clint Byrum
only show user direct assigned items on personal page |
239 |
optparser.add_option('-u', '--user', |
240 |
help='Run for this user', dest='user') |
|
205.2.1
by Thierry Carrez
Added inverted and only-weekdays options |
241 |
optparser.add_option('--only-weekdays', action='store_true', |
242 |
help='Skip Saturdays and Sundays in the resulting graph', dest='only_weekdays') |
|
243 |
optparser.add_option('--inverted', action='store_true', |
|
244 |
help='Generate an inverted burndown chart', dest='inverted') |
|
210
by Jamie Bennett
Add support for specifying a start and end date for creating burndown charts |
245 |
optparser.add_option('-s', '--start-date', |
246 |
help='Explicitly set the start date of the burndown data', dest='start_date') |
|
247 |
optparser.add_option('-e', '--end-date', |
|
248 |
help='Explicitly set the end date of the burndown data', dest='end_date') |
|
205.1.17
by Clint Byrum
- changing link for users to their wi tracker page on team pages |
249 |
optparser.add_option('--no-foreign', action='store_true', default=False, |
250 |
help='Do not show foreign totals separate', dest='noforeign') |
|
249.2.34
by James Westby
Add TR burndowns. |
251 |
optparser.add_option('--group', |
252 |
help='Run for this group', dest='group') |
|
240.11.2
by James Westby
Add a set of pages for date-based milestone views. |
253 |
optparser.add_option('--date', |
254 |
help='Run for this date', dest='date') |
|
57
by Martin Pitt
burndown-chart: directly read from DB, simplify |
255 |
|
256 |
(opts, args) = optparser.parse_args() |
|
257 |
if not opts.database: |
|
258 |
optparser.error('No database given') |
|
259 |
if not opts.output: |
|
260 |
optparser.error('No output file given') |
|
261 |
||
205.1.8
by Clint Byrum
only show user direct assigned items on personal page |
262 |
if opts.user and opts.team: |
263 |
optparser.error('team and user options are mutually exclusive') |
|
249.2.34
by James Westby
Add TR burndowns. |
264 |
if opts.user and opts.group: |
265 |
optparser.error('user and group options are mutually exclusive') |
|
266 |
if opts.team and opts.group: |
|
267 |
optparser.error('team and group options are mutually exclusive') |
|
240.11.2
by James Westby
Add a set of pages for date-based milestone views. |
268 |
if opts.milestone and opts.date: |
269 |
optparser.error('milestone and date options are mutually exclusive') |
|
205.1.8
by Clint Byrum
only show user direct assigned items on personal page |
270 |
|
271 |
# The typing allows polymorphic behavior
|
|
272 |
if opts.user: |
|
273 |
opts.team = report_tools.user_string(opts.user) |
|
274 |
elif opts.team: |
|
275 |
opts.team = report_tools.team_string(opts.team) |
|
276 |
||
282.1.1
by Mattias Backman
Change all SQL queries to go through the Storm API instead of SQLite directly. |
277 |
store = report_tools.get_store(opts.database) |
240.11.4
by James Westby
Rework to use polymorpism for milestone due dates. |
278 |
|
240.11.6
by James Westby
Comments from review. Thanks Michael. |
279 |
milestone_collection = None |
240.11.4
by James Westby
Rework to use polymorpism for milestone due dates. |
280 |
if opts.milestone: |
282.1.1
by Mattias Backman
Change all SQL queries to go through the Storm API instead of SQLite directly. |
281 |
milestone_collection = report_tools.get_milestone(store, opts.milestone) |
240.11.4
by James Westby
Rework to use polymorpism for milestone due dates. |
282 |
elif opts.date: |
240.11.7
by James Westby
Ensure to create MilesstoneGroups with python dates. |
283 |
milestone_collection = report_tools.MilestoneGroup( |
284 |
report_tools.date_to_python(opts.date)) |
|
240.11.4
by James Westby
Rework to use polymorpism for milestone due dates. |
285 |
|
286 |
||
57
by Martin Pitt
burndown-chart: directly read from DB, simplify |
287 |
# get date -> state -> count mapping
|
282.1.1
by Mattias Backman
Change all SQL queries to go through the Storm API instead of SQLite directly. |
288 |
data = report_tools.workitems_over_time(store, team=opts.team, group=opts.group, milestone_collection=milestone_collection) |
57
by Martin Pitt
burndown-chart: directly read from DB, simplify |
289 |
|
61
by Martin Pitt
burndown-chart: cleanly handle 0 work items |
290 |
if len(data) == 0: |
240.11.4
by James Westby
Rework to use polymorpism for milestone due dates. |
291 |
print 'WARNING: no work items, not generating chart (team: %s, group: %s, due date: %s)' % ( |
240.11.6
by James Westby
Comments from review. Thanks Michael. |
292 |
opts.team or 'all', opts.group or 'none', milestone_collection and milestone_collection.display_name or 'none') |
61
by Martin Pitt
burndown-chart: cleanly handle 0 work items |
293 |
sys.exit(0) |
294 |
||
210
by Jamie Bennett
Add support for specifying a start and end date for creating burndown charts |
295 |
# calculate start/end date if no dates are given
|
296 |
if opts.start_date is None: |
|
297 |
start_date = sorted(data.keys())[0] |
|
298 |
else: |
|
299 |
start_date=opts.start_date |
|
300 |
||
301 |
if opts.end_date is None: |
|
240.11.6
by James Westby
Comments from review. Thanks Michael. |
302 |
if milestone_collection is not None: |
240.11.8
by James Westby
Use the string version of the due_date. |
303 |
end_date = milestone_collection.due_date_str |
240.11.2
by James Westby
Add a set of pages for date-based milestone views. |
304 |
else: |
282.1.1
by Mattias Backman
Change all SQL queries to go through the Storm API instead of SQLite directly. |
305 |
end_date=report_tools.milestone_due_date(store) |
210
by Jamie Bennett
Add support for specifying a start and end date for creating burndown charts |
306 |
else: |
307 |
end_date=opts.end_date |
|
57
by Martin Pitt
burndown-chart: directly read from DB, simplify |
308 |
|
203
by Martin Pitt
burndown-chart: fix crash on empty date ranges |
309 |
if not start_date or not end_date or date_to_ordinal(start_date) > date_to_ordinal(end_date): |
240.11.4
by James Westby
Rework to use polymorpism for milestone due dates. |
310 |
print 'WARNING: empty date range, not generating chart (team: %s, group: %s, due date: %s)' % ( |
240.1.92
by James Westby
Fix mis-merge. |
311 |
opts.team or 'all', opts.group or 'none', milestone_collection and milestone_collection.display_name or 'none') |
74
by Martin Pitt
burndown-chart: Fix crash on empty date range |
312 |
sys.exit(0) |
313 |
||
57
by Martin Pitt
burndown-chart: directly read from DB, simplify |
314 |
# title
|
315 |
if opts.team: |
|
316 |
title = '/20' + opts.team |
|
205.1.17
by Clint Byrum
- changing link for users to their wi tracker page on team pages |
317 |
noforeign = opts.noforeign |
249.2.34
by James Westby
Add TR burndowns. |
318 |
elif opts.group: |
319 |
title = "/20" + opts.group |
|
320 |
noforeign = True |
|
57
by Martin Pitt
burndown-chart: directly read from DB, simplify |
321 |
else: |
322 |
title = '/20all teams' |
|
205.1.17
by Clint Byrum
- changing link for users to their wi tracker page on team pages |
323 |
# It never makese sense in all teams mode
|
324 |
noforeign = True |
|
325 |
||
240.11.6
by James Westby
Comments from review. Thanks Michael. |
326 |
if milestone_collection is not None: |
327 |
title += ' (%s)' % milestone_collection.name |
|
57
by Martin Pitt
burndown-chart: directly read from DB, simplify |
328 |
|
205.1.17
by Clint Byrum
- changing link for users to their wi tracker page on team pages |
329 |
do_chart(data, start_date, end_date, opts.trendstart, title, opts.output, opts.only_weekdays, opts.inverted, noforeign) |