加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

Javafx 2图表和徒手变焦

发布时间:2020-12-15 00:38:13 所属栏目:Java 来源:网络整理
导读:此代码绘制XYChart并使用鼠标右键单击和拖动的组合执行自由手绘,而用鼠标左键单击并拖动在选定区域执行放大. 我的问题是关于徒手绘制的缩放它总是得到翻译.例如,尝试在拐角处绘制某个地方. 我怎么解决这个问题? public class Zoom extends Application {Pat
此代码绘制XYChart并使用鼠标右键单击和拖动的组合执行自由手绘,而用鼠标左键单击并拖动在选定区域执行放大.

我的问题是关于徒手绘制的缩放它总是得到翻译.例如,尝试在拐角处绘制某个地方.

我怎么解决这个问题?

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

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()))
                {
                    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,0);

                }
                else
                {
                    //Zoom In

                    double Tgap = 0;
                    double newLowerBound,newUpperBound,axisShift;
                    double xScaleFactor,yScaleFactor;
                    double xaxisShift,yaxisShift;

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


                    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) {

double layX,layY;

layX = path.getLayoutX();
layY = path.getLayoutY();
path.setScaleX(xScaleFactor);
path.setScaleY(yScaleFactor);
path.setTranslateX(xaxisShift);
path.setTranslateY(yaxisShift);
  }
  public static void main(String[] args) {
    launch(args);
   }        
  }

我认为值得使用这样的东西:

ObservableList<PathElement> mypathElements = path.getElements();
 for (int i = 0; i < mypathElements.size(); i++) {
   final PathElement element = mypathElements.get(i);
   if (element instanceof MoveTo) {
     final MoveTo move = (MoveTo)element;
     //change move coordinates     
   } else if (element instanceof LineTo) {
   final LineTo line = (LineTo)element;                                    
   //change line coordinates
   }
 }

解决方法

与 Javafx 2 chart resize with freehand draw相同的问题和相同的答案:

看来你的坐标是基于错误的锚点.您需要找到一个包含图形本身的节点,并且只能使用此节点的坐标,而不是轴或场景.

我甚至建议将所有鼠标事件添加到该节点而不是场景,以避免过多的坐标转换.

另一个建议是使用ScenicView工具调查您的应用程序,看看哪些节点有什么坐标并验证您的数学.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读