生成动态StackedBarChart

时间:2016-01-02 15:20:36

标签: javafx javafx-2 javafx-8

我想从Java Object创建动态StackedBarChart。我试过这段代码:

Java对象:

public class EventsObj
{
    private String date;
    private int info;
    private int error;
    private int warning;
    private int critical;

    public EventsObj()
    {
    }

    public EventsObj(String date, int info, int error, int warning, int critical)
    {
        this.date = date;
        this.info = info;
        this.error = error;
        this.warning = warning;
        this.critical = critical;
    }

    public String getDate()
    {
        return date;
    }

    public void setDate(String date)
    {
        this.date = date;
    }

    public int getInfo()
    {
        return info;
    }

    public void setInfo(int info)
    {
        this.info = info;
    }

    public int getError()
    {
        return error;
    }

    public void setError(int error)
    {
        this.error = error;
    }

    public int getWarning()
    {
        return warning;
    }

    public void setWarning(int warning)
    {
        this.warning = warning;
    }

    public int getCritical()
    {
        return critical;
    }

    public void setCritical(int critical)
    {
        this.critical = critical;
    }
}

Java代码:

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.StackedBarChart;
import javafx.scene.chart.XYChart;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;

public class MainApp extends Application
{
    private StackedBarChart<String, Number> stackedChart;
    private List<EventsObj> eventsObj;

    @Override
    public void start(Stage stage) throws Exception
    {
        createStackedChart();
        List<EventsObj> testData = generateTestData();

        addStackedChartData(testData);

        HBox hb = new HBox(20);
        hb.setPadding(new Insets(10, 20, 20, 40));
        hb.getChildren().add(stackedChart);

        Scene scene = new Scene(hb);
        stage.setTitle("JavaFX and Maven");
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args)
    {
        launch(args);
    }

    private void createStackedChart()
    {
        CategoryAxis xAxis = new CategoryAxis();
        xAxis.setLabel("Days");
        NumberAxis yAxis = new NumberAxis();

        stackedChart = new StackedBarChart<>(xAxis, yAxis);
        stackedChart.setCategoryGap(20);
        stackedChart.setMinSize(500, 400);
        stackedChart.setMaxSize(500, 400);
    }

    private List<EventsObj> generateTestData()
    {
        eventsObj = new ArrayList<>();

        for (int i = 0; i < 20; i++)
        {
            eventsObj.add(new EventsObj(String.valueOf(randomDate()), random(2, 60), random(2, 60), random(2, 60), random(2, 60)));
        }

        return eventsObj;
    }

    public static int random(int lowerBound, int upperBound)
    {
        return (lowerBound + (int) Math.round(Math.random() * (upperBound - lowerBound)));
    }

    private LocalDate randomDate()
    {
        Random random = new Random();
        int minDay = (int) LocalDate.of(1900, 1, 1).toEpochDay();
        int maxDay = (int) LocalDate.of(2015, 1, 1).toEpochDay();
        long randomDay = minDay + random.nextInt(maxDay - minDay);

        LocalDate randomBirthDate = LocalDate.ofEpochDay(randomDay);

        return randomBirthDate;
    }

    private void addStackedChartData(List<EventsObj> data)
    {
        ObservableList<XYChart.Series<String, Number>> observableArrayList = FXCollections.observableArrayList();

        ObservableList<XYChart.Series<String, Number>> observabt = FXCollections.observableArrayList();

        for (EventsObj data1 : data)
        {
            final XYChart.Series<String, Number> series1 = new XYChart.Series<>();
            EventsObj get = data1;
            series1.setName(get.getDate());
            series1.getData().add(new XYChart.Data<>(get.getDate(), get.getInfo()));
            series1.getData().add(new XYChart.Data<>(get.getDate(), get.getWarning()));
            series1.getData().add(new XYChart.Data<>(get.getDate(), get.getCritical()));
            series1.getData().add(new XYChart.Data<>(get.getDate(), get.getError()));
            observabt.addAll(series1);
        }

        stackedChart.getData().addAll(observabt);
    }
}

我需要生成StackedBarChart,每天包含一个条形,其中包含事件类型InfoWarningCritical和{{1}的不同部分}。但由于某种原因,我无法做到正确。它应该是这样的:

enter image description here

应将日期替换为国家,年份应替换为事件类型。

你能帮我解决一下代码吗?

1 个答案:

答案 0 :(得分:1)

您想要创建一个图表,每个日期有一列,每列应包含部分InfoWarningErrorCritical。为此,您需要为每种事件类型创建不同的系列。但是,您使用date作为系列名称和列名称。你需要改变这个:

private static XYChart.Series<String, Number> createSeries(String name) {
    XYChart.Series<String, Number> series = new XYChart.Series<>();
    series.setName(name);
    return series;
}

private void addStackedChartData(List<EventsObj> data) {
    XYChart.Series<String, Number> infoSeries = createSeries("Info");
    XYChart.Series<String, Number> warningSeries = createSeries("Warning");
    XYChart.Series<String, Number> criticalSeries = createSeries("Critical");
    XYChart.Series<String, Number> errorSeries = createSeries("Error");

    for (EventsObj data1 : data) {
        String date = data1.getDate();
        infoSeries.getData().add(new XYChart.Data<>(date, data1.getInfo()));
        warningSeries.getData().add(new XYChart.Data<>(date, data1.getWarning()));
        errorSeries.getData().add(new XYChart.Data<>(date, data1.getError()));
        criticalSeries.getData().add(new XYChart.Data<>(date, data1.getCritical()));
    }
    stackedChart.getData().setAll(errorSeries, warningSeries, infoSeries, criticalSeries);
}

该系列必须以这种方式使用:

series.setName(<Color Key>);
series.getData().add(new XYChart.Data<>(<Column>, <Bar Size>));