2016-11-21 84 views
4

好吧,你所有的專家外匯偷看那裏。我需要一些幫助,在AreaChart的100刻度標記處添加一條黑線。JavaFX面積圖100%線

enter image description here

你可以通過圖片那裏是100線我需要一個線跨片去告訴大家,無論他們是在100%的生產或看不到。 100的位置可以從任何給定的星期改變。有時最高價值不會是170,但可能是150左右。我目前的代碼如下,但它只是測試了這一點(它也不能正常工作)。

@Override 
protected void layoutPlotChildren() { 
    super.layoutPlotChildren(); 
    ObservableList<Node> removeable = FXCollections.observableArrayList(); 
    removeable.addAll(getPlotChildren().stream().filter(node -> node instanceof Line).collect(Collectors.toList())); 
    getPlotChildren().removeAll(removeable); 
    Double y = Double.valueOf(getYAxis().getValueForDisplay(100.0).toString()); 
    System.out.println(y); 
    Line line = new Line(); 
    line.setStartX(0.0); 
    line.setStartY(y); 
    line.setEndX(600.0); 
    line.setEndY(y); 
    getPlotChildren().add(line); 
} 

圖表行並沒有被放置在正確的垂直位置(我很清楚我的行沒有走到最後,這只是一個測試)。

enter image description here

好奇,什麼問題是在這裏,究竟是什麼

getYAxis().getValueForDisplay(100.0) 

在做什麼。

+0

雖然通常會執行'double y = getYAxis()。getValueForDisplay(100.0)',它看起來應該可以工作,而不是轉換爲字符串,以便將其轉換回double。您可以將示例擴展到[MCVE]嗎? –

+0

getYAxis()。getValueForDisplay(100.0)返回一個Y類型的FX對象.Y是你的Axis(在我的情況下它是一個NumberAxis)。沒有任何轉換將它轉換爲double(我總是看到),所以我將它轉換爲一個字符串(每當你打印Y時它打印一個看起來像雙精度的數字),然後轉換爲double。關於這個例子,我們將看到我今天離開工作時能做些什麼。 –

+0

哦,我明白了。你想'getDisplayPosition'。您將像素座標ls轉換爲軸值,而不是軸像素座標。 –

回答

1

Example

我已經在過去不同的解決了這個問題。我使用未修改的圖表,而是將組件添加到「.chart-content」窗格。然後使用座標變換將它們對齊到「.plot-area」組件。這是這種方法的一個完全有效的例子。

public class Horse extends Application { 

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

    private Line line; 
    private NumberAxis yAxis; 
    private Region plotArea; 
    private Pane chartContent; 

    @Override 
    public void start(Stage primaryStage) throws Exception { 
     final CategoryAxis xAxis = new CategoryAxis(); 
     yAxis = new NumberAxis(); 
     final AreaChart<String, Number> chart = new AreaChart<String, Number>(xAxis, yAxis); 
     Series<String, Number> series = new Series<>(); 
     series.getData().add(new Data<>("foo", 50)); 
     series.getData().add(new Data<>("bar", 25)); 
     series.getData().add(new Data<>("baz", 125)); 

     chart.getData().add(series); 

     plotArea = (Region) chart.lookup(".chart-plot-background"); 
     chartContent = (Pane) chart.lookup(".chart-content"); 
     line = new Line(); 
     chartContent.getChildren().add(line); 
     primaryStage.setScene(new Scene(chart)); 
     primaryStage.show(); 

     chart.boundsInParentProperty().addListener((obs, oldValue, newValue) -> { 
      update(); 
     }); 
     plotArea.boundsInLocalProperty().addListener((obs, oldValue, newValue) -> { 
      update(); 
     }); 
     update(); 

    } 

