From e025a487bc53da11697091e99c72e84c40d72b39 Mon Sep 17 00:00:00 2001
From: Robert Goldmann <deadlocker@gmx.de>
Date: Tue, 8 Aug 2017 20:09:05 +0200
Subject: [PATCH] #136 - categories chart is fixed, export of other charts is
 temporarily disabled

---
 ...artGenerator.java => CategoriesChart.java} | 93 +++++++++++++++----
 .../chartGenerators/ChartExportable.java      |  8 ++
 .../logic/chartGenerators/LegendType.java     |  6 ++
 .../budgetmaster/ui/ChartController.java      | 90 +++++++++---------
 .../ui/ExportChartController.java             | 29 ++----
 .../budgetmaster/ui/ReportTab.fxml            |  2 +-
 6 files changed, 143 insertions(+), 85 deletions(-)
 rename src/de/deadlocker8/budgetmaster/logic/chartGenerators/{CategoriesChartGenerator.java => CategoriesChart.java} (75%)
 create mode 100644 src/de/deadlocker8/budgetmaster/logic/chartGenerators/ChartExportable.java
 create mode 100644 src/de/deadlocker8/budgetmaster/logic/chartGenerators/LegendType.java

diff --git a/src/de/deadlocker8/budgetmaster/logic/chartGenerators/CategoriesChartGenerator.java b/src/de/deadlocker8/budgetmaster/logic/chartGenerators/CategoriesChart.java
similarity index 75%
rename from src/de/deadlocker8/budgetmaster/logic/chartGenerators/CategoriesChartGenerator.java
rename to src/de/deadlocker8/budgetmaster/logic/chartGenerators/CategoriesChart.java
index 1b157ee80..d94618d06 100644
--- a/src/de/deadlocker8/budgetmaster/logic/chartGenerators/CategoriesChartGenerator.java
+++ b/src/de/deadlocker8/budgetmaster/logic/chartGenerators/CategoriesChart.java
@@ -6,26 +6,37 @@ import de.deadlocker8.budgetmaster.logic.CategoryInOutSum;
 import de.deadlocker8.budgetmaster.logic.Helpers;
 import javafx.geometry.Insets;
 import javafx.geometry.Pos;
+import javafx.scene.Scene;
+import javafx.scene.SnapshotParameters;
 import javafx.scene.control.Label;
 import javafx.scene.control.Tooltip;
+import javafx.scene.image.WritableImage;
 import javafx.scene.layout.GridPane;
 import javafx.scene.layout.HBox;
 import javafx.scene.layout.Priority;
+import javafx.scene.layout.Region;
 import javafx.scene.layout.VBox;
 import javafx.scene.paint.Color;
+import javafx.scene.transform.Transform;
+import javafx.stage.Modality;
+import javafx.stage.Stage;
 import tools.ConvertTo;
 
