This discussion is archived
2 Replies Latest reply: Jan 18, 2013 12:07 PM by 935521 RSS

How to remove and add plotted data?

935521 Newbie
Currently Being Moderated
In my code below I would like to add two buttons and by clicking on a button("Remove") it will remove one by one plotted data,and plot it back by clicking on the button("Add") such as the examples:

Full data plotted by running the class

[http://s13.postimage.org/gw5bz9ak3/A02773.jpg]

Now by a single click on a Remove button last data point disappear

[http://s13.postimage.org/u87pzxsc3/A02774.jpg]

another click and again last data point disappear, and so on

[http://s2.postimage.org/fjxevg1ph/A02775.jpg]

The inverse operation would be performed by clicking on "Add" button: each click will add back a data point
import javafx.application.Application; 
import javafx.beans.property.SimpleDoubleProperty; 
import javafx.event.EventHandler;  
import javafx.scene.chart.NumberAxis; 
import javafx.scene.chart.XYChart; 
import javafx.stage.Stage; 
import javafx.scene.Scene; 
import javafx.scene.chart.LineChart; 
import javafx.scene.control.Button;
import javafx.scene.input.MouseEvent; 
import javafx.scene.layout.BorderPane; 

public class XYMove extends Application {

BorderPane pane; 
XYChart.Series series1 = new XYChart.Series(); 

SimpleDoubleProperty rectinitX = new SimpleDoubleProperty(); 
SimpleDoubleProperty rectX = new SimpleDoubleProperty(); 
SimpleDoubleProperty rectY = new SimpleDoubleProperty(); 

@Override 
public void start(Stage stage) { 
 
final NumberAxis xAxis = new NumberAxis(12, 20, 1);

double max = 12;
double min = 3;

max *= (1+((double)3/100));
min *= (1-((double)3/100));

final NumberAxis yAxis = new NumberAxis(min, max, 1); 

xAxis.setAnimated(false);
yAxis.setAnimated(false);

yAxis.setTickLabelFormatter(new NumberAxis.DefaultFormatter(yAxis) { 

    @Override 
    public String toString(Number object) { 
        return String.format("%2.0f", object); 
    } 
}); 

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

lineChart.setCreateSymbols(false); 
lineChart.setAlternativeRowFillVisible(false); 
lineChart.setAnimated(false); 
lineChart.setLegendVisible(false);

series1.getData().add(new XYChart.Data(1, 3)); 
series1.getData().add(new XYChart.Data(2, 8)); 
series1.getData().add(new XYChart.Data(3, 6)); 
series1.getData().add(new XYChart.Data(4, 7)); 
series1.getData().add(new XYChart.Data(5, 5)); 
series1.getData().add(new XYChart.Data(6, 6)); 
series1.getData().add(new XYChart.Data(7, 4)); 
series1.getData().add(new XYChart.Data(8, 7)); 
series1.getData().add(new XYChart.Data(9, 6)); 
series1.getData().add(new XYChart.Data(10, 7));
series1.getData().add(new XYChart.Data(11, 6)); 
series1.getData().add(new XYChart.Data(12, 7));
series1.getData().add(new XYChart.Data(13, 6));
series1.getData().add(new XYChart.Data(14, 12)); 
series1.getData().add(new XYChart.Data(15, 10)); 
series1.getData().add(new XYChart.Data(16, 11)); 
series1.getData().add(new XYChart.Data(17, 9)); 
series1.getData().add(new XYChart.Data(18, 10));

pane = new BorderPane(); 
pane.setCenter(lineChart); 
Scene scene = new Scene(pane, 800, 600); 
lineChart.getData().addAll(series1); 

stage.setScene(scene);         

scene.setOnMouseClicked(mouseHandler); 
scene.setOnMouseDragged(mouseHandler); 
scene.setOnMouseEntered(mouseHandler); 
scene.setOnMouseExited(mouseHandler); 
scene.setOnMouseMoved(mouseHandler); 
scene.setOnMousePressed(mouseHandler); 
scene.setOnMouseReleased(mouseHandler); 
stage.show();
} 

EventHandler<MouseEvent> mouseHandler = new EventHandler<MouseEvent>() { 

@Override 
public void handle(MouseEvent mouseEvent) { 

    if (mouseEvent.getEventType() == MouseEvent.MOUSE_PRESSED) {             
        rectinitX.set(mouseEvent.getX()); 
    } 
    else if (mouseEvent.getEventType() == MouseEvent.MOUSE_DRAGGED || mouseEvent.getEventType() == MouseEvent.MOUSE_MOVED) { 
        LineChart<Number, Number> lineChart = (LineChart<Number, Number>) pane.getCenter(); 
        NumberAxis xAxis = (NumberAxis) lineChart.getXAxis(); 

        double Tgap = xAxis.getWidth()/(xAxis.getUpperBound() - xAxis.getLowerBound()); 
        double newXlower=xAxis.getLowerBound(), newXupper=xAxis.getUpperBound();             
        double Delta=0.3;
        
        if(mouseEvent.getEventType() == MouseEvent.MOUSE_DRAGGED){
        if(rectinitX.get() < mouseEvent.getX()&& newXlower >= 0){    
            newXlower=xAxis.getLowerBound()-Delta;
            newXupper=xAxis.getUpperBound()-Delta;
        }
    else if(rectinitX.get() > mouseEvent.getX()&& newXupper <= 22){    
            newXlower=xAxis.getLowerBound()+Delta;
            newXupper=xAxis.getUpperBound()+Delta;
        }    
        xAxis.setLowerBound( newXlower ); 
        xAxis.setUpperBound( newXupper );                        
        }                                        
        rectinitX.set(mouseEvent.getX());                                 
     } 
  } 
}; 
    public static void main(String[] args) {
        launch(args);
    }
}
Thanks!
  • 1. Re: How to remove and add plotted data?
    James_D Guru
    Currently Being Moderated
    I would use an ObservableList (probably backed by a LinkedList) of XYChart.Data to store the collection of "deleted" data points. Create the buttons as usual; your "Remove" button's event handler should remove the last element of the series and add it to the first element of the deleted items data points. The "Add" button should remove the first element of the deleted data points and add it to the end of the series. You can bind the "disable" property of the remove and add button to Bindings.isEmpty(series1.getData()) and Bindings.isEmpty(deletedDataPoints), respectively.

    Something like
    ObservableList<XYChart.Data<Number, Number>> deletedDataPoints = FXCollections.observableList(new LinkedList<XYChart.Data<Number, Number>>());
    ...
    removeButton.setOnAction(new EventHandler<ActionEvent>() {
      @Override
      public void handle(ActionEvent event) {
        deletedDataPoints.add(0, series1.getData().remove(series1.getData().size()-1));
      }
    });
    addButton.setOnAction(new EventHandler<ActionEvent>() {
      @Override
      public void handle(ActionEvent event) {
        series1.getData().add(deletedDataPoints.remove(0));
      }
    });
    removeButton.disableProperty().bind(Bindings.isEmpty(series1.getData()));
    addButton.disableProperty().bind(Bindings.isEmpty(deletedDataPoints));
    The other approach would be to use a separate List for all the data points, and keep an integer variable storing the number of data points displayed. Your "remove" button would decrement the number displayed, and your "add" button would increment the number displayed. Both would also call
    series1.getData().setAll(allDataPoints.sublist(0, numberOfDisplayedPoints));
    You might even be able to make the numberOfDisplayedPoints an IntegerProperty and bind the data property of the series to it in a nice way. This approach probably doesn't perform as well as the previous approach (using a stack of deleted points), because you are not directly giving the chart as much detailed information about what has changed.

    Both approaches get problematic (in the sense that you need to carefully define your application logic, and then implement it) if the underlying data has the potential to change.
  • 2. Re: How to remove and add plotted data?
    935521 Newbie
    Currently Being Moderated
    Hi James D,

    thank you very much your suggestions are always greatly appreciated.

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points