mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-07-07 20:06:36 +02:00
Code Cleanup
- Modified burndown code to conform to coding convention, and be more readable while researching TW-306.
This commit is contained in:
parent
cbb32b4747
commit
ac45f263d8
1 changed files with 203 additions and 203 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue