private double GetPredictedVelocity(HistoryKind historyKind, NormalizedBurndownHistory normalizedHistory, bool ignoreNonWorkingdays) { int nDays = Project.GetProject(MainProjectID).AverageVelocitySpan; if (cache.predictedVelocityCache != null && cache.predictedVelocityCache[(int)historyKind].ContainsKey(nDays)) { return(cache.predictedVelocityCache[(int)historyKind][nDays]); } double weightedValueSum = 0; double weightedDaysSum = 0; int iDay = nDays; DateTime day = DateTime.Now.Date; if (ignoreNonWorkingdays && !Project.IsWorkingDay(day)) { day = Project.GetPreviousWorkingDay(day); } DateTime previousDay = day.AddDays(-1); if (ignoreNonWorkingdays && !Project.IsWorkingDay(previousDay)) { previousDay = Project.GetPreviousWorkingDay(previousDay); } for (int i = 0; i < nDays; i += 1) { if (previousDay < normalizedHistory.Start) { break; } double velocityOneDay = normalizedHistory.ValueAt(previousDay.Date) - normalizedHistory.ValueAt(day.Date); weightedValueSum += velocityOneDay * iDay; weightedDaysSum += iDay; iDay -= 1; day = previousDay; previousDay = previousDay.AddDays(-1); if (ignoreNonWorkingdays && !Project.IsWorkingDay(previousDay)) { previousDay = Project.GetPreviousWorkingDay(day); } } double prediction = 0; if (weightedDaysSum > 0) { prediction = weightedValueSum / weightedDaysSum; } if (cache.predictedVelocityCache == null) { cache.predictedVelocityCache = new Dictionary <int, double> [3]; for (int i = 0; i < cache.predictedVelocityCache.Length - 1; i += 1) { cache.predictedVelocityCache[i] = new Dictionary <int, double>(); } } cache.predictedVelocityCache[(int)historyKind].Add(nDays, prediction); return(prediction); }
private Dictionary <DateTime, double> GetPredictedBurndown(double excessValue, double predictedVelocity) { Dictionary <DateTime, double> predictedBurndown = new Dictionary <DateTime, double>(); double excess = excessValue; DateTime day = DateTime.Now.Date.AddDays(1); while (day.Date <= Date.Date && excess > 0) { if (Project.IsWorkingDay(day)) { excess -= predictedVelocity; } predictedBurndown.Add(day.Date, excess); } return(predictedBurndown); }
private DateTime GetPredictedCompletion(double predictedExcess, double predictedVelocity) { double excess = predictedExcess; if (excess == 0) { return(Date); } if (predictedVelocity <= 0) { return(DateTime.MaxValue); } DateTime prediction = Date.Date; if (excess > 0) { while (excess > 0) { prediction = prediction.AddDays(1); if (Project.IsWorkingDay(prediction)) { excess -= predictedVelocity; } } return(prediction); } else if (excess < 0) { while (excess < 0 && Math.Abs(excess) > predictedVelocity) { prediction = prediction.AddDays(-1); if (Project.IsWorkingDay(prediction)) { excess += predictedVelocity; } } return(prediction); } return(prediction); }