簡體   English   中英

移動並設置折線圖中的XYChart.Data節點的值

[英]Move and set the value of a XYChart.Data node in line chart

我希望有一個交互式折線圖,使我可以移動和設置圖表上點的基礎值。 在XYChart.Data點的節點上添加一個鼠標事件ondragged處理程序,應該可以執行此操作,但是我需要能夠將鼠標事件位置轉換為該點的參考軸框架。 使用以下內容;

xAxis.getValueForDisplay(event.getX()).doubleValue();

其中xAxis是折線圖的數字軸,不適用於應用於XYChart.Data點的鼠標事件(在圖表背景的節點上使用此方法時會起作用)。 下面是我的代碼;

package com.jtech;

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.chart.Axis;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.input.MouseEvent;
import javafx.stage.Stage;

public class MovePoint extends Application {

    class MouseHandler implements EventHandler<MouseEvent> {
        private XYChart.Data data;
        private Axis<Number> xAxis, yAxis;

        public MouseHandler(XYChart.Data data, Axis<Number> xAxis, Axis<Number> yAxis) {
            this.data=data;
            this.xAxis=xAxis;
            this.yAxis=yAxis;
        }

        @Override
        public void handle(MouseEvent event) {
            //we want these in the axis coordinate frame
            double x =  xAxis.getValueForDisplay(event.getX()).doubleValue();
            double y =  yAxis.getValueForDisplay(event.getY()).doubleValue();

            if (event.getEventType() == MouseEvent.MOUSE_DRAGGED) {
                System.out.println(String.format("(%.2f,%.2f)",x,y));
                //data.setXValue(x);
                //data.setYValue(y);
            }
        }
    }

    @Override
    public void start(Stage stage) {
        final NumberAxis xAxis = new NumberAxis(0,6,1);
        final NumberAxis yAxis = new NumberAxis(0,10,2);

        final LineChart<Number, Number> lineChart = new LineChart<>(xAxis, yAxis);
        lineChart.setTitle("Point moving example");
        XYChart.Series series = new XYChart.Series();

        final XYChart.Data d1 = new XYChart.Data(0.0, 0.0);
        final XYChart.Data d2 = new XYChart.Data(0.5, 2.0);
        final XYChart.Data d3 = new XYChart.Data(2.0, 2.5);
        final XYChart.Data d4 = new XYChart.Data(3.5, 3.5);
        final XYChart.Data d5 = new XYChart.Data(5.0, 8.0);

        series.getData().addAll(d1,d2,d3,d4,d5);
        lineChart.getData().add(series);
        lineChart.setLegendVisible(false);

        final Scene scene = new Scene(lineChart, 400, 300);
        stage.setScene(scene);
        stage.show();

        registerNode(d1,xAxis, yAxis);
        registerNode(d2,xAxis, yAxis);
        registerNode(d3,xAxis, yAxis);
        registerNode(d4,xAxis, yAxis);
        registerNode(d5,xAxis, yAxis);
    }

    private void registerNode(XYChart.Data data, Axis<Number> xAxis, Axis<Number> yAxis) {
        final Node node = data.getNode();
        node.setOnMouseDragged(new MouseHandler(data,xAxis,yAxis));
    }

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

實現這一目標的正確方法是什么? 我已經看到了一些轉換實際節點的示例,但我很想知道是否可以通過直接設置數據的實際X,Y值來做到這一點。

這似乎完全有可能:

import javafx.application.Application;
import javafx.application.Platform;
import javafx.geometry.Point2D;
import javafx.scene.Cursor;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.chart.XYChart.Data;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

public class DraggingLineChartSample extends Application {

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Line Chart Sample");
        //defining the axes
        final NumberAxis xAxis = new NumberAxis(0, 12, 1);
        final NumberAxis yAxis = new NumberAxis(0, 50, 5);
        xAxis.setLabel("Number of Month");
        //creating the chart
        final LineChart<Number,Number> lineChart = 
                new LineChart<Number,Number>(xAxis,yAxis);

        lineChart.setTitle("Stock Monitoring, 2010");

        lineChart.setAnimated(false);

        //defining a series
        XYChart.Series<Number, Number> series = new XYChart.Series<>();
        series.setName("My portfolio");
        //populating the series with data
        series.getData().add(new XYChart.Data<>(1, 23));
        series.getData().add(new XYChart.Data<>(2, 14));
        series.getData().add(new XYChart.Data<>(3, 15));
        series.getData().add(new XYChart.Data<>(4, 24));
        series.getData().add(new XYChart.Data<>(5, 34));
        series.getData().add(new XYChart.Data<>(6, 36));
        series.getData().add(new XYChart.Data<>(7, 22));
        series.getData().add(new XYChart.Data<>(8, 45));
        series.getData().add(new XYChart.Data<>(9, 43));
        series.getData().add(new XYChart.Data<>(10, 17));
        series.getData().add(new XYChart.Data<>(11, 29));
        series.getData().add(new XYChart.Data<>(12, 25));        

        Scene scene  = new Scene(new BorderPane(lineChart),800,600);
        lineChart.getData().add(series);

        for (Data<Number, Number> data : series.getData()) {
            Node node = data.getNode() ;
            node.setCursor(Cursor.HAND);
            node.setOnMouseDragged(e -> {
                Point2D pointInScene = new Point2D(e.getSceneX(), e.getSceneY());
                double xAxisLoc = xAxis.sceneToLocal(pointInScene).getX();
                double yAxisLoc = yAxis.sceneToLocal(pointInScene).getY();
                Number x = xAxis.getValueForDisplay(xAxisLoc);
                Number y = yAxis.getValueForDisplay(yAxisLoc);
                data.setXValue(x);
                data.setYValue(y);
            });
        }


        primaryStage.setScene(scene);
        primaryStage.show();
    }

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM