HARSHA sss
HARSHA sss

Reputation: 85

Getting Duplicate series error on second click for chart. How to resolve this?

I am trying to get graphs on click of a button but if I click the button the second time it is throwing a duplicate series exception. can anyone help me with this?

thanks in advance

Tried: 1. series.getData().clear();

NumberAxis xaxis = new NumberAxis(2008,2018,1);  
NumberAxis yaxis = new NumberAxis(10,80,5);
                 xaxis.setLabel("Year");  
                 yaxis.setLabel("Price");

XYChart.Series series = new XYChart.Series();

LineChart linechart = new LineChart(xaxis,yaxis); 


graph1.setOnAction(new EventHandler<ActionEvent>() {
             @Override
             public void handle(ActionEvent event) {
                 Linechart(X,Y,xaxis,yaxis);
             }



private void Linechart(ArrayList <Integer> X, ArrayList<Integer> Y, NumberAxis xaxis, NumberAxis yaxis) {

                 series.getData().clear();

                 series.setName("Stock Analysis");  
                 for(int i=0;i<=X.size()-1;i++){
                     series.getData().add(new XYChart.Data(X.get(i), Y.get(i)));
                 }
                 linechart.getData().add(series);
                 child2.getChildren().remove(area);
                 child2.getChildren().add(linechart);

             }

Upvotes: 3

Views: 237

Answers (1)

Slaw
Slaw

Reputation: 46315

The error you're getting is caused by adding the same Series instance to the same Chart a second time. Your method does not take into account if the series is already present in your chart, so invoking the method a second time naturally leads to the "duplicate series" error. Calling series.getData().clear() won't solve the problem because that clears the series' data, not the chart's data. It's unfortunate they named both properties the same thing (i.e. XYChart#getData() and Series#getData()) as it can get confusing.

You have at least two potential solutions, assuming you continue using the same Series instance:

  1. Remove the Series from the LineChart, update it, then add it back.

    chart.getData().remove(series);
    // update series
    chart.getData().add(series); // side-effect: series moved to end of list
    

    Note: This option may not work if the chart is animated. See JavaFX Duplicate Series Added and JavaFX Duplicate children PieChart.

  2. Simply don't add the Series to the LineChart if it's already present.

    if (!chart.getData().contains(series)) {
      chart.getData().add(series);
    }
    

An alternative is to create and use a new Series instance, if appropriate.

Additionally, calling child2.getChildren().add(linechart); should also cause an exception to be thrown once your method is invoked a second time. At least, it will once you fix your current problem as the current exception stops that line from being executed. The same Node cannot be added to the same Parent multiple times—same problem, different(ish) context.

Your method appears to be trying to do too much. Conceptually, it looks like you want the method to update the chart. If that's the case then there's no need to "re-add" either the Series to the chart or the LineChart to the parent. Set up the user interface when first initializing everything, then just have the method update the data as needed. Doing it this way means the you don't have to use either of the above solutions; it's also a better way of doing things overall.

Also note that you're using raw types. The LineChart, Series, and Data classes are all generic but you don't specify any type arguments. Since both your axes are NumberAxis you should be using:

  • LineChart<Number, Number> chart = new LineChart<>(xAxis, yAxis);
  • Series<Number, Number> series = new Series<>();
  • series.add(new Data<>(x.get(i), y.get(i))); (notice the diamond operator: <>).

And finally, try to follow Java naming conventions, especially when posting to a public forum.

Upvotes: 2

Related Questions