I want to populate a line chart with data from the database. To achieve this, I created a class that returns an ObservableList<XYChart.Series>. But I struggle to merge the same XYChart.Series name (Like the example below).
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); }
}
As you have noticed, there are duplicate series for Permanent and Job Order
Question is
How will I merge that duplicate entry so that I can achieve the output below?
without using a model class
EDIT
As @kleopatra said, (Based from my current knowledge on java) I tried to filter the data from the list by :
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);
}
}
instead of just :
for(XYChart.Series series : getData())
{
lineChart.getData().add(series);
}
though it gives me the concatenated output for the Permanent series (which is what I want to achieve). I can hardly add another series e.g. Job Order to the line chart. As when I uncomment the code under else condition. I got an error.
ConcurrentModificationException


Using @kleopatra's ideas, you can filter the list and create the
Seriesusing the filtered data. Your requirements complicate things.Arrays.asList("Permanent", "2011", 5)also complicates things. It's bad practice inJavato create aListof different types. In my example, I used aHashMapto filter the data.