    private void update() { 
     double location = yAxis.getDisplayPosition(100); 
     Point2D a = plotArea.localToScene(new Point2D(0, location)); 
     Point2D b = plotArea.localToScene(new Point2D(plotArea.getWidth(), location)); 

     Point2D aTrans = chartContent.sceneToLocal(a); 
     Point2D bTrans = chartContent.sceneToLocal(b); 

     line.setStartX(aTrans.getX()); 
     line.setStartY(aTrans.getY()); 
     line.setEndX(bTrans.getX()); 
     line.setEndY(bTrans.getY()); 
    } 

} 
+0

謝謝亞當我感謝你的迴應。我實際上忽略了「getDisplayPosition」,這正是我需要這個工作。 –

1

您正在使用getValueForDisplay()將像素值轉換爲軸值。您想要使用getDisplayPosition()將軸值轉換爲像素值。

替換

Double y = Double.valueOf(getYAxis().getValueForDisplay(100.0).toString()); 

double y = getYAxis().getDisplayPosition(100.0); 

SSCCE:

import java.util.Random; 
import java.util.stream.Collectors; 

import javafx.application.Application; 
import javafx.collections.FXCollections; 
import javafx.collections.ObservableList; 
import javafx.scene.Node; 
import javafx.scene.Scene; 
import javafx.scene.chart.CategoryAxis; 
import javafx.scene.chart.LineChart; 
import javafx.scene.chart.NumberAxis; 
import javafx.scene.chart.XYChart.Data; 
import javafx.scene.chart.XYChart.Series; 
import javafx.scene.shape.Line; 
import javafx.stage.Stage; 

public class LineChartWithHorizontal extends Application { 

    @Override 
    public void start(Stage primaryStage) { 
     LineChart<String, Number> chart = new LineChart<String, Number>(new CategoryAxis(), new NumberAxis()) { 

//   Line line = new Line(); 
//   
//   @Override 
//   protected void layoutPlotChildren() { 
//    super.layoutPlotChildren(); 
//    getPlotChildren().remove(line); 
//    line.setStartX(0); 
//    line.setEndX(600); 
//    double y = getYAxis().getDisplayPosition(100.0); 
//    line.setStartY(y); 
//    line.setEndY(y); 
//    getPlotChildren().add(line); 
//   } 

      @Override 
      protected void layoutPlotChildren() { 
       super.layoutPlotChildren(); 
       ObservableList<Node> removeable = FXCollections.observableArrayList(); 
       removeable.addAll(getPlotChildren().stream().filter(node -> node instanceof Line).collect(Collectors.toList())); 
       getPlotChildren().removeAll(removeable); 
       double y = getYAxis().getDisplayPosition(100.0); 
       System.out.println(y); 
       Line line = new Line(); 
       line.setStartX(0.0); 
       line.setStartY(y); 
       line.setEndX(600.0); 
       line.setEndY(y); 
       getPlotChildren().add(line); 
      } 
     }; 

     Random rng = new Random(); 
     for (int i = 1 ; i <= 4; i++) { 
      Series<String, Number> s = new Series<>(); 
      s.setName("Data "+i); 
      chart.getData().add(s); 
     } 
     for (int i = 1 ; i <= 6; i++) { 
      for (int s = 0 ; s < 4 ; s++) { 
       chart.getData().get(s).getData().add(new Data<>("Item "+i, rng.nextDouble()*200)); 
      } 
     } 

     primaryStage.setScene(new Scene(chart, 600, 600)); 
     primaryStage.show(); 
    } 

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

更自然(我,反正)在註釋的代碼中所示的方法。

+0

是的,我通過閱讀每個人的帖子發現了。謝謝你的幫助,這個問題已經完成(最後)。我的問題與你的代碼有點不同,因爲我爲AreaChart創建了一個單獨的類,並且需要泛型參數(而不是字符串和數字),因爲我將它用於多個圖表,但我只是簡單地將yAxis轉換爲NumberAxis圖表只。關於最小的,完整的驗證示例,我的項目非常複雜,我不習慣需要幫助,所以我不確定如何發佈完整的代碼示例。 –