async void TurnGreen() { if (!await ShowLoseDataWarning()) { return; } try { IncrementPendingRequestCount(); await ClearData(); // set a goal where today is the goal end date var goalStartDate = DateTime.Today.Date - TimeSpan.FromDays(30); var goalEndDate = DateTime.Today.Date; var goal = new WeightLossGoal(goalStartDate, 240, goalEndDate, 210, WeightUnitEnum.ImperialPounds); await DataService.SetGoal(goal); await DataService.AddWeightEntry(new WeightEntry(DateTime.Today.Date, 210, WeightUnitEnum.ImperialPounds)); } finally { DecrementPendingRequestCount(); } Close(); }
public async Task Initialize(string path) { #if DEBUG await SimulateSlowNetworkIfEnabled(); #endif MockGoal = new WeightLossGoal( startDate: new DateTime(2016, 04, 30), startWeight: 225.0M, goalDate: new DateTime(2016, 06, 08), goalWeight: 215.0M, units: WeightUnitEnum.ImperialPounds); MockEntries = new List <WeightEntry>(); MockEntries.Add(new WeightEntry(new DateTime(2016, 4, 24), 234.4M, WeightUnitEnum.ImperialPounds)); MockEntries.Add(new WeightEntry(new DateTime(2016, 4, 25), 234.3M, WeightUnitEnum.ImperialPounds)); MockEntries.Add(new WeightEntry(new DateTime(2016, 4, 26), 234.2M, WeightUnitEnum.ImperialPounds)); MockEntries.Add(new WeightEntry(new DateTime(2016, 4, 27), 234.1M, WeightUnitEnum.ImperialPounds)); MockEntries.Add(new WeightEntry(new DateTime(2016, 4, 28), 234.0M, WeightUnitEnum.ImperialPounds)); MockEntries.Add(new WeightEntry(new DateTime(2016, 4, 29), 233.9M, WeightUnitEnum.ImperialPounds)); MockEntries.Add(new WeightEntry(new DateTime(2016, 4, 30), 233.8M, WeightUnitEnum.ImperialPounds)); MockEntries.Add(new WeightEntry(new DateTime(2016, 5, 1), 233.7M, WeightUnitEnum.ImperialPounds)); MockEntries.Add(new WeightEntry(new DateTime(2016, 5, 2), 233.6M, WeightUnitEnum.ImperialPounds)); MockEntries.Add(new WeightEntry(new DateTime(2016, 5, 3), 233.5M, WeightUnitEnum.ImperialPounds)); MockEntries.Add(new WeightEntry(new DateTime(2016, 5, 4), 233.4M, WeightUnitEnum.ImperialPounds)); MockEntries.Add(new WeightEntry(new DateTime(2016, 5, 5), 233.3M, WeightUnitEnum.ImperialPounds)); HasBeenInitialized = true; FireUserDataUpdated(); }
static decimal GetGoalWeightForDate(WeightLossGoal goal, DateTime date) { // make sure we have a goal set first if (goal == null) { throw new InvalidOperationException($"{nameof(GetGoalWeightForDate)} was passed in a null goal."); } // if the date requested is before the goal start, then return the goal start weight if (date.Date <= goal.StartDate.Date) { return(goal.StartWeight); } // if the date requested is after the goal end, then return the goal end weight if (date.Date >= goal.GoalDate.Date) { return(goal.GoalWeight); } // NOTE:: calculation is: ((y2 - y1) / diet length in days) * days elapsed + y1 // NOTE:: calculation is: start weight - ((start weight - end weight) / diet length in days) * days elapsed decimal weightDiff = goal.StartWeight - goal.GoalWeight; TimeSpan duration = goal.GoalDate.Date - goal.StartDate.Date; TimeSpan elapsed = date - goal.StartDate.Date; var goalWeightForDate = goal.StartWeight - ((weightDiff / (decimal)duration.TotalDays) * (decimal)elapsed.TotalDays); return(goalWeightForDate); }
async void TestLargeDataSet() { if (!await ShowLoseDataWarning()) { return; } try { IncrementPendingRequestCount(); await ClearData(); // set goal var goal = new WeightLossGoal(new DateTime(2017, 1, 1), 200, new DateTime(2017, 7, 1), 200, WeightUnitEnum.ImperialPounds); await DataService.SetGoal(goal); // add some weights DateTime date = new DateTime(2017, 3, 29); TimeSpan day = TimeSpan.FromDays(1); Random random = new Random(); for (int i = 0; i < 1000; i++) { date = date - day; var weightEntry = new WeightEntry(date, 200 + (decimal)(random.NextDouble() * 10) - 5, WeightUnitEnum.ImperialPounds); await DataService.AddWeightEntry(weightEntry); } } finally { DecrementPendingRequestCount(); } Close(); }
public static InfoForToday GetTodaysDisplayInfo(WeightLossGoal goal, WeightEntry todaysWeightEntry) { var infoForToday = new InfoForToday(); infoForToday.TodaysDisplayWeight = (todaysWeightEntry != null) ? todaysWeightEntry.ToString() : Constants.Strings.DailyInfoPage_UnknownWeight; if (goal == null) { infoForToday.IsEnterWeightButtonVisible = false; infoForToday.IsSetGoalButtonVisible = true; } else if (todaysWeightEntry == null) { infoForToday.IsEnterWeightButtonVisible = true; infoForToday.IsSetGoalButtonVisible = false; } infoForToday.TodaysMessage = GetTodaysMessageFromWeight(todaysWeightEntry, goal); // ok that either may be null // if they haven't set a goal, or don't have a weight today, or today is the first day of the diet, then we don't // want to colorize the screen or show the HowToEat information below their weight if (goal != null && todaysWeightEntry != null && goal.StartDate.Date != DateTime.Today.Date) { // update the window color if we have a weight for today and know their goal decimal goalWeightForToday = GetGoalWeightForDate(goal, DateTime.Today.Date); bool onADiet = todaysWeightEntry.Weight > goalWeightForToday; infoForToday.ColorToShow = onADiet ? BaseColorEnum.Red : BaseColorEnum.Green; infoForToday.HowToEatMessage = onADiet ? Constants.Strings.DailyInfoPage_HowToEat_OnDiet : Constants.Strings.DailyInfoPage_HowToEat_OffDiet; } return(infoForToday); }
public async Task <bool> SetGoal(WeightLossGoal weightLossGoal) { #if DEBUG await SimulateSlowNetworkIfEnabled(); #endif MockGoal = weightLossGoal; FireUserDataUpdated(); return(true); }
// NOTE:: either of the parameters could be null if they are not yet entered static string GetTodaysMessageFromWeight(WeightEntry todaysEntry, WeightLossGoal goal) { // if they haven't set a goal if (goal == null) { return(Constants.Strings.DailyInfoPage_TodaysMessage_NoGoal); } // if they started the goal today if (goal.StartDate.Date == DateTime.Today.Date) { return(Constants.Strings.DailyInfoPage_TodaysMessage_NewGoal); } // if they haven't entered today's weight yet if (todaysEntry == null) { return(Constants.Strings.DailyInfoPage_TodaysMessage_NoWeightToday); } decimal todaysGoalWeight = GetGoalWeightForDate(goal, DateTime.Today.Date); int daysToGo = (int)(Math.Floor((goal.GoalDate.Date - DateTime.Today.Date).TotalDays)); // they have reached their goal weight (could be before or after the goal date, we show same message either way) if (todaysEntry.Weight <= goal.GoalWeight) { return(Constants.Strings.DailyInfoPage_GoalEnd_Success); } // they've reached the goal date, show success/failure if (daysToGo <= 0) { return((todaysEntry.Weight <= todaysGoalWeight) ? Constants.Strings.DailyInfoPage_GoalEnd_Success : Constants.Strings.DailyInfoPage_GoalEnd_Failure); } // they are still working towards a goal, show a summary of their progress var amountLost = goal.StartWeight - todaysEntry.Weight; var amountRemaining = Math.Max(todaysEntry.Weight - goal.GoalWeight, 0); // prevent from going negative int daysSinceStart = (int)(Math.Floor((DateTime.Today.Date - goal.StartDate.Date).TotalDays)); // ex: You have [lost/gained] [XX.X] [pounds/kilograms] since starting on your current goal [XX] days ago. You have [XX] days left to lose a remaining [XX.X] pounds. [You can do it!/Keep up the good work!] // NOTE: we don't want to say "-1.2 gained" so we always make sure what we display is positive string gainedLost = (amountLost < 0) ? Constants.Strings.DailyInfoPage_Summary_Gained : Constants.Strings.DailyInfoPage_Summary_Lost; string endingText = (todaysEntry.Weight <= todaysGoalWeight) ? Constants.Strings.DailyInfoPage_SummaryEnding_OnTrack : Constants.Strings.DailyInfoPage_SummaryEnding_OffTrack; return(string.Format(Constants.Strings.DailyInfoPage_ProgressSummary, gainedLost, Math.Abs(amountLost), Constants.Strings.Common_WeightUnit, daysSinceStart, daysToGo, amountRemaining, endingText)); }
async Task <bool> ShowWelcomeFlowIfNeeded() { // check if they have seen the getting started flow yet or don't have a goal WeightLossGoal existingGoal = null; try { IncrementPendingRequestCount(); existingGoal = await DataService.GetGoal(); } catch (Exception ex) { AnalyticsService.TrackFatalError($"{nameof(ShowWelcomeFlowIfNeeded)} - an exception occurred.", ex); // NOTE:: not showing an error here as this is not in response to user action. potentially should show a non-intrusive error banner return(false); } finally { DecrementPendingRequestCount(); // hide loading } bool showGettingStartedFlow = (existingGoal == null && !SettingsService.HasDismissedStartupView); #if DEBUG if (Constants.App.DEBUG_AlwaysShowGettingStarted) #pragma warning disable CS0162 // Unreachable code detected { showGettingStartedFlow = true; } #pragma warning restore CS0162 // Unreachable code detected #endif if (showGettingStartedFlow) { AnalyticsService.TrackEvent(Constants.Analytics.DailyInfoCategory, Constants.Analytics.DailyInfo_LaunchingGettingStarted, 1); SettingsService.HasDismissedStartupView = true; // don't put them in this flow again await Task.Delay(500); // slight delay before fly-up modal so they see the context of the app before it appears await NavigationService.NavigateAsync($"{nameof(NavigationPage)}/{nameof(GettingStartedPage)}", useModalNavigation : true); return(true); } return(false); }
public static bool WeightMetGoalOnDate(WeightLossGoal goal, DateTime dt, decimal weightOnDate) { if (goal == null) { return(false); } if (weightOnDate == decimal.MinValue) { return(false); } var goalWeightForDate = GetGoalWeightForDate(goal, dt.Date); return(weightOnDate <= goalWeightForDate); }
async void TestEndingAGoal() { if (!await ShowLoseDataWarning()) { return; } try { IncrementPendingRequestCount(); await ClearData(); // set a goal where today is the goal end date var goalStartDate = DateTime.Today.Date - TimeSpan.FromDays(30); var goalEndDate = DateTime.Today.Date; var goal = new WeightLossGoal(goalStartDate, 240, goalEndDate, 210); await DataService.SetGoal(goal); // add some weights await DataService.AddWeightEntry(new WeightEntry(goalStartDate + TimeSpan.FromDays(5), 235)); await DataService.AddWeightEntry(new WeightEntry(goalStartDate + TimeSpan.FromDays(10), 230)); await DataService.AddWeightEntry(new WeightEntry(goalStartDate + TimeSpan.FromDays(15), 225)); await DataService.AddWeightEntry(new WeightEntry(goalStartDate + TimeSpan.FromDays(20), 220)); await DataService.AddWeightEntry(new WeightEntry(goalStartDate + TimeSpan.FromDays(25), 215)); } finally { DecrementPendingRequestCount(); } Close(); }
public async Task <bool> SetGoal(WeightLossGoal weightLossGoal) { #if DEBUG await SimulateSlowNetworkIfEnabled(); #endif // delete anything existing goal if (!await RemoveGoal()) { FireUserDataUpdated(); return(false); } var result = await _connection.InsertAsync(weightLossGoal); if (result != 1) { FireUserDataUpdated(); return(false); } FireUserDataUpdated(); return(true); }
void RefreshGraphDataModel(List <WeightEntry> entries, WeightLossGoal goal) { // TODO:: FUTURE:: does all of this have to be done for each refresh? could the axis's be re-used and just // have the data points repopulated? var dateRange = WeightLogicHelpers.GetGraphDateRange(entries); DateTime dateRangeStart = dateRange.Item1; DateTime dateRangeEnd = dateRange.Item2; var weightRange = WeightLogicHelpers.GetMinMaxWeightRange(goal, entries, dateRangeStart, dateRangeEnd); decimal minGraphWeight = weightRange.Item1; decimal maxGraphWeight = weightRange.Item2; // OxyPlot var plotModel = new PlotModel(); // { Title = "OxyPlot Demo" }; plotModel.IsLegendVisible = false; plotModel.PlotAreaBorderColor = GRID_LINES_COLOR_BORDER; // NOTE:: it is assumed the date will always be the first axes in the AxisChanged wiring/un-wiring as that is used // to adjust line markers to show months instead of weeks at a certain zoom level // XAxis - dates plotModel.Axes.Add( new DateTimeAxis { Position = AxisPosition.Bottom, Minimum = DateTimeAxis.ToDouble(dateRangeStart), Maximum = DateTimeAxis.ToDouble(dateRangeEnd), AxislineColor = OxyColors.White, TicklineColor = OxyColors.White, MajorGridlineColor = GRID_LINES_COLOR_MAJOR, MinorGridlineColor = GRID_LINES_COLOR_MINOR, AxislineStyle = LineStyle.Solid, TextColor = OxyColors.White, TickStyle = TickStyle.Outside, MajorGridlineStyle = LineStyle.Solid, MinorGridlineStyle = LineStyle.Solid, MinorIntervalType = DateTimeIntervalType.Days, IntervalType = DateTimeIntervalType.Days, MinorStep = WeekScale_MinorStep, MajorStep = WeekScale_MajorStep, // a week StringFormat = WeekScale_AxisFormat, // TODO:: FUTURE:: make swap for some cultures? IsZoomEnabled = true, MinimumRange = Constants.App.Graph_MinDateRangeVisible, // closest zoom in shows at least 5 days MaximumRange = Constants.App.Graph_MaxDateRangeVisible, // furthest zoom out shows at most 1 year }); // YAxis - weights plotModel.Axes.Add( new LinearAxis { Position = AxisPosition.Left, Minimum = (double)minGraphWeight, Maximum = (double)maxGraphWeight, AxislineColor = OxyColors.White, TicklineColor = OxyColors.White, MajorGridlineColor = GRID_LINES_COLOR_MAJOR, MinorGridlineColor = GRID_LINES_COLOR_MINOR, AxislineStyle = LineStyle.Solid, TextColor = OxyColors.White, TickStyle = TickStyle.Outside, MajorGridlineStyle = LineStyle.Solid, MinorGridlineStyle = LineStyle.Solid, MinorStep = 1, MajorStep = 5, IsZoomEnabled = true, MinimumRange = Constants.App.Graph_MinWeightRangeVisible, // closest zoom in shows at least 5 pounds MaximumRange = Constants.App.Graph_MaxWeightRangeVisible // furthest zoom out shows at most 100 pounds }); var series1 = new LineSeries { MarkerType = MarkerType.Circle, MarkerSize = 4, MarkerStroke = OxyColors.White, MarkerFill = OxyColors.White, StrokeThickness = 4, MarkerStrokeThickness = 1, Color = OxyColors.White }; foreach (var entry in entries) { series1.Points.Add(new DataPoint(DateTimeAxis.ToDouble(entry.Date), Decimal.ToDouble(entry.Weight))); } plotModel.Series.Clear(); plotModel.Series.Add(series1); // setup goal line if (goal != null) { var series2 = new LineSeries { MarkerType = MarkerType.None, LineStyle = LineStyle.Dash, Color = OxyColors.White }; // diet line // we want to extend the goal line at least 30 days past the end of the goal and extend it further if they are already past // the goal date (ex: they are 90 days past goal end date and just using the line for maintenance) var goalExtendedDate = goal.GoalDate + TimeSpan.FromDays(30); if (DateTime.Today.Date > goalExtendedDate) { goalExtendedDate = DateTime.Today.Date + TimeSpan.FromDays(30); } series2.Points.Add(new DataPoint(DateTimeAxis.ToDouble(goal.StartDate - TimeSpan.FromDays(30)), (double)goal.StartWeight)); series2.Points.Add(new DataPoint(DateTimeAxis.ToDouble(goal.StartDate), (double)goal.StartWeight)); series2.Points.Add(new DataPoint(DateTimeAxis.ToDouble(goal.GoalDate), (double)goal.GoalWeight)); series2.Points.Add(new DataPoint(DateTimeAxis.ToDouble(goalExtendedDate), (double)goal.GoalWeight)); plotModel.Series.Add(series2); } UnwireDateAxisChangedEvent(); // unwire any previous event handlers for axis zoom changing PlotModel = plotModel; PlotModel.Axes[0].AxisChanged += DateAxis_Changed; }
async void Save() { AnalyticsService.TrackEvent(Constants.Analytics.SetGoalCategory, Constants.Analytics.SetGoal_SavedGoal, 1); // convert entered value to a valid weight decimal startWeight, goalWeight; if (!decimal.TryParse(StartWeight, out startWeight) || !decimal.TryParse(GoalWeight, out goalWeight)) { // show error about invalid value if we can't convert the entered value to a decimal await DialogService.DisplayAlertAsync(Constants.Strings.SetGoalPage_InvalidWeight_Title, Constants.Strings.SetGoalPage_InvalidWeight_Message, Constants.Strings.GENERIC_OK); return; } // give warning if goal weight is greater than start weight // NOTE:: we don't prevent this scenario as I have had friends intentionally use the previous version of line diet for // tracking weight gain during pregnancy or muscle building - so we just give a warning. We also don't prevent equal // start and goal weights in case they just want a line to show a maintenance weight they are trying to stay at if (goalWeight > startWeight) { await DialogService.DisplayAlertAsync(Constants.Strings.SetGoalPage_GoalWeightGreaterThanStartWeight_Title, Constants.Strings.SetGoalpage_GoalWeightGreaterThanStartWeight_Message, Constants.Strings.GENERIC_OK); } try { IncrementPendingRequestCount(); // see if they've entered a different weight already for this date, if so warn them about it being updated var existingWeight = await DataService.GetWeightEntryForDate(StartDate); if (existingWeight != null) { if (existingWeight.Weight != startWeight) { // show warning that an existing entry will be updated (is actually deleted and re-added), allow them to cancel var result = await DialogService.DisplayAlertAsync(Constants.Strings.Common_UpdateExistingWeight_Title, string.Format(Constants.Strings.Common_UpdateExistingWeight_Message, existingWeight.Weight, StartDate, startWeight), Constants.Strings.GENERIC_OK, Constants.Strings.GENERIC_CANCEL); // if they canceled the dialog then return without changing anything if (!result) { return; } } // remove existing weight if (!await DataService.RemoveWeightEntryForDate(StartDate)) { AnalyticsService.TrackError($"{nameof(Save)} - Error when trying to remove existing weight entry for start date"); await DialogService.DisplayAlertAsync(Constants.Strings.Common_SaveError, Constants.Strings.SetGoalPage_Save_RemoveExistingWeightFailed_Message, Constants.Strings.GENERIC_OK); return; } } var addStartWeightResult = await DataService.AddWeightEntry(new WeightEntry(StartDate, startWeight)); if (!addStartWeightResult) { AnalyticsService.TrackError($"{nameof(Save)} - Error when trying to add weight entry for start date"); await DialogService.DisplayAlertAsync(Constants.Strings.Common_SaveError, Constants.Strings.SetGoalPage_Save_AddingWeightFailed_Message, Constants.Strings.GENERIC_OK); return; } var weightLossGoal = new WeightLossGoal(StartDate, startWeight, GoalDate.Date, goalWeight); if (!await DataService.SetGoal(weightLossGoal)) { AnalyticsService.TrackError($"{nameof(Save)} - Error when trying to save new weight loss goal"); await DialogService.DisplayAlertAsync(Constants.Strings.Common_SaveError, Constants.Strings.SetGoalPage_Save_AddingGoalFailed_Message, Constants.Strings.GENERIC_OK); return; } await NavigationService.GoBackAsync(useModalNavigation : true); } catch (Exception ex) { AnalyticsService.TrackFatalError($"{nameof(Save)} - an exception occurred.", ex); await DialogService.DisplayAlertAsync(Constants.Strings.Common_SaveError, Constants.Strings.SetGoalPage_Save_Exception_Message, Constants.Strings.GENERIC_OK); } finally { DecrementPendingRequestCount(); } }
async void Save() { AnalyticsService.TrackEvent(Constants.Analytics.SetGoalCategory, Constants.Analytics.SetGoal_SavedGoal, 1); // convert entered value to a valid weight bool parsedWeightFields = true; decimal startWeight = 0; decimal goalWeight = 0; if (ShowStonesEntryFields) { var startWeightStoneFields = GetStartWeightInStones(); var goalWeightStoneFields = GetGoalWeightInStones(); if (startWeightStoneFields == null || goalWeightStoneFields == null) { parsedWeightFields = false; } else { startWeight = startWeightStoneFields.ToPoundsDecimal(); goalWeight = goalWeightStoneFields.ToPoundsDecimal(); } } else { if (!decimal.TryParse(StartWeight, NumberStyles.AllowDecimalPoint, CultureInfo.CurrentCulture, out startWeight) || !decimal.TryParse(GoalWeight, NumberStyles.AllowDecimalPoint, CultureInfo.CurrentCulture, out goalWeight)) { parsedWeightFields = false; } } if (!parsedWeightFields) { // show error about invalid value if we can't convert the entered value to a decimal await DialogService.DisplayAlertAsync(Constants.Strings.SetGoalPage_InvalidWeight_Title, Constants.Strings.SetGoalPage_InvalidWeight_Message, Constants.Strings.Generic_OK); return; } // give warning if goal weight is greater than start weight // NOTE:: we don't prevent this scenario as I have had friends intentionally use the previous version of line diet for // tracking weight gain during pregnancy or muscle building - so we just give a warning. We also don't prevent equal // start and goal weights in case they just want a line to show a maintenance weight they are trying to stay at if (goalWeight > startWeight) { // TODO:: analytics var result = await DialogService.DisplayAlertAsync(Constants.Strings.SetGoalPage_GoalWeightGreaterThanStartWeight_Title, Constants.Strings.SetGoalpage_GoalWeightGreaterThanStartWeight_Message, Constants.Strings.Generic_OK, Constants.Strings.Generic_Cancel); if (!result) { return; } } try { IncrementPendingRequestCount(); // see if they've entered a different weight already for this date, if so warn them about it being updated var existingEntry = await DataService.GetWeightEntryForDate(StartDate); if (existingEntry != null) { if (existingEntry.Weight != startWeight) { // show different message for stones/pounds string warningMessage; if (ShowStonesEntryFields) { var existingWeightInStones = existingEntry.Weight.ToStonesAndPounds(); var startWeightInStones = startWeight.ToStonesAndPounds(); warningMessage = string.Format(Constants.Strings.Common_UpdateExistingWeight_Message, string.Format(Constants.Strings.Common_Stones_WeightFormat, existingWeightInStones.Stones, existingWeightInStones.Pounds), StartDate, string.Format(Constants.Strings.Common_Stones_WeightFormat, startWeightInStones.Stones, startWeightInStones.Pounds)); } else { warningMessage = string.Format(Constants.Strings.Common_UpdateExistingWeight_Message, existingEntry.Weight, StartDate, startWeight); } // show warning that an existing entry will be updated (is actually deleted and re-added), allow them to cancel var result = await DialogService.DisplayAlertAsync(Constants.Strings.Common_UpdateExistingWeight_Title, warningMessage, Constants.Strings.Generic_OK, Constants.Strings.Generic_Cancel); // if they canceled the dialog then return without changing anything if (!result) { return; } } // remove existing weight if (!await DataService.RemoveWeightEntryForDate(StartDate)) { AnalyticsService.TrackError($"{nameof(Save)} - Error when trying to remove existing weight entry for start date"); await DialogService.DisplayAlertAsync(Constants.Strings.Common_SaveError, Constants.Strings.SetGoalPage_Save_RemoveExistingWeightFailed_Message, Constants.Strings.Generic_OK); return; } } var addStartWeightResult = await DataService.AddWeightEntry(new WeightEntry(StartDate, startWeight, SettingsService.WeightUnit)); if (!addStartWeightResult) { AnalyticsService.TrackError($"{nameof(Save)} - Error when trying to add weight entry for start date"); await DialogService.DisplayAlertAsync(Constants.Strings.Common_SaveError, Constants.Strings.SetGoalPage_Save_AddingWeightFailed_Message, Constants.Strings.Generic_OK); return; } var weightLossGoal = new WeightLossGoal(StartDate, startWeight, GoalDate.Date, goalWeight, SettingsService.WeightUnit); if (!await DataService.SetGoal(weightLossGoal)) { AnalyticsService.TrackError($"{nameof(Save)} - Error when trying to save new weight loss goal"); await DialogService.DisplayAlertAsync(Constants.Strings.Common_SaveError, Constants.Strings.SetGoalPage_Save_AddingGoalFailed_Message, Constants.Strings.Generic_OK); return; } await NavigationService.GoBackAsync(useModalNavigation : true); } catch (Exception ex) { AnalyticsService.TrackFatalError($"{nameof(Save)} - an exception occurred.", ex); await DialogService.DisplayAlertAsync(Constants.Strings.Common_SaveError, Constants.Strings.SetGoalPage_Save_Exception_Message, Constants.Strings.Generic_OK); } finally { DecrementPendingRequestCount(); } }
// NOTE:: primarily used for screenshots, is based on specific dates async void TestRealDataSet() { if (!await ShowLoseDataWarning()) { return; } try { IncrementPendingRequestCount(); await ClearData(); // set goal var goal = new WeightLossGoal(new DateTime(2017, 1, 1), 237.4M, new DateTime(2017, 7, 1), 200, WeightUnitEnum.ImperialPounds); await DataService.SetGoal(goal); // add some weights await DataService.AddWeightEntry(new WeightEntry(new DateTime(2017, 1, 1), 237.4M, WeightUnitEnum.ImperialPounds)); await DataService.AddWeightEntry(new WeightEntry(new DateTime(2017, 1, 17), 235.2M, WeightUnitEnum.ImperialPounds)); await DataService.AddWeightEntry(new WeightEntry(new DateTime(2017, 2, 4), 233.0M, WeightUnitEnum.ImperialPounds)); await DataService.AddWeightEntry(new WeightEntry(new DateTime(2017, 2, 22), 230.8M, WeightUnitEnum.ImperialPounds)); await DataService.AddWeightEntry(new WeightEntry(new DateTime(2017, 2, 27), 229.4M, WeightUnitEnum.ImperialPounds)); await DataService.AddWeightEntry(new WeightEntry(new DateTime(2017, 2, 28), 228.6M, WeightUnitEnum.ImperialPounds)); await DataService.AddWeightEntry(new WeightEntry(new DateTime(2017, 3, 1), 228.2M, WeightUnitEnum.ImperialPounds)); await DataService.AddWeightEntry(new WeightEntry(new DateTime(2017, 3, 2), 227.0M, WeightUnitEnum.ImperialPounds)); await DataService.AddWeightEntry(new WeightEntry(new DateTime(2017, 3, 3), 226.4M, WeightUnitEnum.ImperialPounds)); await DataService.AddWeightEntry(new WeightEntry(new DateTime(2017, 3, 4), 227.0M, WeightUnitEnum.ImperialPounds)); await DataService.AddWeightEntry(new WeightEntry(new DateTime(2017, 3, 5), 227.2M, WeightUnitEnum.ImperialPounds)); await DataService.AddWeightEntry(new WeightEntry(new DateTime(2017, 3, 6), 226.0M, WeightUnitEnum.ImperialPounds)); await DataService.AddWeightEntry(new WeightEntry(new DateTime(2017, 3, 7), 225.4M, WeightUnitEnum.ImperialPounds)); await DataService.AddWeightEntry(new WeightEntry(new DateTime(2017, 3, 8), 225.4M, WeightUnitEnum.ImperialPounds)); await DataService.AddWeightEntry(new WeightEntry(new DateTime(2017, 3, 9), 225.2M, WeightUnitEnum.ImperialPounds)); await DataService.AddWeightEntry(new WeightEntry(new DateTime(2017, 3, 10), 225.8M, WeightUnitEnum.ImperialPounds)); await DataService.AddWeightEntry(new WeightEntry(new DateTime(2017, 3, 11), 225.2M, WeightUnitEnum.ImperialPounds)); await DataService.AddWeightEntry(new WeightEntry(new DateTime(2017, 3, 12), 223.8M, WeightUnitEnum.ImperialPounds)); await DataService.AddWeightEntry(new WeightEntry(new DateTime(2017, 3, 13), 223.5M, WeightUnitEnum.ImperialPounds)); await DataService.AddWeightEntry(new WeightEntry(new DateTime(2017, 3, 14), 223.0M, WeightUnitEnum.ImperialPounds)); await DataService.AddWeightEntry(new WeightEntry(new DateTime(2017, 3, 15), 221.8M, WeightUnitEnum.ImperialPounds)); await DataService.AddWeightEntry(new WeightEntry(new DateTime(2017, 3, 16), 221.6M, WeightUnitEnum.ImperialPounds)); await DataService.AddWeightEntry(new WeightEntry(new DateTime(2017, 3, 17), 221.4M, WeightUnitEnum.ImperialPounds)); } finally { DecrementPendingRequestCount(); } Close(); }
public static Tuple <decimal, decimal> GetMinMaxWeightRange(WeightLossGoal goal, List <WeightEntry> entries, DateTime dateStart, DateTime dateEnd) { if (entries.Count == 0) { if (goal != null) { // there should normally be at least one weight if a goal is set, there is nothing really to graph but the goal line itself return(new Tuple <decimal, decimal>(goal.GoalWeight - Constants.App.Graph_GoalOnly_Padding, goal.GoalWeight + Constants.App.Graph_GoalOnly_Padding)); } // no goal set and no saved weights, so just graph a default range return(new Tuple <decimal, decimal>(Constants.App.Graph_WeightRange_DefaultMin, Constants.App.Graph_WeightRange_DefaultMax)); } decimal minValue = decimal.MaxValue; decimal maxValue = decimal.MinValue; // if there is a goal set then we want to include that line for the date range we're looking at if (goal != null) { // now see if our goal is greater/less for start end dates, if so include those in the range decimal goalStart = GetGoalWeightForDate(goal, dateStart); if (goalStart != decimal.MinValue) { if (goalStart < minValue) { minValue = goalStart; } if (goalStart > maxValue) { maxValue = goalStart; } } decimal goalEnd = GetGoalWeightForDate(goal, dateEnd); if (goalEnd != decimal.MinValue) { if (goalEnd < minValue) { minValue = goalEnd; } if (goalEnd > maxValue) { maxValue = goalEnd; } } } foreach (var entry in entries) { if (entry.Weight < minValue) { minValue = (decimal)entry.Weight; } if (entry.Weight > maxValue) { maxValue = (decimal)entry.Weight; } } minValue = minValue * Constants.App.Graph_WeightRange_MinPadding; maxValue = maxValue * Constants.App.Graph_WeightRange_MaxPadding; minValue = (decimal)Math.Floor(minValue); // use whole numbers maxValue = (decimal)Math.Ceiling(maxValue); return(new Tuple <decimal, decimal>(minValue, maxValue)); }