2 Replies Latest reply: Aug 12, 2013 8:08 AM by tjozsa RSS

    Auto-resize plotted data while scrolling left-right

    935521
      In the attached code I have a line chart with 3% margin for Y upper and lower values. Obviously, these settings are related to all data series, in this case to all 18 data point, so the min and max Y chart values are setted by taking the lowest and the highest value then add or subtract 3%.

      So, the extremes values are "min is: 2.91, max is: 12.36"

      What I would like to get is to have min and max Y values related only to the visible plotted data, and auto-resize when chart is scrolled left-right.

      How to accomplish this?

      Thanks.
      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);
          }
      }
        • 1. Re: Auto-resize plotted data while scrolling left-right
          935521
          Any help very much appreciated, thanks!

          Edited by: 932518 on Jan 24, 2013 6:48 PM
          • 2. Re: Auto-resize plotted data while scrolling left-right
            tjozsa

            Hi,

             

            I know that it has been months now, but maybe it is still helpful. Actually you already wrote down the solution. You are successfully manipulating the axisX, do the same for axisY. something like this:

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

             

              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();

             

              NumberAxis yAxis = (NumberAxis) lineChart.getYAxis();

             

              double Tgap = xAxis.getWidth()

              / (xAxis.getUpperBound() - xAxis.getLowerBound());

              double newXlower = xAxis.getLowerBound(), newXupper = xAxis

              .getUpperBound();

              double newYlower = yAxis.getLowerBound(), newYupper = yAxis.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;

              newYlower = 1;

              newYupper = 5;

             

              } else if (rectinitX.get() > mouseEvent.getX()

              && newXupper <= 22) {

              newXlower = xAxis.getLowerBound() + Delta;

              newXupper = xAxis.getUpperBound() + Delta;

              newYlower = 5;

              newYupper = 50;

              }

              xAxis.setLowerBound(newXlower);

              xAxis.setUpperBound(newXupper);

              yAxis.setLowerBound(newYlower);

              yAxis.setUpperBound(newYupper);

              }

              rectinitX.set(mouseEvent.getX());

              }

              }

              };

             

            Sure I used dummy data here but it works as expected in my opinion. What you can do instead of dummy data is to trace the delta move on axisX, which was caused by the mouse drag event and iterate through your series to find the minimum and maximum Y values data to display on the chart. Then simply set the lower and upper bound on the axisY.

             

            Thanks very much for the idea on how to make the content of the chart scrolled. That is exactly what I have been searching for.

             

            Regards,

            Tamas