2013-03-25 42 views
7

Tôi đang cố gắng xây dựng một biểu đồ chuỗi sử dụng JavaFX, nơi dữ liệu được chèn động.Cách thêm điểm đánh dấu giá trị vào biểu đồ JavaFX?

Mỗi lần nhập giá trị mới, tôi muốn kiểm tra xem đây có phải là giá trị cao nhất cho đến giờ không, và nếu có, tôi muốn vẽ một đường ngang để cho biết đây là giá trị lớn nhất.

Trong biểu đồ JFree, tôi đã sử dụng ValueMarker, nhưng tôi đang cố gắng thực hiện tương tự với JavaFX.

Tôi đã thử sử dụng đối tượng Đường kẻ, nhưng chắc chắn không giống nhau, bởi vì tôi không thể cung cấp giá trị Biểu đồ, nó chiếm vị trí pixel tương đối trong cửa sổ.

Dưới đây là ảnh chụp màn hình của biểu đồ tôi muốn đạt được:

http://postimg.org/image/s5fkupsuz/

Bất kỳ lời đề nghị? Cảm ơn bạn.

Trả lời

14

Để chuyển đổi giá trị biểu đồ thành pixel, bạn có thể sử dụng phương thức NumberAxis#getDisplayPosition() trả về tọa độ thực tế của các nút biểu đồ.

Mặc dù các tọa độ có liên quan đến biểu đồ khu vực, mà bạn có thể tìm hiểu bằng cách mã tiếp theo:

Node chartArea = chart.lookup(".chart-plot-background"); 
Bounds chartAreaBounds = chartArea.localToScene(chartArea.getBoundsInLocal()); 

Note localToScene() phương pháp cho phép bạn chuyển đổi bất kỳ tọa độ cho những người Scene. Vì vậy, bạn có thể sử dụng chúng để cập nhật tọa độ điểm đánh dấu giá trị của bạn. Đảm bảo bạn thực hiện cuộc gọi localToScene sau khi Cảnh của bạn được hiển thị.

chương trình mẫu Xem dưới đây trong đó sản xuất bảng xếp hạng tiếp theo:

enter image description here

public class LineChartValueMarker extends Application { 

    private Line valueMarker = new Line(); 
    private XYChart.Series<Number, Number> series = new XYChart.Series<>(); 
    private NumberAxis yAxis; 
    private double yShift; 

    private void updateMarker() { 
     // find maximal y value 
     double max = 0; 
     for (Data<Number, Number> value : series.getData()) { 
      double y = value.getYValue().doubleValue(); 
      if (y > max) { 
       max = y; 
      } 
     } 
     // find pixel position of that value 
     double displayPosition = yAxis.getDisplayPosition(max); 
     // update marker 
     valueMarker.setStartY(yShift + displayPosition); 
     valueMarker.setEndY(yShift + displayPosition); 
    } 

    @Override 
    public void start(Stage stage) { 
     LineChart<Number, Number> chart = new LineChart<>(new NumberAxis(0, 100, 10), yAxis = new NumberAxis(0, 100, 10)); 

     series.getData().add(new XYChart.Data(0, 0)); 
     series.getData().add(new XYChart.Data(10, 20)); 

     chart.getData().addAll(series); 
     Pane pane = new Pane(); 
     pane.getChildren().addAll(chart, valueMarker); 
     Scene scene = new Scene(pane); 

     // add new value on mouseclick for testing 
     chart.setOnMouseClicked(new EventHandler<MouseEvent>() { 
      @Override 
      public void handle(MouseEvent t) { 
       series.getData().add(new XYChart.Data(series.getData().size() * 10, 30 + 50 * new Random().nextDouble())); 
       updateMarker(); 
      } 
     }); 

     stage.setScene(scene); 
     stage.show(); 

     // find chart area Node 
     Node chartArea = chart.lookup(".chart-plot-background"); 
     Bounds chartAreaBounds = chartArea.localToScene(chartArea.getBoundsInLocal()); 
     // remember scene position of chart area 
     yShift = chartAreaBounds.getMinY(); 
     // set x parameters of the valueMarker to chart area bounds 
     valueMarker.setStartX(chartAreaBounds.getMinX()); 
     valueMarker.setEndX(chartAreaBounds.getMaxX()); 
     updateMarker(); 
    } 

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

+1 đẹp dirtyness :-) – kleopatra

+0

btw, thay đổi mã của bạn một chút để đối phó với bố mẹ thay đổi kích thước http: // stackoverflow. com/a/24403761/203657 – kleopatra

+0

@kleopatra, cảm ơn! Nhưng tại sao bẩn? :) –

Các vấn đề liên quan