Javafx 如何创建包含重复条目的XYChart.Series的可观察列表

Javafx 如何创建包含重复条目的XYChart.Series的可观察列表,javafx,linechart,observablelist,Javafx,Linechart,Observablelist,我想用数据库中的数据填充折线图。为了实现这一点,我创建了一个返回ObservableList的类。但是我很难合并相同的XYChart.Series名称(如下面的示例) MVCE import javafx.application.Application; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.scene.Scene; import javaf

我想用数据库中的数据填充折线图。为了实现这一点,我创建了一个返回ObservableList的类。但是我很难合并相同的XYChart.Series名称(如下面的示例)

MVCE

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.stage.Stage;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Sample extends Application {
    @Override public void start(Stage stage) {
        //create the chart
        final CategoryAxis xAxis = new CategoryAxis();
        final NumberAxis yAxis = new NumberAxis();
        xAxis.setLabel("Year");

        final LineChart<String,Number> lineChart =
                new LineChart<>(xAxis, yAxis);

        lineChart.setTitle("Employment Monitoring, 2020");

        for(XYChart.Series series : getData()){
            lineChart.getData().add(series);
        }

        // show the scene.
        Scene scene = new Scene(lineChart, 800, 600);
        stage.setScene(scene);
        stage.show();
    }

    /* How can I return the right value to the line chart ? */
    private ObservableList<XYChart.Series> getData(){
        var list = FXCollections.<XYChart.Series>observableArrayList();
        
        // Supposed that this data where values retrieved from the database
        ArrayList<List> arrayList = new ArrayList<>();
        arrayList.add(Arrays.asList("Permanent", "2011", 5));
        arrayList.add(Arrays.asList("Job Order", "2011", 16));
        arrayList.add(Arrays.asList("Permanent", "2012", 10));
        arrayList.add(Arrays.asList("Job Order", "2012", 19));

        for (List obs : arrayList){
            list.add(
                    new XYChart.Series(
                            (String) obs.get(0),
                            FXCollections.observableArrayList(
                                    new XYChart.Data<>((String) obs.get(1), (Number) obs.get(2))
                            )
                    ));
        }
        return list;
    }

    public static void main(String[] args) { launch(args); }
}
而不仅仅是:

for(XYChart.Series series : getData())
{
    lineChart.getData().add(series);
}
尽管它给了我
永久性
系列的级联输出(这是我想要实现的)。我几乎无法在折线图中添加另一个系列,例如
工单
。当我在
else
条件下取消对代码的注释时。我犯了个错误

ConcurrentModificationException


使用@kleopatra的想法,您可以过滤列表并使用过滤后的数据创建
系列。你的要求使事情复杂化<代码>数组。asList(“永久”、“2011”、5)
也使事情复杂化。在
Java
中,创建不同类型的
列表是一种不好的做法。在我的示例中,我使用了
HashMap
来过滤数据

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.stage.Stage;

public class App extends Application
{

    @Override
    public void start(Stage stage)
    {
        //create the chart
        final CategoryAxis xAxis = new CategoryAxis();
        final NumberAxis yAxis = new NumberAxis();
        xAxis.setLabel("Year");

        final LineChart<String, Number> lineChart
                = new LineChart<>(xAxis, yAxis);

        lineChart.setTitle("Employment Monitoring, 2020");
        lineChart.getData().addAll(getData());
        

        // show the scene.
        Scene scene = new Scene(lineChart, 800, 600);
        stage.setScene(scene);
        stage.show();
    }

    /* How can I return the right value to the line chart ? */
    private List<XYChart.Series<String, Number>> getData()
    {
        List<XYChart.Series<String, Number>> series = new ArrayList();

        // Supposed that this data where values retrieved from the database
        List<List> items = new ArrayList<>();
        items.add(Arrays.asList("Permanent", "2011", 5));
        items.add(Arrays.asList("Job Order", "2011", 16));
        items.add(Arrays.asList("Permanent", "2012", 10));
        items.add(Arrays.asList("Job Order", "2012", 19));

        Map<String, List> map = new HashMap();
        for (int i = 0; i < items.size(); i++) {
            if (map.get(items.get(i).get(0).toString()) == null) {
                List newEntry = new ArrayList();
                newEntry.add(items.get(i).get(1));
                newEntry.add(items.get(i).get(2));
                map.put(items.get(i).get(0).toString(), newEntry);
                System.out.println("Createing array " + items.get(i).get(0).toString() + "  Adding " + items.get(i).get(1) + ":" + items.get(i).get(2));
            }
            else {
                List oldList = map.get(items.get(i).get(0).toString());
                oldList.add(items.get(i).get(1));
                oldList.add(items.get(i).get(2));
                System.out.println("Adding to array " + items.get(i).get(0).toString() + "  Adding " + items.get(i).get(1) + ":" + items.get(i).get(2));
            }
        }

        for (Map.Entry<String, List> entry : map.entrySet()) {
            XYChart.Series<String, Number> tempItemsSeries = new XYChart.Series();
            tempItemsSeries.setName(entry.getKey());

            //System.out.println(entry.getValue().size() + Arrays.toString(entry.getValue().toArray()));
            for (int i = 0; i < entry.getValue().size(); i = i + 2) {
                tempItemsSeries.getData().add(new XYChart.Data(entry.getValue().get(i), entry.getValue().get(i + 1)));
            }
            series.add(tempItemsSeries);
        }

        return series;
    }

