0 Replies Latest reply: May 7, 2012 8:28 AM by 935521 RSS

    Zoom on XYChart + draw freehand

    935521
      Hi all,

      I have a problem with zooming in JavaFX 2: I just posted this request in another forum but got no answer after nearly a week, so I hope to get help here

      This is my problem:

      By left mouse click and drag on a XYChart from upper left to lower right this code perform a perfect zoom of the area selected within a blue rectangle, and restore back by left mouse click and drag from lower right to upper left.

      This is perfect for the graph line plotted.

      Right mouse click and drag perform freehand draw, but it won't get magnified.

      Here is my code
      ..public class Zoom extends Application {
       
       Path path;//Add path for freehand
      BorderPane pane;
      Rectangle rect;
      SimpleDoubleProperty rectinitX = new SimpleDoubleProperty();
      SimpleDoubleProperty rectinitY = new SimpleDoubleProperty();
      SimpleDoubleProperty rectX = new SimpleDoubleProperty();
      SimpleDoubleProperty rectY = new SimpleDoubleProperty();
       
      double initXLowerBound = 0, initXUpperBound = 0, initYLowerBound = 0, initYUpperBound = 0;
      @Override
      public void start(Stage stage) {
       
          stage.setTitle("Line plot");
       
          final NumberAxis xAxis = new NumberAxis(1, 12, 1);
          final NumberAxis yAxis = new NumberAxis(0.53000, 0.53910, 0.0005);
       
          yAxis.setTickLabelFormatter(new NumberAxis.DefaultFormatter(yAxis) {
       
              @Override
              public String toString(Number object) {
                  return String.format("%7.5f", object);
              }
          });
       
          final LineChart<Number, Number> lineChart = new LineChart<Number, Number>(xAxis, yAxis);
       
          //lineChart.setTitle("Stock quotes");
          lineChart.setCreateSymbols(false);
          lineChart.setAlternativeRowFillVisible(false);
          lineChart.setAnimated(true);
       
          XYChart.Series series1 = new XYChart.Series();
          //series1.setName("Stock 1");
          series1.getData().add(new XYChart.Data(1, 0.53185));
          series1.getData().add(new XYChart.Data(2, 0.532235));
          series1.getData().add(new XYChart.Data(3, 0.53234));
          series1.getData().add(new XYChart.Data(4, 0.538765));
          series1.getData().add(new XYChart.Data(5, 0.53442));
          series1.getData().add(new XYChart.Data(6, 0.534658));
          series1.getData().add(new XYChart.Data(7, 0.53023));
          series1.getData().add(new XYChart.Data(8, 0.53001));
          series1.getData().add(new XYChart.Data(9, 0.53589));
          series1.getData().add(new XYChart.Data(10, 0.53476));
          series1.getData().add(new XYChart.Data(11, 0.530123));
          series1.getData().add(new XYChart.Data(12, 0.53035));
       
       
          pane = new BorderPane();
          pane.setCenter(lineChart);
          //Scene scene = new Scene(lineChart, 800, 600);
          Scene scene = new Scene(pane, 800, 600);
          lineChart.getData().addAll(series1);
           
          initXLowerBound = ((NumberAxis) lineChart.getXAxis()).getLowerBound();
          initXUpperBound = ((NumberAxis) lineChart.getXAxis()).getUpperBound();
          initYLowerBound = ((NumberAxis) lineChart.getYAxis()).getLowerBound();
          initYUpperBound = ((NumberAxis) lineChart.getYAxis()).getUpperBound();
       
          stage.setScene(scene);        
           
          path = new Path();
          path.setStrokeWidth(1);
          path.setStroke(Color.BLACK);
       
          scene.setOnMouseClicked(mouseHandler);
          scene.setOnMouseDragged(mouseHandler);
          scene.setOnMouseEntered(mouseHandler);
          scene.setOnMouseExited(mouseHandler);
          scene.setOnMouseMoved(mouseHandler);
          scene.setOnMousePressed(mouseHandler);
          scene.setOnMouseReleased(mouseHandler);
       
          //root.getChildren().add(lineChart);
          pane.getChildren().add(path);
       
          rect = new Rectangle();
          rect.setFill(Color.web("blue", 0.1));
          rect.setStroke(Color.BLUE);
          rect.setStrokeDashOffset(50);
       
          rect.widthProperty().bind(rectX.subtract(rectinitX));
          rect.heightProperty().bind(rectY.subtract(rectinitY));
          pane.getChildren().add(rect);
       
          stage.show();
      }
       
      EventHandler<MouseEvent> mouseHandler = new EventHandler<MouseEvent>() {
       
          @Override
          public void handle(MouseEvent mouseEvent) {
              if (mouseEvent.getButton() == MouseButton.PRIMARY)
              {
                      if (mouseEvent.getEventType() == MouseEvent.MOUSE_PRESSED) {
                          rect.setX(mouseEvent.getX());
                          rect.setY(mouseEvent.getY());
                          rectinitX.set(mouseEvent.getX());
                          rectinitY.set(mouseEvent.getY());
                      } else if (mouseEvent.getEventType() == MouseEvent.MOUSE_DRAGGED) {
                          rectX.set(mouseEvent.getX());
                          rectY.set(mouseEvent.getY());
                      } else if (mouseEvent.getEventType() == MouseEvent.MOUSE_RELEASED) {
       
                          if ((rectinitX.get() >= rectX.get())&&(rectinitY.get() >= rectY.get())){
       
                              LineChart<Number, Number> lineChart = (LineChart<Number, Number>) pane.getCenter();
       
                              ((NumberAxis) lineChart.getXAxis()).setLowerBound(initXLowerBound);
                              ((NumberAxis) lineChart.getXAxis()).setUpperBound(initXUpperBound);
       
                              ((NumberAxis) lineChart.getYAxis()).setLowerBound(initYLowerBound);
                              ((NumberAxis) lineChart.getYAxis()).setUpperBound(initYUpperBound);
                          }
                          else{
                              //Zoom In
                              double Tgap = 0;
                              double newLowerBound, newUpperBound, axisShift;
                              
                              LineChart<Number, Number> lineChart = (LineChart<Number, Number>) pane.getCenter();
                              // Zoom in Y-axis by changing bound range.            
                              NumberAxis yAxis = (NumberAxis) lineChart.getYAxis();
                              Tgap = yAxis.getHeight()/(yAxis.getUpperBound() - yAxis.getLowerBound());
                              axisShift = getSceneShiftY(yAxis);
                              newUpperBound = yAxis.getUpperBound() - ((rectinitY.get() - axisShift) / Tgap);
                              newLowerBound = yAxis.getUpperBound() - (( rectY.get() - axisShift) / Tgap);
       
                              if (newUpperBound > yAxis.getUpperBound())
                                  newUpperBound = yAxis.getUpperBound();
       
                              yAxis.setLowerBound(newLowerBound);
                              yAxis.setUpperBound(newUpperBound);
       
                              NumberAxis xAxis = (NumberAxis) lineChart.getXAxis();
       
                              Tgap = xAxis.getWidth()/(xAxis.getUpperBound() - xAxis.getLowerBound());            
                              axisShift = getSceneShiftX(xAxis);            
       
                              newLowerBound = ((rectinitX.get() - axisShift) / Tgap) + xAxis.getLowerBound();
                              newUpperBound = ((rectX.get() - axisShift) / Tgap) + xAxis.getLowerBound();                
       
                              if (newUpperBound > xAxis.getUpperBound())
                                  newUpperBound = xAxis.getUpperBound();
       
                              xAxis.setLowerBound( newLowerBound );
                              xAxis.setUpperBound( newUpperBound );
       
                          }
                          // Hide the rectangle
                          rectX.set(0);
                          rectY.set(0);
                      }
              }// end if (mouseEvent.getButton() == MouseButton.PRIMARY)
              else if (mouseEvent.getButton() == MouseButton.SECONDARY) //free hand graphics
              {
                  if(mouseEvent.getEventType() == MouseEvent.MOUSE_PRESSED){
                      path.getElements().clear();
                      path.getElements().add(new MoveTo(mouseEvent.getX(), mouseEvent.getY()));
                  }
                  else if(mouseEvent.getEventType()==MouseEvent.MOUSE_DRAGGED){
                      path.getElements().add(new LineTo(mouseEvent.getX(), mouseEvent.getY()));
                  }
              } //end if (mouseEvent.getButton() == MouseButton.SECONDARY)
          }
         };
      private static double getSceneShiftX(Node node) {
          double shift = 0;
          do { 
              shift += node.getLayoutX(); 
              node = node.getParent();
          } while (node != null);
          return shift;
      }
      private static double getSceneShiftY(Node node) {
          double shift = 0;
          do { 
              shift += node.getLayoutY(); 
              node = node.getParent();
          } while (node != null);
          return shift;
      }
       
          public static void main(String[] args) {
              launch(args);
          }
           
           
      }...
      Any help really appreciated.

      Susie

      PS. Sorry I pressed twice the submit button don't know how to remove one.

      Edited by: 932518 on 7-mag-2012 6.26