如何创建一个包含重复条目的 XYChart.Series 的可观察列表
How to create an observable list of XYChart.Series that combines duplicate entry
我想用数据库中的数据填充折线图。为此,我创建了一个 class,returns 一个 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); }
}
这将产生这个输出
如您所见,Permanent
和 Job Order
有重复的系列
问题是
我将如何合并重复的条目以便获得下面的输出?
without using a model class
编辑
正如@kleopatra 所说,(根据我目前对 java 的了解) 我尝试通过以下方式过滤列表中的数据:
for (XYChart.Series series : getData()){
XYChart.Data item = (XYChart.Data) series.getData().get(0);
if (lineChart.getData().size() > 0){
for (XYChart.Series duplicate : lineChart.getData())
{
if (duplicate.getName().equals(series.getName()))
{
duplicate.getData().add(item);
} else {
// lineChart.getData().add(series);
}
}
} else {
lineChart.getData().add(series);
}
}
而不仅仅是:
for(XYChart.Series series : getData())
{
lineChart.getData().add(series);
}
尽管它为我提供了 Permanent
系列的串联输出(这是我想要实现的)。我几乎不能添加另一个系列,例如Job Order
到折线图。就像我在 else
条件下取消注释代码一样。我收到一个错误。
ConcurrentModificationException
使用@kleopatra 的想法,您可以过滤列表并使用过滤后的数据创建 Series
。您的要求使事情复杂化。 Arrays.asList("Permanent", "2011", 5)
也使事情复杂化。在 Java
中创建不同类型的 List
是不好的做法。在我的示例中,我使用 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);
}
}
我想用数据库中的数据填充折线图。为此,我创建了一个 class,returns 一个 ObservableList
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); }
}
这将产生这个输出
如您所见,Permanent
和 Job Order
问题是
我将如何合并重复的条目以便获得下面的输出?
without using a model class
编辑
正如@kleopatra 所说,(根据我目前对 java 的了解) 我尝试通过以下方式过滤列表中的数据:
for (XYChart.Series series : getData()){
XYChart.Data item = (XYChart.Data) series.getData().get(0);
if (lineChart.getData().size() > 0){
for (XYChart.Series duplicate : lineChart.getData())
{
if (duplicate.getName().equals(series.getName()))
{
duplicate.getData().add(item);
} else {
// lineChart.getData().add(series);
}
}
} else {
lineChart.getData().add(series);
}
}
而不仅仅是:
for(XYChart.Series series : getData())
{
lineChart.getData().add(series);
}
尽管它为我提供了 Permanent
系列的串联输出(这是我想要实现的)。我几乎不能添加另一个系列,例如Job Order
到折线图。就像我在 else
条件下取消注释代码一样。我收到一个错误。
ConcurrentModificationException
使用@kleopatra 的想法,您可以过滤列表并使用过滤后的数据创建 Series
。您的要求使事情复杂化。 Arrays.asList("Permanent", "2011", 5)
也使事情复杂化。在 Java
中创建不同类型的 List
是不好的做法。在我的示例中,我使用 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);
}
}