    public static void main(String[] args)
    {
        launch(args);
    }
}
import java.util.ArrayList;
导入java.util.array;
导入java.util.HashMap;
导入java.util.List;
导入java.util.Map;
导入javafx.application.application;
导入javafx.scene.scene;
导入javafx.scene.chart.CategoryAxis;
导入javafx.scene.chart.LineChart;
导入javafx.scene.chart.NumberAxis;
导入javafx.scene.chart.XYChart;
导入javafx.stage.stage;
公共类应用程序扩展应用程序
{
@凌驾
公众假期开始(阶段)
{
//创建图表
最终CategoryAxis xAxis=新CategoryAxis();
最终数字axis yAxis=新数字axis();
xAxis.setLabel(“年度”);
最终折线图折线图
=新线形图(xAxis,yAxis);
线形图。setTitle(“就业监测,2020年”);
lineChart.getData().addAll(getData());
//展示场景。
场景=新场景(线条图,800600);
舞台场景;
stage.show();
}
/*如何将正确的值返回到折线图*/
私有列表getData()
{
列表系列=新的ArrayList();
//假设此数据包含从数据库检索的值
列表项=新建ArrayList();
添加(数组.asList(“永久”、“2011”和“5”);
添加(数组.asList(“工作订单”,“2011”,16));
添加(数组.asList(“永久”、“2012”和“10”);
添加(数组.asList(“工作订单”,“2012”,19));
Map Map=newhashmap();
对于(int i=0;i

使用@kleopatra的想法,您可以过滤列表并使用过滤后的数据创建
系列。你的要求使事情复杂化<代码>数组。asList(“永久”、“2011”、5)
也使事情复杂化。在
Java
中,创建不同类型的
列表是一种不好的做法。在我的示例中,我使用了
HashMap
来过滤数据

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.stage.Stage;

public class App extends Application
{

    @Override
    public void start(Stage stage)
    {
        //create the chart
        final CategoryAxis xAxis = new CategoryAxis();
        final NumberAxis yAxis = new NumberAxis();
        xAxis.setLabel("Year");

        final LineChart<String, Number> lineChart
                = new LineChart<>(xAxis, yAxis);

        lineChart.setTitle("Employment Monitoring, 2020");
        lineChart.getData().addAll(getData());
        

        // show the scene.
        Scene scene = new Scene(lineChart, 800, 600);
        stage.setScene(scene);
        stage.show();
    }

    /* How can I return the right value to the line chart ? */
    private List<XYChart.Series<String, Number>> getData()
    {
        List<XYChart.Series<String, Number>> series = new ArrayList();

        // Supposed that this data where values retrieved from the database
        List<List> items = new ArrayList<>();
        items.add(Arrays.asList("Permanent", "2011", 5));
        items.add(Arrays.asList("Job Order", "2011", 16));
        items.add(Arrays.asList("Permanent", "2012", 10));
        items.add(Arrays.asList("Job Order", "2012", 19));

        Map<String, List> map = new HashMap();
        for (int i = 0; i < items.size(); i++) {
            if (map.get(items.get(i).get(0).toString()) == null) {
                List newEntry = new ArrayList();
                newEntry.add(items.get(i).get(1));
                newEntry.add(items.get(i).get(2));
                map.put(items.get(i).get(0).toString(), newEntry);
                System.out.println("Createing array " + items.get(i).get(0).toString() + "  Adding " + items.get(i).get(1) + ":" + items.get(i).get(2));
            }
            else {
                List oldList = map.get(items.get(i).get(0).toString());
                oldList.add(items.get(i).get(1));
                oldList.add(items.get(i).get(2));
                System.out.println("Adding to array " + items.get(i).get(0).toString() + "  Adding " + items.get(i).get(1) + ":" + items.get(i).get(2));
            }
        }

        for (Map.Entry<String, List> entry : map.entrySet()) {
            XYChart.Series<String, Number> tempItemsSeries = new XYChart.Series();
            tempItemsSeries.setName(entry.getKey());

            //System.out.println(entry.getValue().size() + Arrays.toString(entry.getValue().toArray()));
            for (int i = 0; i < entry.getValue().size(); i = i + 2) {
                tempItemsSeries.getData().add(new XYChart.Data(entry.getValue().get(i), entry.getValue().get(i + 1)));
            }
            series.add(tempItemsSeries);
        }

        return series;
    }

    public static void main(String[] args)
    {
        launch(args);
    }
}
import java.util.ArrayList;
导入java.util.array;
导入java.util.HashMap;
导入java.util.List;
导入java.util.Map;
导入javafx.application.application;
导入javafx.scene.scene;
导入javafx.scene.chart.CategoryAxis;
导入javafx.scene.chart.LineChart;
导入javafx.scene.chart.NumberAxis;
导入javafx.scene.chart.XYChart;
导入javafx.stage.stage;
公共类应用程序扩展应用程序
{
@凌驾
公众假期开始(阶段)
{
//创建图表
最终CategoryAxis xAxis=新CategoryAxis();
最终数字axis yAxis=新数字axis();
xAxis.setLabel(“年度”);
最终折线图折线图
=新线形图(xAxis,yAxis);
线形图。setTitle(“就业监测,2020年”);
lineChart.getData().addAll(getData());
//展示场景。
场景=新场景(线条图,800600);
舞台场景;
stage.show();
}
/*如何将正确的值返回到折线图*/
私有列表getData()
{
列表系列=新的ArrayList();
//假设此数据包含从数据库检索的值
列表项=新建ArrayList();
添加(数组.asList(“永久”、“2011”和“5”);
添加(数组.asList(“工作订单”,“2011”,16));
添加(数组.asList(“永久”、“2012”和“10”);
添加(数组.asList(“工作订单”,“2012”,19));
Map Map=newhashmap();
对于(int i=0;i