package project.rainanalyser.alpha; import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.chart.BarChart; import javafx.scene.chart.CategoryAxis; import javafx.scene.chart.NumberAxis; import javafx.scene.chart.XYChart; import javafx.stage.Stage; import java.util.ArrayList; import java.util.List; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; public class RainfallVisualizer extends Application { private static final int CHART_WIDTH = 800; private static final int CHART_HEIGHT = 600; private static final int CHART_PADDING = 50; private static final int BAR_WIDTH = 20; private static final int BAR_SPACING = 10; private static final String[] MONTHS = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; private List rainfallData; @Override public void start(Stage stage) { readRainfallData(); final CategoryAxis xAxis = new CategoryAxis(); final NumberAxis yAxis = new NumberAxis(); final BarChart barChart = new BarChart<>(xAxis, yAxis); barChart.setTitle("Rainfall Visualiser"); xAxis.setLabel("Month"); yAxis.setLabel("Rainfall (mm)"); XYChart.Series series = new XYChart.Series<>(); double maxRainfall = Double.MIN_VALUE; double minRainfall = Double.MAX_VALUE; int maxIndex = -1; int minIndex = -1; for (int i = 0; i < rainfallData.size(); i++) { double rainfall = rainfallData.get(i); if (rainfall > maxRainfall) { maxRainfall = rainfall; maxIndex = i; } if (rainfall < minRainfall) { minRainfall = rainfall; minIndex = i; } XYChart.Data data = new XYChart.Data<>(MONTHS[i], rainfall); series.getData().add(data); } barChart.getData().add(series); for (XYChart.Data data : series.getData()) { if (data.getXValue().equals(MONTHS[maxIndex])) { data.getNode().setStyle("-fx-bar-fill: #146C94 ;"); // Set green color for the biggest month } else if (data.getXValue().equals(MONTHS[minIndex])) { data.getNode().setStyle("-fx-bar-fill: #AFD3E2;"); // Set red color for the smallest month } else { data.getNode().setStyle("-fx-bar-fill: #19A7CE;"); // Set blue color for the rest of the months } } Scene scene = new Scene(barChart, CHART_WIDTH, CHART_HEIGHT); barChart.setLegendVisible(false); stage.setScene(scene); stage.show(); } private void readRainfallData() { String[] files = { "output/output.csv" }; // Specify the input file name rainfallData = new ArrayList<>(); double[] monthlyTotal = new double[12]; int[] monthCount = new int[12]; try (BufferedReader reader = new BufferedReader(new FileReader(files[0]))) { String line; boolean firstLine = true; // Added a flag to indicate the first line while ((line = reader.readLine()) != null) { if (firstLine) { // Skip the first line firstLine = false; continue; } String[] data = line.split(","); if (data.length >= 5) { String year = data[0].trim(); String month = data[1].trim(); String rainfall = data[2].trim(); if (!rainfall.isEmpty() && !rainfall.equals("NaN")) { // Check for missing or invalid data double rainfallAmount = Double.parseDouble(rainfall); int monthIndex = getMonthIndex(month); if (monthIndex != -1) { // Skip data if month index is -1 monthlyTotal[monthIndex] += rainfallAmount; monthCount[monthIndex]++; } } } } for (int i = 0; i < MONTHS.length; i++) { if (monthCount[i] > 0) { double averageRainfall = monthlyTotal[i] / monthCount[i]; rainfallData.add(averageRainfall); } else { rainfallData.add(0.0); } } } catch (IOException e) { System.err.println("Error reading file: " + files[0]); e.printStackTrace(); } } private int getMonthIndex(String month) { try { int monthValue = Integer.parseInt(month); if (monthValue >= 1 && monthValue <= 12) { return monthValue - 1; // Subtract 1 to get the correct array index } } catch (NumberFormatException e) { // Month value is not a valid integer } return -1; // Invalid month value } public static void main(String[] args) { launch(args); } }