下面的代码绘制了一个 XYLineChart:通过鼠标左键单击并拖动绘制的线可以向左/向右平移。

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.input.MouseEvent;  
import javafx.scene.layout.BorderPane; 
enter code here 
 
 
public class GridMove 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(1, 12, 1); 
        final NumberAxis yAxis = new NumberAxis(0.53000, 0.53910, 0.0005); 
 
        xAxis.setAnimated(false); 
        yAxis.setAnimated(false); 
 
        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(false); 
        lineChart.setLegendVisible(false); 
 
        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)); 
 
        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 = xAxis.getLowerBound() - Delta; 
                        newXupper = xAxis.getUpperBound() - Delta; 
                    } else if (rectinitX.get() > mouseEvent.getX()) { 
                        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) 现在通过向左/向右移动 Line,Grid 和 X Ticks 不会移动:那么,如何一起平移 Line、Grid 和 X Ticks?

2) 是否可以在 JavaFx 2 中完成此操作?

谢谢

编辑 没人愿意帮忙吗?

编辑 2:添加了导入语句

编辑 3:代码改进,现在网格和线一起移动。只需要沿着线和网格移动 X 轴刻度,并且垂直网格线在线范围值之外丢失
import java.util.Set; 
import javafx.application.Application;  
import javafx.beans.property.DoubleProperty; 
import javafx.beans.property.SimpleDoubleProperty;  
import javafx.collections.ObservableList; 
import javafx.event.EventHandler;   
import javafx.scene.chart.Axis; 
import javafx.scene.chart.NumberAxis;  
import javafx.scene.chart.XYChart;  
import javafx.scene.chart.XYChart.Series; 
import javafx.stage.Stage;  
import javafx.scene.Node; 
import javafx.scene.Scene;  
import javafx.scene.chart.LineChart;  
import javafx.scene.input.MouseEvent;  
import javafx.scene.layout.BorderPane; 
import javafx.scene.shape.LineTo; 
import javafx.scene.shape.MoveTo; 
import javafx.scene.shape.Path; 
 
public class GridMove extends Application { 
 
BorderPane pane; 
 
XYChart.Series series1 = new XYChart.Series(); 
 
SimpleDoubleProperty rectinitX = new SimpleDoubleProperty(); 
SimpleDoubleProperty rectX = new SimpleDoubleProperty(); 
SimpleDoubleProperty rectY = new SimpleDoubleProperty(); 
LineChart<Number, Number> lineChart; 
 
@Override 
public void start(Stage stage) { 
 
    final NumberAxis xAxis = new NumberAxis(1, 12, 1); 
    final NumberAxis yAxis = new NumberAxis(0.53000, 0.53910, 0.0005); 
 
    xAxis.setAnimated(false); 
    yAxis.setAnimated(false); 
 
    yAxis.setTickLabelFormatter(new NumberAxis.DefaultFormatter(yAxis) { 
        @Override 
        public String toString(Number object) { 
            return String.format("%7.5f", object); 
        } 
    }); 
 
    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, 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)); 
 
    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 newXlower = xAxis.getLowerBound(), newXupper = xAxis.getUpperBound(); 
            double Delta = 0.3; 
 
            if (mouseEvent.getEventType() == MouseEvent.MOUSE_DRAGGED) { 
                if (rectinitX.get() < mouseEvent.getX()) { 
                    Delta *= -1;                     
                }  
                newXlower = xAxis.getLowerBound() + Delta; 
                newXupper = xAxis.getUpperBound() + Delta; 
 
                xAxis.setLowerBound(newXlower); 
                xAxis.setUpperBound(newXupper); 
 
                DoubleProperty p1 = xAxis.scaleXProperty(); 
                DoubleProperty p2 = xAxis.translateXProperty(); 
 
                double horizontalValueRange = xAxis.getUpperBound() - xAxis.getLowerBound(); 
                double horizontalWidthPixels = xAxis.getWidth(); 
                //pixels per unit 
                double xScale = horizontalWidthPixels / horizontalValueRange; 
 
                Set<Node> nodes = lineChart.lookupAll(".chart-vertical-grid-lines"); 
                for (Node n: nodes) { 
                    Path p = (Path) n; 
                    double currLayoutX = p.getLayoutX(); 
                    p.setLayoutX(currLayoutX + (Delta*-1) * xScale); 
                }                     
                double lox = xAxis.getLayoutX();                                       
            } 
            rectinitX.set(mouseEvent.getX()); 
        } 
    } 
}; 
public static void main(String[] args) { 
    launch(args); 
} 
} 

非常感谢任何帮助!

请您参考如下方法:

这是一个评论,但不知何故我太新了,无法发表评论。

我会通过将图表嵌入到带有不可见滚动条的 ScrollPane 中并将图表的 y 轴不透明度设置为 0 来解决此问题。如果无法将所有图表数据加载到内存中,则必须管理滚动事件等中的数据获取。

此外,您可以为 y 轴使用独立的 NumberAxis。您必须手动进行适当的缩放和定位。


评论关闭
IT干货网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!