-public class CategoriesChartGenerator
+public class CategoriesChart extends VBox implements ChartExportable
 {
-	private String title;
+	private String titleIncomes;
+	private String titlePayments;
 	private ArrayList<CategoryInOutSum> categoryInOutSums;
-	private boolean useBudgetIN;
 	private String currency;
-	private double total;
+	private double totalIncomes;
+	private double totalPayments;
+	private LegendType legendType;
+	
 
-	public CategoriesChartGenerator(String title, ArrayList<CategoryInOutSum> categoryInOutSums, boolean useBudgetIN, String currency)
+	public CategoriesChart(String titleIncomes, String titlePayments, ArrayList<CategoryInOutSum> categoryInOutSums, String currency, LegendType legendType)
 	{
-		this.title = title;
+		this.titleIncomes = titleIncomes;
+		this.titlePayments = titlePayments;
 		if(categoryInOutSums == null)
 		{
 			this.categoryInOutSums = new ArrayList<>();
@@ -33,13 +44,33 @@ public class CategoriesChartGenerator
 		else
 		{
 			this.categoryInOutSums = categoryInOutSums;
-		}		
-		this.useBudgetIN = useBudgetIN;
+		}
+		
 		this.currency = currency;
-		this.total = getTotal(this.categoryInOutSums, useBudgetIN);
+		this.totalIncomes = getTotal(this.categoryInOutSums, true);
+		this.totalPayments = getTotal(categoryInOutSums, false);
+		this.legendType = legendType;
+		
+		this.setSpacing(10);
+		
+		this.getChildren().add(generate(titleIncomes, true));
+		this.getChildren().add(generate(titlePayments, false));
+		
+		Region spacer = new Region();
+		this.getChildren().add(spacer);
+		VBox.setVgrow(spacer, Priority.ALWAYS);
+		
+		if(this.legendType == LegendType.NORMAL)
+		{
+			this.getChildren().add(generateLegend());
+		}
+		else if(this.legendType == LegendType.FULL)
+		{
+			this.getChildren().add(generateFullLegend());		
+		}
 	}	
 
-	public VBox generate()
+	private VBox generate(String title, boolean useIncomes)
 	{
 		VBox generatedChart = new VBox();
 		HBox chart = new HBox();
@@ -58,17 +89,18 @@ public class CategoriesChartGenerator
 			chart.getChildren().add(currentPart);
 
 			double value;
-			if(useBudgetIN)
+			double percentage;
+			if(useIncomes)
 			{
 				value = currentItem.getBudgetIN() / 100.0;
+				percentage = value / totalIncomes;
 			}
 			else
 			{
 				value = -currentItem.getBudgetOUT() / 100.0;
+				percentage = value / totalPayments;
 			}
 
-			double percentage = value / total;
-
 			currentPart.prefWidthProperty().bind(chart.widthProperty().multiply(percentage));
 			
 			String categoryName = currentItem.getName();
@@ -87,7 +119,7 @@ public class CategoriesChartGenerator
 		return generatedChart;
 	}
 
-	public GridPane generateLegend()
+	private GridPane generateLegend()
 	{
 		GridPane legend = new GridPane();
 		legend.setPadding(new Insets(10));
@@ -133,7 +165,7 @@ public class CategoriesChartGenerator
 		return legend;
 	}
 	
-	public VBox generateFullLegend()
+	private VBox generateFullLegend()
 	{
 		VBox legend = new VBox();
 		legend.setPadding(new Insets(10));
@@ -242,12 +274,12 @@ public class CategoriesChartGenerator
 		return legendItem;
 	}
 
-	private double getTotal(ArrayList<CategoryInOutSum> categoryInOutSums, boolean useBudgetIN)
+	private double getTotal(ArrayList<CategoryInOutSum> categoryInOutSums, boolean useIncomes)
 	{		
 		double total = 0;
 		for(CategoryInOutSum currentItem : categoryInOutSums)
 		{
-			if(useBudgetIN)
+			if(useIncomes)
 			{
 				total += currentItem.getBudgetIN() / 100.0;
 			}
@@ -258,4 +290,31 @@ public class CategoriesChartGenerator
 		}
 		return total;
 	}
+
+	@Override
+	public WritableImage export(int width, int height)
+	{
+		VBox root = new VBox();
+		root.setPadding(new Insets(25));
+		root.getChildren().add(generate(titleIncomes, true));
+		root.getChildren().add(generate(titlePayments, false));
+		
+		Region spacer = new Region();
+		root.getChildren().add(spacer);
+		VBox.setVgrow(spacer, Priority.ALWAYS);
+		
+		root.getChildren().add(generateFullLegend());		
+		
+		Stage newStage = new Stage();
+		newStage.initModality(Modality.NONE);
+		newStage.setScene(new Scene(root, width, height));
+		newStage.setResizable(false);		
+		newStage.show();
+		
+		SnapshotParameters sp = new SnapshotParameters();
+		sp.setTransform(Transform.scale(width / root.getWidth(), height / root.getHeight()));
+		newStage.close();
+		
+		return root.snapshot(sp, null);
+	}
 }
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/logic/chartGenerators/ChartExportable.java b/src/de/deadlocker8/budgetmaster/logic/chartGenerators/ChartExportable.java
new file mode 100644
index 000000000..2189d23a2
--- /dev/null
+++ b/src/de/deadlocker8/budgetmaster/logic/chartGenerators/ChartExportable.java
@@ -0,0 +1,8 @@
+package de.deadlocker8.budgetmaster.logic.chartGenerators;
+
+import javafx.scene.image.WritableImage;
+
+public interface ChartExportable
+{
+	WritableImage export(int width, int height);
+}
diff --git a/src/de/deadlocker8/budgetmaster/logic/chartGenerators/LegendType.java b/src/de/deadlocker8/budgetmaster/logic/chartGenerators/LegendType.java
new file mode 100644
index 000000000..f597aff27
--- /dev/null
+++ b/src/de/deadlocker8/budgetmaster/logic/chartGenerators/LegendType.java
@@ -0,0 +1,6 @@
+package de.deadlocker8.budgetmaster.logic.chartGenerators;
+
+public enum LegendType
+{
+	NONE, NORMAL, FULL;
+}
diff --git a/src/de/deadlocker8/budgetmaster/ui/ChartController.java b/src/de/deadlocker8/budgetmaster/ui/ChartController.java
index 6cb72445f..6b96c34d5 100644
--- a/src/de/deadlocker8/budgetmaster/ui/ChartController.java
+++ b/src/de/deadlocker8/budgetmaster/ui/ChartController.java
@@ -13,7 +13,9 @@ import de.deadlocker8.budgetmaster.logic.ExceptionHandler;
 import de.deadlocker8.budgetmaster.logic.Helpers;
 import de.deadlocker8.budgetmaster.logic.MonthInOutSum;
 import de.deadlocker8.budgetmaster.logic.ServerConnection;
