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