Code Cleanup

- Modified burndown code to conform to coding convention, and be more
  readable while researching TW-306.
This commit is contained in:
Paul Beckingham 2014-04-13 10:26:43 -04:00
parent cbb32b4747
commit ac45f263d8

View file

@ -41,7 +41,7 @@
extern Context context; extern Context context;
// Helper macro. // Helper macro.
#define LOC(y,x) (((y) * (width + 1)) + (x)) #define LOC(y,x) (((y) * (_width + 1)) + (x))
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
class Bar class Bar
@ -53,26 +53,26 @@ public:
~Bar (); ~Bar ();
public: public:
int offset; // from left of chart int _offset; // from left of chart
std::string major_label; // x-axis label, major (year/-/month) std::string _major_label; // x-axis label, major (year/-/month)
std::string minor_label; // x-axis label, minor (month/week/day) std::string _minor_label; // x-axis label, minor (month/week/day)
int pending; // Number of pending tasks in period int _pending; // Number of pending tasks in period
int started; // Number of started tasks in period int _started; // Number of started tasks in period
int done; // Number of done tasks in period int _done; // Number of done tasks in period
int added; // Number added in period int _added; // Number added in period
int removed; // Number removed in period int _removed; // Number removed in period
}; };
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
Bar::Bar () Bar::Bar ()
: offset (0) : _offset (0)
, major_label ("") , _major_label ("")
, minor_label ("") , _minor_label ("")
, pending (0) , _pending (0)
, started (0) , _started (0)
, done (0) , _done (0)
, added (0) , _added (0)
, removed (0) , _removed (0)
{ {
} }
@ -87,14 +87,14 @@ Bar& Bar::operator= (const Bar& other)
{ {
if (this != &other) if (this != &other)
{ {
offset = other.offset; _offset = other._offset;
major_label = other.major_label; _major_label = other._major_label;
minor_label = other.minor_label; _minor_label = other._minor_label;
pending = other.pending; _pending = other._pending;
started = other.started; _started = other._started;
done = other.done; _done = other._done;
added = other.added; _added = other._added;
removed = other.removed; _removed = other._removed;
} }
return *this; return *this;
@ -159,25 +159,25 @@ private:
void calculateRates (std::vector <time_t>&); void calculateRates (std::vector <time_t>&);
public: public:
int width; // Terminal width int _width; // Terminal width
int height; // Terminal height int _height; // Terminal height
int graph_width; // Width of plot area int _graph_width; // Width of plot area
int graph_height; // Height of plot area int _graph_height; // Height of plot area
int max_value; // Largest combined bar value int _max_value; // Largest combined bar value
int max_label; // Longest y-axis label int _max_label; // Longest y-axis label
std::vector <int> labels; // Y-axis labels std::vector <int> _labels; // Y-axis labels
int estimated_bars; // Estimated bar count int _estimated_bars; // Estimated bar count
int actual_bars; // Calculated bar count int _actual_bars; // Calculated bar count
std::map <time_t, Bar> bars; // Epoch-indexed set of bars std::map <time_t, Bar> _bars; // Epoch-indexed set of bars
Date earliest; // Date of earliest estimated bar Date _earliest; // Date of earliest estimated bar
int carryover_done; // Number of 'done' tasks prior to chart range int _carryover_done; // Number of 'done' tasks prior to chart range
char period; // D, W, M char _period; // D, W, M
std::string title; // Additional description std::string _title; // Additional description
std::string grid; // String representing grid of characters std::string _grid; // String representing grid of characters
float find_rate; // Calculated find rate float _find_rate; // Calculated find rate
float fix_rate; // Calculated fix rate float _fix_rate; // Calculated fix rate
std::string completion; // Estimated completion date std::string _completion; // Estimated completion date
}; };
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -185,27 +185,27 @@ Chart::Chart (char type)
{ {
// How much space is there to render in? This chart will occupy the // How much space is there to render in? This chart will occupy the
// maximum space, and the width drives various other parameters. // maximum space, and the width drives various other parameters.
width = context.getWidth (); _width = context.getWidth ();
height = context.getHeight () - 1; // Allow for new line with prompt. _height = context.getHeight () - 1; // Allow for new line with prompt.
max_value = 0; _max_value = 0;
max_label = 1; _max_label = 1;
graph_height = height - 7; _graph_height = _height - 7;
graph_width = width - max_label - 14; _graph_width = _width - _max_label - 14;
// Estimate how many 'bars' can be dsplayed. This will help subset a // Estimate how many 'bars' can be dsplayed. This will help subset a
// potentially enormous data set. // potentially enormous data set.
estimated_bars = (width - 1 - 14) / 3; _estimated_bars = (_width - 1 - 14) / 3;
actual_bars = 0; _actual_bars = 0;
period = type; _period = type;
carryover_done = 0; _carryover_done = 0;
// Rates are calculated last. // Rates are calculated last.
find_rate = 0.0; _find_rate = 0.0;
fix_rate = 0.0; _fix_rate = 0.0;
// Set the title. // Set the title.
title = "("; _title = "(";
std::vector <Arg>::const_iterator arg; std::vector <Arg>::const_iterator arg;
for (arg = context.a3.begin (); arg != context.a3.end (); ++arg) for (arg = context.a3.begin (); arg != context.a3.end (); ++arg)
{ {
@ -217,13 +217,13 @@ Chart::Chart (char type)
; ;
else else
{ {
if (title.length () > 1) if (_title.length () > 1)
title += " "; _title += " ";
title += arg->_raw; _title += arg->_raw;
} }
} }
title += ")"; _title += ")";
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -247,8 +247,8 @@ void Chart::scan (std::vector <Task>& tasks)
Date from = quantize (Date (task->get_date ("entry"))); Date from = quantize (Date (task->get_date ("entry")));
epoch = from.toEpoch (); epoch = from.toEpoch ();
if (bars.find (epoch) != bars.end ()) if (_bars.find (epoch) != _bars.end ())
++bars[epoch].added; ++_bars[epoch]._added;
// e--> e--s--> // e--> e--s-->
// ppp> pppsss> // ppp> pppsss>
@ -262,14 +262,14 @@ void Chart::scan (std::vector <Task>& tasks)
while (from < start) while (from < start)
{ {
epoch = from.toEpoch (); epoch = from.toEpoch ();
if (bars.find (epoch) != bars.end ()) ++bars[epoch].pending; if (_bars.find (epoch) != _bars.end ()) ++_bars[epoch]._pending;
from = increment (from); from = increment (from);
} }
while (from < now) while (from < now)
{ {
epoch = from.toEpoch (); epoch = from.toEpoch ();
if (bars.find (epoch) != bars.end ()) ++bars[epoch].started; if (_bars.find (epoch) != _bars.end ()) ++_bars[epoch]._started;
from = increment (from); from = increment (from);
} }
} }
@ -278,7 +278,7 @@ void Chart::scan (std::vector <Task>& tasks)
while (from < now) while (from < now)
{ {
epoch = from.toEpoch (); epoch = from.toEpoch ();
if (bars.find (epoch) != bars.end ()) ++bars[epoch].pending; if (_bars.find (epoch) != _bars.end ()) ++_bars[epoch]._pending;
from = increment (from); from = increment (from);
} }
} }
@ -292,14 +292,14 @@ void Chart::scan (std::vector <Task>& tasks)
Date end = quantize (Date (task->get_date ("end"))); Date end = quantize (Date (task->get_date ("end")));
epoch = end.toEpoch (); epoch = end.toEpoch ();
if (bars.find (epoch) != bars.end ()) if (_bars.find (epoch) != _bars.end ())
++bars[epoch].removed; ++_bars[epoch]._removed;
// Maintain a running total of 'done' tasks that are off the left of the // Maintain a running total of 'done' tasks that are off the left of the
// chart. // chart.
if (end < earliest) if (end < _earliest)
{ {
++carryover_done; ++_carryover_done;
continue; continue;
} }
@ -309,21 +309,21 @@ void Chart::scan (std::vector <Task>& tasks)
while (from < start) while (from < start)
{ {
epoch = from.toEpoch (); epoch = from.toEpoch ();
if (bars.find (epoch) != bars.end ()) ++bars[epoch].pending; if (_bars.find (epoch) != _bars.end ()) ++_bars[epoch]._pending;
from = increment (from); from = increment (from);
} }
while (from < end) while (from < end)
{ {
epoch = from.toEpoch (); epoch = from.toEpoch ();
if (bars.find (epoch) != bars.end ()) ++bars[epoch].started; if (_bars.find (epoch) != _bars.end ()) ++_bars[epoch]._started;
from = increment (from); from = increment (from);
} }
while (from < now) while (from < now)
{ {
epoch = from.toEpoch (); epoch = from.toEpoch ();
if (bars.find (epoch) != bars.end ()) ++bars[epoch].done; if (_bars.find (epoch) != _bars.end ()) ++_bars[epoch]._done;
from = increment (from); from = increment (from);
} }
} }
@ -333,14 +333,14 @@ void Chart::scan (std::vector <Task>& tasks)
while (from < end) while (from < end)
{ {
epoch = from.toEpoch (); epoch = from.toEpoch ();
if (bars.find (epoch) != bars.end ()) ++bars[epoch].pending; if (_bars.find (epoch) != _bars.end ()) ++_bars[epoch]._pending;
from = increment (from); from = increment (from);
} }
while (from < now) while (from < now)
{ {
epoch = from.toEpoch (); epoch = from.toEpoch ();
if (bars.find (epoch) != bars.end ()) ++bars[epoch].done; if (_bars.find (epoch) != _bars.end ()) ++_bars[epoch]._done;
from = increment (from); from = increment (from);
} }
} }
@ -353,10 +353,10 @@ void Chart::scan (std::vector <Task>& tasks)
// Skip old deleted tasks. // Skip old deleted tasks.
Date end = quantize (Date (task->get_date ("end"))); Date end = quantize (Date (task->get_date ("end")));
epoch = end.toEpoch (); epoch = end.toEpoch ();
if (bars.find (epoch) != bars.end ()) if (_bars.find (epoch) != _bars.end ())
++bars[epoch].removed; ++_bars[epoch]._removed;
if (end < earliest) if (end < _earliest)
continue; continue;
if (task->has ("start")) if (task->has ("start"))
@ -365,14 +365,14 @@ void Chart::scan (std::vector <Task>& tasks)
while (from < start) while (from < start)
{ {
epoch = from.toEpoch (); epoch = from.toEpoch ();
if (bars.find (epoch) != bars.end ()) ++bars[epoch].pending; if (_bars.find (epoch) != _bars.end ()) ++_bars[epoch]._pending;
from = increment (from); from = increment (from);
} }
while (from < end) while (from < end)
{ {
epoch = from.toEpoch (); epoch = from.toEpoch ();
if (bars.find (epoch) != bars.end ()) ++bars[epoch].started; if (_bars.find (epoch) != _bars.end ()) ++_bars[epoch]._started;
from = increment (from); from = increment (from);
} }
} }
@ -382,7 +382,7 @@ void Chart::scan (std::vector <Task>& tasks)
while (from < end) while (from < end)
{ {
epoch = from.toEpoch (); epoch = from.toEpoch ();
if (bars.find (epoch) != bars.end ()) ++bars[epoch].pending; if (_bars.find (epoch) != _bars.end ()) ++_bars[epoch]._pending;
from = increment (from); from = increment (from);
} }
} }
@ -414,23 +414,23 @@ void Chart::scan (std::vector <Task>& tasks)
// +---------------------------------------------------------------------+ // +---------------------------------------------------------------------+
std::string Chart::render () std::string Chart::render ()
{ {
if (graph_height < 5 || // a 4-line graph is essentially unreadable. if (_graph_height < 5 || // a 4-line graph is essentially unreadable.
graph_width < 2) // A single-bar graph is useless. _graph_width < 2) // A single-bar graph is useless.
{ {
return std::string (STRING_CMD_BURN_TOO_SMALL) + "\n"; return std::string (STRING_CMD_BURN_TOO_SMALL) + "\n";
} }
if (max_value == 0) if (_max_value == 0)
context.footnote (STRING_FEEDBACK_NO_MATCH); context.footnote (STRING_FEEDBACK_NO_MATCH);
// Create a grid, folded into a string. // Create a grid, folded into a string.
grid = ""; _grid = "";
for (int i = 0; i < height; ++i) for (int i = 0; i < _height; ++i)
grid += std::string (width, ' ') + "\n"; _grid += std::string (_width, ' ') + "\n";
// Title. // Title.
std::string full_title; std::string full_title;
switch (period) switch (_period)
{ {
case 'D': full_title = STRING_CMD_BURN_DAILY; break; case 'D': full_title = STRING_CMD_BURN_DAILY; break;
case 'W': full_title = STRING_CMD_BURN_WEEKLY; break; case 'W': full_title = STRING_CMD_BURN_WEEKLY; break;
@ -439,118 +439,118 @@ std::string Chart::render ()
full_title += std::string (" ") + STRING_CMD_BURN_TITLE; full_title += std::string (" ") + STRING_CMD_BURN_TITLE;
if (title.length ()) if (_title.length ())
{ {
if (full_title.length () + 1 + title.length () < (unsigned) width) if (full_title.length () + 1 + _title.length () < (unsigned) _width)
{ {
full_title += " " + title; full_title += " " + _title;
grid.replace (LOC (0, (width - full_title.length ()) / 2), full_title.length (), full_title); _grid.replace (LOC (0, (_width - full_title.length ()) / 2), full_title.length (), full_title);
} }
else else
{ {
grid.replace (LOC (0, (width - full_title.length ()) / 2), full_title.length (), full_title); _grid.replace (LOC (0, (_width - full_title.length ()) / 2), full_title.length (), full_title);
grid.replace (LOC (1, (width - title.length ()) / 2), title.length (), title); _grid.replace (LOC (1, (_width - _title.length ()) / 2), _title.length (), _title);
} }
} }
else else
{ {
grid.replace (LOC (0, (width - full_title.length ()) / 2), full_title.length (), full_title); _grid.replace (LOC (0, (_width - full_title.length ()) / 2), full_title.length (), full_title);
} }
// Legend. // Legend.
grid.replace (LOC (graph_height / 2 - 1, width - 10), 10, "DD " + leftJustify (STRING_CMD_BURN_DONE, 7)); _grid.replace (LOC (_graph_height / 2 - 1, _width - 10), 10, "DD " + leftJustify (STRING_CMD_BURN_DONE, 7));
grid.replace (LOC (graph_height / 2, width - 10), 10, "SS " + leftJustify (STRING_CMD_BURN_STARTED, 7)); _grid.replace (LOC (_graph_height / 2, _width - 10), 10, "SS " + leftJustify (STRING_CMD_BURN_STARTED, 7));
grid.replace (LOC (graph_height / 2 + 1, width - 10), 10, "PP " + leftJustify (STRING_CMD_BURN_PENDING, 7)); _grid.replace (LOC (_graph_height / 2 + 1, _width - 10), 10, "PP " + leftJustify (STRING_CMD_BURN_PENDING, 7));
// Determine y-axis labelling. // Determine y-axis labelling.
std::vector <int> labels; std::vector <int> _labels;
yLabels (labels); yLabels (_labels);
max_label = (int) log10 ((double) labels[2]) + 1; _max_label = (int) log10 ((double) _labels[2]) + 1;
// Draw y-axis. // Draw y-axis.
for (int i = 0; i < graph_height; ++i) for (int i = 0; i < _graph_height; ++i)
grid.replace (LOC (i + 1, max_label + 1), 1, "|"); _grid.replace (LOC (i + 1, _max_label + 1), 1, "|");
// Draw y-axis labels. // Draw y-axis labels.
char label [12]; char label [12];
sprintf (label, "%*d", max_label, labels[2]); sprintf (label, "%*d", _max_label, _labels[2]);
grid.replace (LOC (1, max_label - strlen (label)), strlen (label), label); _grid.replace (LOC (1, _max_label - strlen (label)), strlen (label), label);
sprintf (label, "%*d", max_label, labels[1]); sprintf (label, "%*d", _max_label, _labels[1]);
grid.replace (LOC (1 + (graph_height / 2), max_label - strlen (label)), strlen (label), label); _grid.replace (LOC (1 + (_graph_height / 2), _max_label - strlen (label)), strlen (label), label);
grid.replace (LOC (graph_height + 1, max_label - 1), 1, "0"); _grid.replace (LOC (_graph_height + 1, _max_label - 1), 1, "0");
// Draw x-axis. // Draw x-axis.
grid.replace (LOC (height - 6, max_label + 1), 1, "+"); _grid.replace (LOC (_height - 6, _max_label + 1), 1, "+");
grid.replace (LOC (height - 6, max_label + 2), graph_width, std::string (graph_width, '-')); _grid.replace (LOC (_height - 6, _max_label + 2), _graph_width, std::string (_graph_width, '-'));
// Draw x-axis labels. // Draw x-axis labels.
std::vector <time_t> bars_in_sequence; std::vector <time_t> bars_in_sequence;
std::map <time_t, Bar>::iterator it; std::map <time_t, Bar>::iterator it;
for (it = bars.begin (); it != bars.end (); ++it) for (it = _bars.begin (); it != _bars.end (); ++it)
bars_in_sequence.push_back (it->first); bars_in_sequence.push_back (it->first);
std::sort (bars_in_sequence.begin (), bars_in_sequence.end ()); std::sort (bars_in_sequence.begin (), bars_in_sequence.end ());
std::vector <time_t>::iterator seq; std::vector <time_t>::iterator seq;
std::string major_label; std::string _major_label;
for (seq = bars_in_sequence.begin (); seq != bars_in_sequence.end (); ++seq) for (seq = bars_in_sequence.begin (); seq != bars_in_sequence.end (); ++seq)
{ {
Bar bar = bars[*seq]; Bar bar = _bars[*seq];
// If it fits within the allowed space. // If it fits within the allowed space.
if (bar.offset < actual_bars) if (bar._offset < _actual_bars)
{ {
grid.replace (LOC (height - 5, max_label + 3 + ((actual_bars - bar.offset - 1) * 3)), bar.minor_label.length (), bar.minor_label); _grid.replace (LOC (_height - 5, _max_label + 3 + ((_actual_bars - bar._offset - 1) * 3)), bar._minor_label.length (), bar._minor_label);
if (major_label != bar.major_label) if (_major_label != bar._major_label)
grid.replace (LOC (height - 4, max_label + 2 + ((actual_bars - bar.offset - 1) * 3)), bar.major_label.length (), " " + bar.major_label); _grid.replace (LOC (_height - 4, _max_label + 2 + ((_actual_bars - bar._offset - 1) * 3)), bar._major_label.length (), " " + bar._major_label);
major_label = bar.major_label; _major_label = bar._major_label;
} }
} }
// Draw bars. // Draw bars.
for (seq = bars_in_sequence.begin (); seq != bars_in_sequence.end (); ++seq) for (seq = bars_in_sequence.begin (); seq != bars_in_sequence.end (); ++seq)
{ {
Bar bar = bars[*seq]; Bar bar = _bars[*seq];
// If it fits within the allowed space. // If it fits within the allowed space.
if (bar.offset < actual_bars) if (bar._offset < _actual_bars)
{ {
int pending = ( bar.pending * graph_height) / labels[2]; int pending = ( bar._pending * _graph_height) / _labels[2];
int started = ((bar.pending + bar.started) * graph_height) / labels[2]; int started = ((bar._pending + bar._started) * _graph_height) / _labels[2];
int done = ((bar.pending + bar.started + bar.done + carryover_done) * graph_height) / labels[2]; int done = ((bar._pending + bar._started + bar._done + _carryover_done) * _graph_height) / _labels[2];
for (int b = 0; b < pending; ++b) for (int b = 0; b < pending; ++b)
grid.replace (LOC (graph_height - b, max_label + 3 + ((actual_bars - bar.offset - 1) * 3)), 2, "PP"); _grid.replace (LOC (_graph_height - b, _max_label + 3 + ((_actual_bars - bar._offset - 1) * 3)), 2, "PP");
for (int b = pending; b < started; ++b) for (int b = pending; b < started; ++b)
grid.replace (LOC (graph_height - b, max_label + 3 + ((actual_bars - bar.offset - 1) * 3)), 2, "SS"); _grid.replace (LOC (_graph_height - b, _max_label + 3 + ((_actual_bars - bar._offset - 1) * 3)), 2, "SS");
for (int b = started; b < done; ++b) for (int b = started; b < done; ++b)
grid.replace (LOC (graph_height - b, max_label + 3 + ((actual_bars - bar.offset - 1) * 3)), 2, "DD"); _grid.replace (LOC (_graph_height - b, _max_label + 3 + ((_actual_bars - bar._offset - 1) * 3)), 2, "DD");
} }
} }
// Draw rates. // Draw rates.
calculateRates (bars_in_sequence); calculateRates (bars_in_sequence);
char rate[12]; char rate[12];
if (find_rate != 0.0) if (_find_rate != 0.0)
sprintf (rate, "%.1f/d", find_rate); sprintf (rate, "%.1f/d", _find_rate);
else else
strcpy (rate, "-"); strcpy (rate, "-");
grid.replace (LOC (height - 2, max_label + 3), 18 + strlen (rate), std::string ("Add rate: ") + rate); _grid.replace (LOC (_height - 2, _max_label + 3), 18 + strlen (rate), std::string ("Add rate: ") + rate);
if (fix_rate != 0.0) if (_fix_rate != 0.0)
sprintf (rate, "%.1f/d", fix_rate); sprintf (rate, "%.1f/d", _fix_rate);
else else
strcpy (rate, "-"); strcpy (rate, "-");
grid.replace (LOC (height - 1, max_label + 3), 18 + strlen (rate), std::string ("Done/Delete rate: ") + rate); _grid.replace (LOC (_height - 1, _max_label + 3), 18 + strlen (rate), std::string ("Done/Delete rate: ") + rate);
// Draw completion date. // Draw completion date.
if (completion.length ()) if (_completion.length ())
grid.replace (LOC (height - 2, max_label + 32), 22 + completion.length (), "Estimated completion: " + completion); _grid.replace (LOC (_height - 2, _max_label + 32), 22 + _completion.length (), "Estimated completion: " + _completion);
optimizeGrid (); optimizeGrid ();
@ -563,53 +563,53 @@ std::string Chart::render ()
// Replace DD, SS, PP with colored strings. // Replace DD, SS, PP with colored strings.
std::string::size_type i; std::string::size_type i;
while ((i = grid.find ("PP")) != std::string::npos) while ((i = _grid.find ("PP")) != std::string::npos)
grid.replace (i, 2, color_pending.colorize (" ")); _grid.replace (i, 2, color_pending.colorize (" "));
while ((i = grid.find ("SS")) != std::string::npos) while ((i = _grid.find ("SS")) != std::string::npos)
grid.replace (i, 2, color_started.colorize (" ")); _grid.replace (i, 2, color_started.colorize (" "));
while ((i = grid.find ("DD")) != std::string::npos) while ((i = _grid.find ("DD")) != std::string::npos)
grid.replace (i, 2, color_done.colorize (" ")); _grid.replace (i, 2, color_done.colorize (" "));
} }
else else
{ {
// Replace DD, SS, PP with ./+/X strings. // Replace DD, SS, PP with ./+/X strings.
std::string::size_type i; std::string::size_type i;
while ((i = grid.find ("PP")) != std::string::npos) while ((i = _grid.find ("PP")) != std::string::npos)
grid.replace (i, 2, " X"); _grid.replace (i, 2, " X");
while ((i = grid.find ("SS")) != std::string::npos) while ((i = _grid.find ("SS")) != std::string::npos)
grid.replace (i, 2, " +"); _grid.replace (i, 2, " +");
while ((i = grid.find ("DD")) != std::string::npos) while ((i = _grid.find ("DD")) != std::string::npos)
grid.replace (i, 2, " ."); _grid.replace (i, 2, " .");
} }
return grid; return _grid;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// grid =~ /\s+$//g // _grid =~ /\s+$//g
void Chart::optimizeGrid () void Chart::optimizeGrid ()
{ {
std::string::size_type ws; std::string::size_type ws;
while ((ws = grid.find (" \n")) != std::string::npos) while ((ws = _grid.find (" \n")) != std::string::npos)
{ {
std::string::size_type non_ws = ws; std::string::size_type non_ws = ws;
while (grid[non_ws] == ' ') while (_grid[non_ws] == ' ')
--non_ws; --non_ws;
grid.replace (non_ws + 1, ws - non_ws + 1, "\n"); _grid.replace (non_ws + 1, ws - non_ws + 1, "\n");
} }
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
Date Chart::quantize (const Date& input) Date Chart::quantize (const Date& input)
{ {
if (period == 'D') return input.startOfDay (); if (_period == 'D') return input.startOfDay ();
if (period == 'W') return input.startOfWeek (); if (_period == 'W') return input.startOfWeek ();
if (period == 'M') return input.startOfMonth (); if (_period == 'M') return input.startOfMonth ();
return input; return input;
} }
@ -624,7 +624,7 @@ Date Chart::increment (const Date& input)
int days; int days;
switch (period) switch (_period)
{ {
case 'D': case 'D':
if (++d > Date::daysInMonth (m, y)) if (++d > Date::daysInMonth (m, y))
@ -675,7 +675,7 @@ Date Chart::decrement (const Date& input)
int m = input.month (); int m = input.month ();
int y = input.year (); int y = input.year ();
switch (period) switch (_period)
{ {
case 'D': case 'D':
if (--d == 0) if (--d == 0)
@ -718,14 +718,14 @@ Date Chart::decrement (const Date& input)
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Do 'bars[epoch] = Bar' for every bar that may appear on a chart. // Do '_bars[epoch] = Bar' for every bar that may appear on a chart.
void Chart::generateBars () void Chart::generateBars ()
{ {
Bar bar; Bar bar;
// Determine the last bar date. // Determine the last bar date.
Date cursor; Date cursor;
switch (period) switch (_period)
{ {
case 'D': cursor = Date ().startOfDay (); break; case 'D': cursor = Date ().startOfDay (); break;
case 'W': cursor = Date ().startOfWeek (); break; case 'W': cursor = Date ().startOfWeek (); break;
@ -734,43 +734,43 @@ void Chart::generateBars ()
// Iterate and determine all the other bar dates. // Iterate and determine all the other bar dates.
char str[12]; char str[12];
for (int i = 0; i < estimated_bars; ++i) for (int i = 0; i < _estimated_bars; ++i)
{ {
// Create the major and minor labels. // Create the major and minor labels.
switch (period) switch (_period)
{ {
case 'D': // month/day case 'D': // month/day
{ {
std::string month = Date::monthName (cursor.month ()); std::string month = Date::monthName (cursor.month ());
bar.major_label = month.substr (0, 3); bar._major_label = month.substr (0, 3);
sprintf (str, "%02d", cursor.day ()); sprintf (str, "%02d", cursor.day ());
bar.minor_label = str; bar._minor_label = str;
} }
break; break;
case 'W': // year/week case 'W': // year/week
sprintf (str, "%d", cursor.year ()); sprintf (str, "%d", cursor.year ());
bar.major_label = str; bar._major_label = str;
sprintf (str, "%02d", cursor.weekOfYear (0)); sprintf (str, "%02d", cursor.weekOfYear (0));
bar.minor_label = str; bar._minor_label = str;
break; break;
case 'M': // year/month case 'M': // year/month
sprintf (str, "%d", cursor.year ()); sprintf (str, "%d", cursor.year ());
bar.major_label = str; bar._major_label = str;
sprintf (str, "%02d", cursor.month ()); sprintf (str, "%02d", cursor.month ());
bar.minor_label = str; bar._minor_label = str;
break; break;
} }
bar.offset = i; bar._offset = i;
bars[cursor.toEpoch ()] = bar; _bars[cursor.toEpoch ()] = bar;
// Record the earliest date, for use as a cutoff when scanning data. // Record the earliest date, for use as a cutoff when scanning data.
earliest = cursor; _earliest = cursor;
// Move to the previous period. // Move to the previous period.
cursor = decrement (cursor); cursor = decrement (cursor);
@ -780,39 +780,39 @@ void Chart::generateBars ()
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void Chart::maxima () void Chart::maxima ()
{ {
max_value = 0; _max_value = 0;
max_label = 1; _max_label = 1;
std::map <time_t, Bar>::iterator it; std::map <time_t, Bar>::iterator it;
for (it = bars.begin (); it != bars.end (); it++) for (it = _bars.begin (); it != _bars.end (); it++)
{ {
// Determine max_label. // Determine _max_label.
int total = it->second.pending + int total = it->second._pending +
it->second.started + it->second._started +
it->second.done + it->second._done +
carryover_done; _carryover_done;
// Determine max_value. // Determine _max_value.
if (total > max_value) if (total > _max_value)
max_value = total; _max_value = total;
int length = (int) log10 ((double) total) + 1; int length = (int) log10 ((double) total) + 1;
if (length > max_label) if (length > _max_label)
max_label = length; _max_label = length;
} }
// How many bars can be shown? // How many bars can be shown?
actual_bars = (width - max_label - 14) / 3; _actual_bars = (_width - _max_label - 14) / 3;
graph_width = width - max_label - 14; _graph_width = _width - _max_label - 14;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Given the vertical chart area size (graph_height), the largest value // Given the vertical chart area size (graph_height), the largest value
// (max_value), populate a vector of labels for the y axis. // (_max_value), populate a vector of labels for the y axis.
void Chart::yLabels (std::vector <int>& labels) void Chart::yLabels (std::vector <int>& labels)
{ {
// Calculate may Y using a nice algorithm that rounds the data. // Calculate may Y using a nice algorithm that rounds the data.
int high = burndown_size (max_value); int high = burndown_size (_max_value);
int half = high / 2; int half = high / 2;
labels.push_back (0); labels.push_back (0);
@ -825,7 +825,7 @@ void Chart::calculateRates (std::vector <time_t>& sequence)
{ {
// If there are no current pending tasks, then it is meaningless to find // If there are no current pending tasks, then it is meaningless to find
// rates or estimated completion date. // rates or estimated completion date.
if (bars[sequence.back ()].pending == 0) if (_bars[sequence.back ()]._pending == 0)
return; return;
// Calculate how many items we have. // Calculate how many items we have.
@ -844,7 +844,7 @@ void Chart::calculateRates (std::vector <time_t>& sequence)
// How many days do these sums represent? // How many days do these sums represent?
int half_days = 1; int half_days = 1;
int quarter_days = 1; int quarter_days = 1;
switch (period) switch (_period)
{ {
case 'D': case 'D':
half_days = half; half_days = half;
@ -869,14 +869,14 @@ void Chart::calculateRates (std::vector <time_t>& sequence)
for (unsigned int i = half; i < sequence.size (); ++i) for (unsigned int i = half; i < sequence.size (); ++i)
{ {
total_added_50 += bars[sequence[i]].added; total_added_50 += _bars[sequence[i]]._added;
total_removed_50 += bars[sequence[i]].removed; total_removed_50 += _bars[sequence[i]]._removed;
} }
for (unsigned int i = half + quarter; i < sequence.size (); ++i) for (unsigned int i = half + quarter; i < sequence.size (); ++i)
{ {
total_added_75 += bars[sequence[i]].added; total_added_75 += _bars[sequence[i]]._added;
total_removed_75 += bars[sequence[i]].removed; total_removed_75 += _bars[sequence[i]]._removed;
} }
float find_rate_50 = 1.0 * total_added_50 / half_days; float find_rate_50 = 1.0 * total_added_50 / half_days;
@ -887,8 +887,8 @@ void Chart::calculateRates (std::vector <time_t>& sequence)
// Make configurable. // Make configurable.
float bias = (float) context.config.getReal ("burndown.bias"); float bias = (float) context.config.getReal ("burndown.bias");
find_rate = (find_rate_50 * (1.0 - bias) + find_rate_75 * bias); _find_rate = (find_rate_50 * (1.0 - bias) + find_rate_75 * bias);
fix_rate = (fix_rate_50 * (1.0 - bias) + fix_rate_75 * bias); _fix_rate = (fix_rate_50 * (1.0 - bias) + fix_rate_75 * bias);
// Q: Why is this equation written out as a debug message? // Q: Why is this equation written out as a debug message?
// A: People are going to want to know how the rates and the completion date // A: People are going to want to know how the rates and the completion date
@ -908,7 +908,7 @@ void Chart::calculateRates (std::vector <time_t>& sequence)
<< " days) * " << " days) * "
<< bias << bias
<< ") = " << ") = "
<< find_rate << _find_rate
<< "\nChart::calculateRates fix rate: " << "\nChart::calculateRates fix rate: "
<< "(" << "("
<< total_removed_50 << total_removed_50
@ -923,20 +923,20 @@ void Chart::calculateRates (std::vector <time_t>& sequence)
<< " days) * " << " days) * "
<< bias << bias
<< ") = " << ") = "
<< fix_rate; << _fix_rate;
context.debug (rates.str ()); context.debug (rates.str ());
// Estimate completion // Estimate completion
if (fix_rate > find_rate) if (_fix_rate > _find_rate)
{ {
int current_pending = bars[sequence.back ()].pending; int current_pending = _bars[sequence.back ()]._pending;
int remaining_days = (int) (current_pending / (fix_rate - find_rate)); int remaining_days = (int) (current_pending / (_fix_rate - _find_rate));
Date now; Date now;
OldDuration delta (remaining_days * 86400); OldDuration delta (remaining_days * 86400);
now += delta; now += delta;
completion = now.toString (context.config.get ("dateformat")) _completion = now.toString (context.config.get ("dateformat"))
+ " (" + " ("
+ delta.format () + delta.format ()
+ ")"; + ")";
@ -945,18 +945,18 @@ void Chart::calculateRates (std::vector <time_t>& sequence)
est << "Chart::calculateRates Completion: " est << "Chart::calculateRates Completion: "
<< current_pending << current_pending
<< " tasks / (" << " tasks / ("
<< fix_rate << _fix_rate
<< " - " << " - "
<< find_rate << _find_rate
<< ") = " << ") = "
<< remaining_days << remaining_days
<< " days = " << " days = "
<< completion; << _completion;
context.debug (est.str ()); context.debug (est.str ());
} }
else else
{ {
completion = STRING_CMD_BURN_NO_CONVERGE; _completion = STRING_CMD_BURN_NO_CONVERGE;
} }
} }