-import de.deadlocker8.budgetmaster.logic.chartGenerators.CategoriesChartGenerator;
+import de.deadlocker8.budgetmaster.logic.chartGenerators.CategoriesChart;
+import de.deadlocker8.budgetmaster.logic.chartGenerators.ChartExportable;
+import de.deadlocker8.budgetmaster.logic.chartGenerators.LegendType;
 import de.deadlocker8.budgetmaster.logic.chartGenerators.LineChartGenerator;
 import de.deadlocker8.budgetmaster.logic.chartGenerators.MonthChartGenerator;
 import fontAwesome.FontIcon;
@@ -39,7 +41,6 @@ import javafx.scene.control.ToggleGroup;
 import javafx.scene.layout.AnchorPane;
 import javafx.scene.layout.HBox;
 import javafx.scene.layout.Priority;
-import javafx.scene.layout.Region;
 import javafx.scene.layout.VBox;
 import javafx.scene.paint.Color;
 import javafx.stage.Modality;
@@ -71,6 +72,8 @@ public class ChartController implements Refreshable
 	private Controller controller;
 	private Button buttonChartMonthExport;
 	private File lastExportPath;
+	
+	private CategoriesChart categoriesChart;
 
 	public void init(Controller controller)
 	{
@@ -85,7 +88,7 @@ public class ChartController implements Refreshable
 		iconShow.setColor(Color.WHITE);
 		buttonChartCategoriesShow.setStyle("-fx-background-color: #2E79B9;");
 		buttonChartCategoriesShow.setGraphic(iconShow);
-		
+
 		FontIcon iconShow2 = new FontIcon(FontIconType.SAVE);
 		iconShow2.setSize(16);
 		iconShow2.setColor(Color.WHITE);
@@ -97,18 +100,19 @@ public class ChartController implements Refreshable
 		iconShow3.setColor(Color.WHITE);
 		buttonChartMonthShow.setStyle("-fx-background-color: #2E79B9;");
 		buttonChartMonthShow.setGraphic(iconShow3);
-		
+
 		buttonChartMonthExport = new Button();
-		buttonChartMonthExport.setOnAction((event)->{
-			export(vboxChartMonth);
-		});		
-		
+		//DEBUG
+//		buttonChartMonthExport.setOnAction((event) -> {
+//			export(vboxChartMonth);
+//		});
+
 		FontIcon iconShow4 = new FontIcon(FontIconType.SAVE);
 		iconShow4.setSize(16);
 		iconShow4.setColor(Color.WHITE);
 		buttonChartMonthExport.setStyle("-fx-background-color: #2E79B9;");
 		buttonChartMonthExport.setGraphic(iconShow4);
-		
+
 		datePickerEnd.setDayCellFactory(new Callback<DatePicker, DateCell>()
 		{
 			@Override
@@ -133,52 +137,40 @@ public class ChartController implements Refreshable
 		comboBoxStartMonth.setItems(FXCollections.observableArrayList(Helpers.getMonthList()));
 		comboBoxStartYear.setItems(FXCollections.observableArrayList(Helpers.getYearList()));
 		comboBoxEndMonth.setItems(FXCollections.observableArrayList(Helpers.getMonthList()));
-		comboBoxEndYear.setItems(FXCollections.observableArrayList(Helpers.getYearList()));				
+		comboBoxEndYear.setItems(FXCollections.observableArrayList(Helpers.getYearList()));
 
 		final ToggleGroup toggleGroup = new ToggleGroup();
 		radioButtonBars.setToggleGroup(toggleGroup);
 		radioButtonBars.setSelected(true);
-		radioButtonLines.setToggleGroup(toggleGroup);		
+		radioButtonLines.setToggleGroup(toggleGroup);
 
 		accordion.setExpandedPane(accordion.getPanes().get(0));
 		vboxChartMonth.setSpacing(15);
 	}
-	
+
 	public void buttonChartCategoriesShow()
 	{
-		chartCategoriesShow(false);
+		chartCategoriesShow(LegendType.NORMAL);
 	}
 
-	public void chartCategoriesShow(boolean fullLegend)
+	public void chartCategoriesShow(LegendType legendType)
 	{
 		DateTime startDate = DateTime.parse(datePickerStart.getValue().toString());
 		DateTime endDate = DateTime.parse(datePickerEnd.getValue().toString());
-
 		try
 		{
 			ServerConnection connection = new ServerConnection(controller.getSettings());
 			ArrayList<CategoryInOutSum> sums = connection.getCategoryInOutSumForMonth(startDate, endDate);
 
-			Platform.runLater(() -> {
+			Platform.runLater(()->{;
 				vboxChartCategories.getChildren().clear();
-
-				CategoriesChartGenerator generator = new CategoriesChartGenerator("Einnahmen nach Kategorien", sums, true, controller.getSettings().getCurrency());
-				vboxChartCategories.getChildren().add(generator.generate());
-				generator = new CategoriesChartGenerator("Ausgaben nach Kategorien", sums, false, controller.getSettings().getCurrency());
-				vboxChartCategories.getChildren().add(generator.generate());
-
-				Region spacer = new Region();
-				vboxChartCategories.getChildren().add(spacer);
-				VBox.setVgrow(spacer, Priority.ALWAYS);
-
-				if(fullLegend)
-				{
-					vboxChartCategories.getChildren().add(generator.generateFullLegend());
-				}
-				else
-				{
-					vboxChartCategories.getChildren().add(generator.generateLegend());
-				}
+				categoriesChart = new CategoriesChart("Einnahmen nach Kategorien", 
+																	  "Ausgaben nach Kategorien",
+																	  sums,
+																	  controller.getSettings().getCurrency(),
+																	  legendType);
+				vboxChartCategories.getChildren().add(categoriesChart);
+				VBox.setVgrow(categoriesChart, Priority.ALWAYS);
 			});
 		}
 		catch(Exception e)
@@ -192,14 +184,16 @@ public class ChartController implements Refreshable
 	
 	public void chartCategoriesExport()
 	{
-		export(vboxChartCategories);
+		if(categoriesChart != null)
+		{
+			export(categoriesChart);
+		}
 	}
-	
-	public void export(VBox chart)
-	{	
-		Worker.runLater(()->{
-			chartCategoriesShow(true);
-			Platform.runLater(()->{
+
+	public void export(ChartExportable chart)
+	{
+		Worker.runLater(() -> {
+			Platform.runLater(() -> {
 				try
 				{
 					FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/de/deadlocker8/budgetmaster/ui/ExportChartGUI.fxml"));
@@ -218,7 +212,7 @@ public class ChartController implements Refreshable
 				catch(IOException e)
 				{
 					Logger.error(e);
-				}	
+				}
 			});
 		});
 	}
@@ -239,7 +233,7 @@ public class ChartController implements Refreshable
 				hboxChartMonthButtons.getChildren().remove(buttonChartMonthExport);
 			}
 		}
-		
+
 		Platform.runLater(() -> {
 			vboxChartMonth.getChildren().clear();
 		});
@@ -304,17 +298,17 @@ public class ChartController implements Refreshable
 			});
 		}
 	}
-	
+
 	public Controller getControlle()
 	{
 		return controller;
 	}
-	
+
 	public void setLastExportPath(File lastExportPath)
 	{
-		this.lastExportPath = lastExportPath;		
+		this.lastExportPath = lastExportPath;
 	}
-	
+
 	public File getLastExportPath()
 	{
 		return lastExportPath;
@@ -340,7 +334,7 @@ public class ChartController implements Refreshable
 		comboBoxEndYear.setValue(String.valueOf(controller.getCurrentDate().plusMonths(6).getYear()));
 
 		Worker.runLater(() -> {
-			chartCategoriesShow(false);
+			chartCategoriesShow(LegendType.NORMAL);
 			chartMonthShow();
 
 			Platform.runLater(() -> {
diff --git a/src/de/deadlocker8/budgetmaster/ui/ExportChartController.java b/src/de/deadlocker8/budgetmaster/ui/ExportChartController.java
index d33e8612a..f054c82ba 100644
--- a/src/de/deadlocker8/budgetmaster/ui/ExportChartController.java
+++ b/src/de/deadlocker8/budgetmaster/ui/ExportChartController.java
@@ -7,11 +7,11 @@ import java.util.Optional;
 
 import javax.imageio.ImageIO;
 
+import de.deadlocker8.budgetmaster.logic.chartGenerators.ChartExportable;
 import fontAwesome.FontIcon;
 import fontAwesome.FontIconType;
 import javafx.embed.swing.SwingFXUtils;
 import javafx.fxml.FXML;
-import javafx.scene.SnapshotParameters;
 import javafx.scene.control.Alert;
 import javafx.scene.control.Alert.AlertType;
 import javafx.scene.control.Button;
@@ -21,9 +21,7 @@ import javafx.scene.control.TextField;
 import javafx.scene.control.TextFormatter;
 import javafx.scene.image.WritableImage;
 import javafx.scene.layout.AnchorPane;
-import javafx.scene.layout.VBox;
 import javafx.scene.paint.Color;
-import javafx.scene.transform.Transform;
 import javafx.stage.FileChooser;
 import javafx.stage.Stage;
 import logger.Logger;
@@ -41,10 +39,10 @@ public class ExportChartController
 	
 	private ChartController controller;
 	private Stage stage;
-	private VBox chart;
+	private ChartExportable chart;
 	private File savePath;
 
-	public void init(Stage stage, ChartController controller, VBox chart)
+	public void init(Stage stage, ChartController controller, ChartExportable chart)
 	{
 		this.controller = controller;
 		this.stage = stage;
@@ -55,13 +53,9 @@ public class ExportChartController
 		{
 			labelSavePath.setText(savePath.getAbsolutePath());
 		}
-		
-		stage.setOnCloseRequest((event)->{
-			controller.chartCategoriesShow(false);
-		});
-		
-		textFieldWidth.setText(String.valueOf((int)chart.getWidth()));
-		textFieldHeight.setText(String.valueOf((int)chart.getHeight()));
+				
+		textFieldWidth.setText("600");
+		textFieldHeight.setText("400");
 
 		anchorPaneMain.setStyle("-fx-background-color: #F4F4F4;");
 		
@@ -177,11 +171,10 @@ public class ExportChartController
 		{
 			AlertGenerator.showAlert(AlertType.WARNING, "Warnung", "", "Wähle einen Speicherort für das Diagramm aus.", controller.getControlle().getIcon(), stage, null, false);
 			return;
-		}			
+		}
+		
+		WritableImage image = chart.export(width, height);		
 		
-		SnapshotParameters sp = new SnapshotParameters();
-		sp.setTransform(Transform.scale(width / chart.getWidth(), height / chart.getHeight()));
-		WritableImage image = chart.snapshot(sp, null);		
 		try
 		{
 			ImageIO.write(SwingFXUtils.fromFXImage(image, null), "png", savePath);
@@ -237,14 +230,12 @@ public class ExportChartController
 			AlertGenerator.showAlert(AlertType.ERROR, "Fehler", "", "Beim Exportieren des Diagramms ist ein Fehler aufgetreten:\n\n" + e.getMessage(), controller.getControlle().getIcon(), stage, null, false);
 		}
 		
-		stage.close();
-		controller.chartCategoriesShow(false);
+		stage.close();	
 		controller.setLastExportPath(savePath);
 	}
 	
 	public void cancel()
 	{
 		stage.close();
-		controller.chartCategoriesShow(false);
 	}
 }
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/ui/ReportTab.fxml b/src/de/deadlocker8/budgetmaster/ui/ReportTab.fxml
index 9910f4d01..7896f7852 100644
--- a/src/de/deadlocker8/budgetmaster/ui/ReportTab.fxml
+++ b/src/de/deadlocker8/budgetmaster/ui/ReportTab.fxml
@@ -45,7 +45,7 @@
                   </VBox>
                </children>
                <VBox.margin>
-                  <Insets />
+                  <Insets bottom="10.0" />
                </VBox.margin>
             </HBox>
             <TableView fx:id="tableView" prefHeight="270.0" prefWidth="772.0" VBox.vgrow="ALWAYS">
-- 
GitLab