2013-03-25 2 views
7

데이터가 동적으로 삽입되는 JavaFX를 사용하여 시리즈 차트를 작성하려고합니다.JavaFX 차트에 값 표시자를 추가하는 방법은 무엇입니까?

새 값이 삽입 될 때마다이 값이 지금까지 최고 값인지 확인하고 싶으면이 값이 최대 값임을 나타내는 가로선을 그려야합니다.

JFree 차트에서는 ValueMarker를 사용했지만 JavaFX에서도 동일한 작업을 수행하려고합니다.

Line 개체를 사용해 보았지만 Chart 값을 제공 할 수 없기 때문에 분명히 같지 않습니다. Windows에서 상대적인 픽셀 위치를 취합니다.

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

어떤 제안 : 여기

내가 달성하고자하는 차트의 스크린 샷이다? 감사합니다.

답변

14

차트 값을 픽셀로 변환하려면 NumberAxis#getDisplayPosition() 메서드를 사용하면 차트 노드의 실제 좌표가 반환됩니다.

이 좌표는 다음 코드에 의해 찾을 수 영역, 차트를 기준으로하지만 :

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

참고이 장면들에 어떤 좌표를 변환 할 수 있습니다 localToScene() 방법. 따라서이를 사용하여 값 마커 좌표를 업데이트 할 수 있습니다. 장면이 표시된 후 localToScene 전화를 걸 었는지 확인하십시오.

참조 샘플 프로그램은 아래 다음 차트를 생산 : // 유래 :

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 좋은 dirtyness BTW – kleopatra

+0

:-), 크기 조정 부모 HTTP에 대처하기 위해 약간의 코드를 변경했습니다. co.kr/a/24403761/203657 – kleopatra

+0

@kleopatra, thanks! 그러나 왜 더러움? :) –

관련 문제