Почему после очистки данные остаются на LineChart? - PullRequest
0 голосов
/ 20 апреля 2020

У меня есть приложение погоды, которое я создаю, чтобы опробовать функции в JavaFX, но когда я звоню:

package controller.tab;

import application.CSVReader;
import controller.MainController;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.chart.*;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.stage.Window;

import java.text.DateFormatSymbols;
import java.util.ArrayList;

public class Tab2Controller {

private MainController main;
private CSVReader CSVReader;

private int[] firstTimeCalled;

private ObservableList<XYChart.Series<String, Float>> firstLineChartData;
private ObservableList<XYChart.Series<String, Float>> secondLineChartData;

private ArrayList<XYChart.Data<String, Float>> list1;
private ArrayList<XYChart.Data<String, Float>> list2;

@FXML private LineChart<String, Float> firstLineChart;
@FXML private LineChart<String, Float> secondLineChart;

@FXML private ComboBox<String> comboSelect1;
@FXML private ComboBox<String> comboSelect2;

public void init(MainController mainController) {
    main = mainController;
    CSVReader = new CSVReader();

    firstLineChartData = FXCollections.observableArrayList();
    secondLineChartData = FXCollections.observableArrayList();

    setChartsNotAnimated();

    list1 = new ArrayList<>();
    list2 = new ArrayList<>();

    firstTimeCalled = new int[]{-1,-1};
}

public void initialiseCharts(String cityName) {
    for (int i=0; i<4; i++) {
        firstTimeCalled[i] = -1;
    }

    clearEverything(firstLineChart, firstLineChartData, list1, comboSelect1);
    clearEverything(secondLineChart, secondLineChartData, list2, comboSelect2);

    ArrayList<String> values = CSVReader.getYearlyStationStats(cityName);

    if (!values.isEmpty()) {
        for (String value : values) {
            String[] coord = value.split(",");
            list1.add(new XYChart.Data<>(coord[0], Float.parseFloat(coord[1])));
            list2.add(new XYChart.Data<>(coord[0], Float.parseFloat(coord[2])));
        }

        firstLineChartData.add(new LineChart.Series<>(FXCollections.observableList(list1)));
        secondLineChartData.add(new LineChart.Series<>(FXCollections.observableList(list2)));

        firstLineChart.getData().setAll(firstLineChartData);
        secondLineChart.getData().setAll(secondLineChartData);

        ArrayList<String> cities = CSVReader.getAllYears(cityName);
        for (String city : cities) {
            comboSelect1.getItems().add(city);
            comboSelect2.getItems().add(city);
        }

        comboSelect1.getItems().add("All years");
        comboSelect2.getItems().add("All years");

        firstLineChart.getYAxis().setLabel("Temperature (℃)");
        firstLineChart.getXAxis().setLabel("Year");

        secondLineChart.getYAxis().setLabel("Temperature (℃)");
        secondLineChart.getXAxis().setLabel("Year");

        firstLineChart.setTitle("Highest Max Mean Temperature vs. Years");
        secondLineChart.setTitle("Lowest Min Mean Temperature vs. Years");
    }

    firstLineChart.setLegendVisible(false);
    secondLineChart.setLegendVisible(false);
}

private void setChartsNotAnimated() {
    firstLineChart.setAnimated(false);
    secondLineChart.setAnimated(false);
}

private ArrayList<XYChart.Data<String, Float>> getSelectedData(String cityName, String year_selected, Integer indexOfData) {
    ArrayList<String> selectedData = CSVReader.getAllData(cityName, year_selected);
    list1 = new ArrayList<>();
    for (String data : selectedData) {
        String[] split_data = data.split(",");
        list1.add(new XYChart.Data<>(changeToMonth(split_data[1]), Float.parseFloat(split_data[indexOfData])));
    }
    return list1;
}

private void fillChart(String cityName, int index, String year_selected, ComboBox<String> newBox, XYChart<String, Float> chart, ObservableList<XYChart.Series<String, Float>> list){
    if (cityName != null && !newBox.getSelectionModel().isEmpty()) {
        if (year_selected.compareTo("All years")==0){
            for (String year : CSVReader.getAllYears(cityName)){
                if(!checkChartContains(year, list)) {
                    list1 = getSelectedData(cityName, year, index);
                    list.add(new LineChart.Series<>(year, FXCollections.observableList(list1)));
                }
            }
        } else {
            list1 = getSelectedData(cityName, year_selected, index);
            Window current = chart.getScene().getWindow();
            checkValidity(current, year_selected, FXCollections.observableList(list1), list);
        }
        chart.getXAxis().setLabel("Month");
        if (index == 2) {
            chart.setTitle("Highest Max Mean Temperature vs. Months");
        }
        if (index == 3) {
            chart.setTitle("Lowest Min Mean Temperature vs. Months");
        }
        if (index == 4) {
            chart.setTitle("Total Frost Days vs. Months");
        }
        if (index == 5) {
            chart.setTitle("Total Rainfall vs. Months");
        }
    }
    chart.getData().setAll(list);
}

@FXML
private void addDataToChart(ActionEvent event) {
    String cityName = main.getCityName();
    Button btn = (Button) event.getSource();
    String year_selected;

    if (btn.getId().compareTo("btnAdd1")==0) {
        year_selected = comboSelect1.getSelectionModel().getSelectedItem();
        clearDataOnly(0);
        fillChart(cityName,2, year_selected, comboSelect1, firstLineChart, firstLineChartData);
    }

    if (btn.getId().compareTo("btnAdd2")==0) {
        year_selected = comboSelect2.getSelectionModel().getSelectedItem();
        clearDataOnly(1);
        fillChart(cityName,3, year_selected, comboSelect2, secondLineChart, secondLineChartData);
    }
}

@FXML private void revertCharts() {
    String cityName = main.getCityName();
    initialiseCharts(cityName);
}

private void clearAxis(XYChart<String, Float> chart) {
    chart.getYAxis().setLabel("");
    chart.getXAxis().setLabel("");
    chart.setTitle("");
}

private void clearEverything(XYChart<String,Float> chart,
                             ObservableList<XYChart.Series<String, Float>> chartData,
                             ArrayList<XYChart.Data<String, Float>> series_list,
                             ComboBox<String> comboBox) {
    chart.getData().clear();
    chartData.clear();
    series_list.clear();
    comboBox.getItems().clear();
}

@FXML
private void clearChartOnly(ActionEvent event) {
    Button btn = (Button) event.getSource();

    if (btn.getId().compareTo("btnClear1")==0) {
        firstLineChartData.clear();
        firstLineChart.getData().clear();
        clearAxis(firstLineChart);
    }

    if (btn.getId().compareTo("btnClear2")==0) {
        secondLineChartData.clear();
        secondLineChart.getData().clear();
        clearAxis(secondLineChart);
    }
}

private void clearDataOnly(Integer number) {
    if ((firstTimeCalled[number] == -1) && (number == 0)) {
        firstLineChart.getData().clear();
        firstLineChartData.clear();
        firstTimeCalled[number] = 1;
        firstLineChart.setLegendVisible(true);
    }

    if ((firstTimeCalled[number] == -1) && (number == 1)) {
        secondLineChart.getData().clear();
        secondLineChartData.clear();
        firstTimeCalled[number] = 1;
        secondLineChart.setLegendVisible(true);
    }
}

private String changeToMonth(String number) {
    DateFormatSymbols dfs = new DateFormatSymbols();
    String[] months = dfs.getMonths();
    return months[Integer.parseInt(number)-1];
}

private static void showAlert(Window owner, String title, String message) {
    Alert alert = new Alert(Alert.AlertType.ERROR);
    alert.setTitle(title);
    alert.setHeaderText(null);
    alert.setContentText(message);
    alert.initOwner(owner);
    alert.show();
}

private boolean checkChartContains(String year_selected, ObservableList<XYChart.Series<String, Float>> chartToAddTo) {
    for (LineChart.Series<String, Float> series1 : chartToAddTo) {
        if(series1.getName().compareTo(year_selected)==0){
            return true;
        }
    }
    return false;
}

private void checkValidity(Window current, String year_selected, ObservableList<XYChart.Data<String,Float>> observableFloatList, ObservableList<XYChart.Series<String, Float>> chartToAddTo) {
    boolean alreadyContains = checkChartContains(year_selected, chartToAddTo);
    if (alreadyContains && chartToAddTo.size()>=3) {
        showAlert(current, "Unnecessary Extra Data", "The graph already contains 3 or more sets of data, you cannot add more.");
    } else if (chartToAddTo.size()>=3) {
        showAlert(current, "Unnecessary Extra Data", "The graph already contains 3 or more sets of data, you cannot add more.");
    } else if (alreadyContains) {
        showAlert(current, "Already Exists", "The graph already contains this data, it cannot be added again.");
    }

    if (!alreadyContains && chartToAddTo.size()<3) {
        chartToAddTo.add(new LineChart.Series<>(year_selected, observableFloatList));
    }
}

} я получаю следующее, но только на secondLineChart, первая диаграмма не не делай этого, есть ли ошибка, о которой я должен знать? Я добавляю строку данных, и когда я ее очищаю, я получаю следующую проблему, мой код очень длинный, поэтому я выветрил его (простите за каламбур), чтобы сделать его немного легче для чтения, вызовы для очистки находятся в обычно функция и переменные secondLineChartData и list2 инициализируются. Если вам нужно больше кода, чем я, я с радостью добавлю его, мне просто интересно, будет ли этот код более простым для исправления.

Заранее спасибо.

enter image description here

...