Philip Vaughn Philip Vaughn - 12 days ago 5
Java Question

JavaFX Area Chart 100% line

Ok all you expert FX peeps out there. I need some help adding a dark line at the 100 tick mark spot on an AreaChart.

enter image description here

As you can see by the picture there at that 100 mark I need a line to go across the sheet to tell everyone whether they're at 100% production or not. The position of that 100 can change from any given week. Sometimes the top value will not be 170 but maybe 150 or so. My current code is as follows but it's just testing this out (and it's also not working correctly).

@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);
}


The chart line is not being placed in the right vertical position (I'm well aware my line doesn't go to the end this is just a test).

enter image description here

Curious as to what the issue is here and what exactly

getYAxis().getValueForDisplay(100.0)


is doing.

Answer

Example

I've solved this issue differently in the past. I used the charts unmodified, and instead added components to the ".chart-content" Pane. These are then aligned to the ".plot-area" component using co-ordinate transforms. This is a fully working example of this approach.

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());
    }

}
Comments