Я предполагаю, что цель состоит в том, чтобы нарисовать фигуру, используя систему координат, определенную осями диаграммы.
Самый простой способ - это преобразовать форму вместо оси. Для этого вы можете создать служебный метод:
private Transform chartDisplayTransform(NumberAxis xAxis, NumberAxis yAxis) {
return new Affine(
xAxis.getScale(), 0, xAxis.getDisplayPosition(0),
0, yAxis.getScale(), yAxis.getDisplayPosition(0)
);
}
Еще одно замечание о вашем коде: метод layoutPlotChildren()
не обязательно удаляет узлы, поэтому вы можете добавить больше прямоугольников, чем ожидаете, с помощью код вы разместили.
Вот версия вашего кода, которая использует этот метод (и гарантирует, что прямоугольник добавляется только один раз).
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.transform.Affine;
import javafx.scene.transform.Transform;
import javafx.stage.Stage;
public class FlippedExampleChart extends Application {
private LineChart<Number, Number> chart;
@Override
public void start(Stage primaryStage) throws Exception {
final NumberAxis xAxis = new NumberAxis();
final NumberAxis yAxis = new NumberAxis();
// Flip the axis
// yAxis.setScaleY(-1);
Rectangle r = new Rectangle(0, 0, 50, 100);
r.setFill(Color.GREEN);
this.chart = new LineChart<Number, Number>(xAxis, yAxis) {
@Override
public void layoutPlotChildren() {
super.layoutPlotChildren();
r.getTransforms().setAll(chartDisplayTransform(xAxis, yAxis));
// note nodes don't get removed from the plot children, and this method may be
// called often:
if (!getPlotChildren().contains(r)) {
getPlotChildren().add(r);
}
}
};
this.chart.setAnimated(false);
VBox vbox = new VBox(this.chart);
Scene scene = new Scene(vbox, 400, 200);
primaryStage.setScene(scene);
primaryStage.setHeight(600);
primaryStage.setWidth(400);
primaryStage.show();
}
private Transform chartDisplayTransform(NumberAxis xAxis, NumberAxis yAxis) {
return new Affine(xAxis.getScale(), 0, xAxis.getDisplayPosition(0), 0, yAxis.getScale(),
yAxis.getDisplayPosition(0));
}
public static void main(String[] args) {
Application.launch(args);
}
}
И результат:
Если у вас есть несколько узлов для обработки таким образом, стратегия состоит в том, чтобы добавить их Group
и примените преобразование к Group
:
@Override
public void start(Stage primaryStage) throws Exception {
final NumberAxis xAxis = new NumberAxis();
final NumberAxis yAxis = new NumberAxis();
Group extraNodes = new Group();
this.chart = new LineChart<Number, Number>(xAxis, yAxis) {
@Override
public void layoutPlotChildren() {
super.layoutPlotChildren();
Rectangle r1 = new Rectangle(0, 0, 50, 100);
r1.setFill(Color.GREEN);
Rectangle r2 = new Rectangle(70, 0, 30, 20);
r2.setFill(Color.AQUAMARINE);
extraNodes.getChildren().setAll(r1, r2);
extraNodes.getTransforms().setAll(chartDisplayTransform(xAxis, yAxis));
// note nodes don't get removed from the plot children, and this method may be
// called often:
if (!getPlotChildren().contains(extraNodes)) {
getPlotChildren().add(extraNodes);
}
}
};
this.chart.setAnimated(false);
VBox vbox = new VBox(this.chart);
Scene scene = new Scene(vbox, 400, 200);
primaryStage.setScene(scene);
primaryStage.setHeight(600);
primaryStage.setWidth(400);
primaryStage.show();
}
Также см. этот связанный вопрос