diff --git a/client/src/main/java/client/scenes/nutrition/NutritionPieChartCtrl.java b/client/src/main/java/client/scenes/nutrition/NutritionPieChartCtrl.java new file mode 100644 index 0000000..40d869b --- /dev/null +++ b/client/src/main/java/client/scenes/nutrition/NutritionPieChartCtrl.java @@ -0,0 +1,210 @@ +package client.scenes.nutrition; + +import client.utils.LocaleAware; +import client.utils.LocaleManager; +import com.google.inject.Inject; +import commons.FormalIngredient; +import commons.Ingredient; +import commons.Recipe; +import commons.VagueIngredient; +import javafx.fxml.FXML; +import javafx.scene.chart.PieChart; + +import java.util.List; +import java.util.Objects; +import java.util.logging.Logger; + +public class NutritionPieChartCtrl implements LocaleAware { + /** + * Nutrition info for a recipe or an ingredient. + * + * @param protein The protein this recipe/ingredient has + * @param fat The fat this recipe/ingredient has + * @param carbs The carbs this recipe/ingredient has + */ + private record CompleteNutritionInfo( + double protein, + double fat, + double carbs + ) { + /** + * Create a new {@link CompleteNutritionInfo} with zeroed values. + * + * @return A {@link CompleteNutritionInfo} with zeroed values. + */ + static CompleteNutritionInfo zero() { + return new CompleteNutritionInfo(0.0, 0.0, 0.0); + } + + /** + * Check whether this instance has all values set to zero. + * + * @return Whether all values (protein, carbs, fat) are zero. + */ + public boolean isZero() { + return this.protein() == 0.0 + && this.carbs() == 0.0 + && this.fat() == 0.0; + } + + /** + * Scale this object by an amount. Multiplies all values by amount. + * + * @param amount The amount to scale it by. + * @return The newly scaled nutrition info. + */ + public CompleteNutritionInfo scaled(double amount) { + return new CompleteNutritionInfo( + this.protein() * amount, + this.fat() * amount, + this.carbs() * amount + ); + } + + /** + * Add another nutrition info object to this object. + * + * @param rhs The nutrition info object to add. + * @return A new nutrition info object with the sum of both objects' nutrients. + */ + public CompleteNutritionInfo add(CompleteNutritionInfo rhs) { + return new CompleteNutritionInfo( + this.protein() + rhs.protein(), + this.fat() + rhs.fat(), + this.carbs() + rhs.carbs() + ); + } + } + + private final LocaleManager localeManager; + private final Logger logger = Logger.getLogger(NutritionPieChartCtrl.class.getName()); + + @FXML + PieChart pieChart; + + private Recipe recipe; + + @Inject + NutritionPieChartCtrl( + LocaleManager manager + ) { + this.localeManager = manager; + } + + /** + * Get the data for this pie chart based on the current recipe. + *
+ * This accumulates all the nutrients (properly scaled) from all ingredients in this recipe + * and returns a summary with data points. + *
+ *+ * The list will be of length 3 if any nutrients are added, or 0 if all the nutrients + * sum up to be 0. + *
+ * @return The data for this pie chart, as a labeled list of data. + */ + private List+ * The pie chart will disappear if all the nutrients in the recipe + * are zero. + *
+ * @param recipe The recipe to display. + */ + public void setRecipe(Recipe recipe) { + this.recipe = recipe; + this.refresh(); + } + + @Override + public void updateText() { + + } + + @Override + public LocaleManager getLocaleManager() { + return this.localeManager; + } + + /** + * Refresh the data in this pie chart. + */ + private void refresh() { + if (this.recipe == null) { + this.pieChart.setVisible(false); + logger.info("Refreshing pie chart with no recipe"); + return; + } + + logger.info("Refreshing pie chart with recipe"); + this.pieChart.setVisible(true); + this.pieChart.getData().setAll( + this.getPieChartData() + ); + } + + public void initializeComponents() { + final double START_ANGLE = 60.0; + + this.pieChart.setClockwise(true); + this.pieChart.setStartAngle(START_ANGLE); + this.refresh(); + } +} diff --git a/client/src/main/java/client/scenes/recipe/RecipeDetailCtrl.java b/client/src/main/java/client/scenes/recipe/RecipeDetailCtrl.java index d923ffd..e1926d3 100644 --- a/client/src/main/java/client/scenes/recipe/RecipeDetailCtrl.java +++ b/client/src/main/java/client/scenes/recipe/RecipeDetailCtrl.java @@ -2,6 +2,7 @@ package client.scenes.recipe; import client.exception.UpdateException; import client.scenes.FoodpalApplicationCtrl; +import client.scenes.nutrition.NutritionPieChartCtrl; import client.service.ShoppingListService; import client.utils.Config; import client.utils.ConfigService; @@ -102,6 +103,9 @@ public class RecipeDetailCtrl implements LocaleAware { @FXML private ComboBox