2016-11-21 2 views
4

あなたのエキスパートFXがそこを覗いています。 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); 
} 

グラフの行が右の垂直位置に配置されていません(これは単なるテストにすぎません)。問題はここにあり、まさに

getYAxis().getValueForDisplay(100.0) 

何が何をしているかについての好奇心

enter image description here

+0

これはうまくいくはずですが、通常はdouble型に戻すことができるように文字列に変換するのではなく、 'double y = getYAxis()。getValueForDisplay(100.0)'を実行します。この例を[MCVE]に拡張できますか? –

+0

getYAxis()。getValueForDisplay(100.0)は、Y型のFXオブジェクトを返します.YはAxisです(私の場合はNumberAxisです)。 (私がとにかく見た)ダブルに変換するための変換はありませんので、文字列に変換します(Yを印刷するたびにdoubleのような数字が出力されます)。そしてdoubleに変換されます。今日の仕事を辞めたときに私ができることを見ていきます。 –

+0

ああ、私はそれを参照してください。 'getDisplayPosition'が必要です。ピクセル値をピクセル値に変換するのではなく、ピクセル座標値を軸値に変換しています。 –

答えて

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 = getYAxis().getDisplayPosition(100.0); 

SSCCEと

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

を交換:

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のために別のクラスを作成し、(StringとNumberの代わりに)ジェネリックパラメータを必要としたためです。チャートのみ。また、最小限で完全な検証済みのサンプルについては、私のプロジェクトは非常に複雑で、ヘルプが必要ないので、完全なコード例を投稿する方法がわからなかった。 –

関連する問題