2016-11-21 82 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图表只。关于最小的,完整的验证示例,我的项目非常复杂,我不习惯需要帮助,所以我不确定如何发布完整的代码示例。 –