Ejemplo n.º 1
0
void Chart::calculateRates (std::vector <time_t>& sequence)
{
  // If there are no current pending tasks, then it is meaningless to find
  // rates or estimated completion date.
  if (bars[sequence.back ()].pending == 0)
    return;

  // Calculate how many items we have.
  int quantity = (int) sequence.size ();
  int half     = quantity / 2;
  int quarter  = quantity / 4;

  // If the half and quarter indexes match, then there are too few data points
  // to generate any meaningful rates.
  if (half == quantity || half == 0 || quarter == 0)
  {
    context.debug ("Chart::calculateRates Insufficient data for rate calc");
    return;
  }

  // How many days do these sums represent?
  int half_days = 1;
  int quarter_days = 1;
  switch (period)
  {
  case 'D':
    half_days = half;
    quarter_days = quarter;
    break;

  case 'W':
    half_days = half * 7;
    quarter_days = quarter * 7;
    break;

  case 'M':
    half_days = half * 30;
    quarter_days = quarter * 30;
    break;
  }

  int total_added_50 = 0;
  int total_added_75 = 0;
  int total_removed_50 = 0;
  int total_removed_75 = 0;

  for (unsigned int i = half; i < sequence.size (); ++i)
  {
    total_added_50 += bars[sequence[i]].added;
    total_removed_50 += bars[sequence[i]].removed;
  }

  for (unsigned int i = half + quarter; i < sequence.size (); ++i)
  {
    total_added_75 += bars[sequence[i]].added;
    total_removed_75 += bars[sequence[i]].removed;
  }

  float find_rate_50 = 1.0 * total_added_50 / half_days;
  float find_rate_75 = 1.0 * total_added_75 / quarter_days;
  float fix_rate_50 = 1.0 * total_removed_50 / half_days;
  float fix_rate_75 = 1.0 * total_removed_75 / quarter_days;

  // Make configurable.
  float bias = (float) context.config.getReal ("burndown.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);

  // 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
  //    are calculated.  This may also help debugging.
  std::stringstream rates;
  rates << "Chart::calculateRates find rate: "
        << "("
        << total_added_50
        << " added / "
        << half_days
        << " days) * (1.0 - "
        << bias
        << ") + ("
        << total_added_75
        << " added / "
        << quarter_days
        << " days) * "
        << bias
        << ") = "
        << find_rate
        << "\nChart::calculateRates fix rate: "
        << "("
        << total_removed_50
        << " removed / "
        << half_days
        << " days) * (1.0 - "
        << bias
        << ") + ("
        << total_removed_75
        << " added / "
        << quarter_days
        << " days) * "
        << bias
        << ") = "
        << fix_rate;
  context.debug (rates.str ());

  // Estimate completion
  if (fix_rate > find_rate)
  {
    int current_pending = bars[sequence.back ()].pending;
    int remaining_days = (int) (current_pending / (fix_rate - find_rate));

    Date now;
    Duration delta (remaining_days * 86400);
    now += delta;

    completion = now.toString (context.config.get ("dateformat"))
               + " ("
               + delta.format ()
               + ")";

    std::stringstream est;
    est << "Chart::calculateRates Completion: "
         << current_pending
         << " tasks / ("
         << fix_rate
         << " - "
         << find_rate
         << ") = "
         << remaining_days
         << " days = "
         << completion;
    context.debug (est.str ());
  }
  else
  {
    completion = STRING_CMD_BURN_NO_CONVERGE;
  }
}