This discussion is archived
0 Replies Latest reply: Nov 21, 2012 9:38 AM by famedoro RSS

Zoom as axis rescaling

famedoro Newbie
Currently Being Moderated
Hi all,

I would like to zoom in ( no magnify) a selected part of a chart: to zoom I mean a change for axis scale while the image should not be magnified.

I was able to zoom by pixel resolution, but it is not what I would like to achieve: as from these links,
first picture [http://postimage.org/image/ritfwispt/] show a freehand draw by right mouse click and drag, and picture 2 [http://postimage.org/image/kh76iqw87/] shows same freehand draw displaced and magnified once double click and drag with left mouse click.

Does anybody can help me ?
import javafx.application.Application;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.scene.Node;
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.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;


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("Lines 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.setCreateSymbols(false);
    lineChart.setAlternativeRowFillVisible(false);
    lineChart.setAnimated(true);
    lineChart.setLegendVisible(false);

    XYChart.Series series1 = new XYChart.Series();
    
    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(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);

    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()))
                    {
                        //Condizioni Iniziali
                        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);
                        
                        ZoomFreeHand(path, 1.0, 1.0, 0, 0);

                    }
                    else
                    {
                        //Zoom In

                        double Tgap = 0;
                        double newLowerBound, newUpperBound, axisShift;
                        double xScaleFactor, yScaleFactor;
                        double xaxisShift, yaxisShift;
                        //System.out.println("Zoom bounds : [" + rectinitX.get()+", "+rectinitY.get()+"] ["+ rectX.get()+", "+rectY.get()+"]");                
                        //System.out.println("TODO: Determine bound ranges according these zoom coordinates.\n");

                        // TODO: Determine bound ranges according this zoom coordinates.
                        //LineChart<String, Number> lineChart = (LineChart<String, Number>) pane.getCenter();
                        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);
                        yaxisShift = axisShift;
                        
                        newUpperBound = yAxis.getUpperBound() - ((rectinitY.get() - axisShift) / Tgap);
                        newLowerBound = yAxis.getUpperBound() - (( rectY.get() - axisShift) / Tgap);

                       if (newUpperBound > yAxis.getUpperBound())
                            newUpperBound = yAxis.getUpperBound();

                        yScaleFactor = (yAxis.getUpperBound() - yAxis.getLowerBound())/(newUpperBound - newLowerBound);
                        yAxis.setLowerBound(newLowerBound);
                        yAxis.setUpperBound(newUpperBound);

                        // Zoom in X-axis by removing first and last data values.

                        NumberAxis xAxis = (NumberAxis) lineChart.getXAxis();


                        Tgap = xAxis.getWidth()/(xAxis.getUpperBound() - xAxis.getLowerBound());            
                        axisShift = getSceneShiftX(xAxis);                        
                        xaxisShift = axisShift;
                                
                        
                        
                        newLowerBound = ((rectinitX.get() - axisShift) / Tgap) + xAxis.getLowerBound();
                        newUpperBound = ((rectX.get() - axisShift) / Tgap) + xAxis.getLowerBound();                

                        if (newUpperBound > xAxis.getUpperBound())
                            newUpperBound = xAxis.getUpperBound();

                        xScaleFactor = (xAxis.getUpperBound() - xAxis.getLowerBound())/(newUpperBound - newLowerBound);
                        xAxis.setLowerBound( newLowerBound );
                        xAxis.setUpperBound( newUpperBound );


                        ZoomFreeHand(path, xScaleFactor, yScaleFactor, xaxisShift, yaxisShift);
                    }
                    // Hide the rectangle
                    rectX.set(0);
                    rectY.set(0);
                }
        }
        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()));
            }
        } 
    }
   };
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;
}
private static void ZoomFreeHand(Path path, double xScaleFactor, double yScaleFactor, double xaxisShift, double yaxisShift) {    
    path.setScaleX(xScaleFactor);
    path.setScaleY(yScaleFactor);
    path.setTranslateX(xaxisShift);
    path.setTranslateY(yaxisShift);
}

    public static void main(String[] args) {
        launch(args);
    }
    
    
}

Legend

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