当前位置:   article > 正文

散点图 计算 java_关于Java:JavaFX中的象限散点图?

javafx chart 4象限

感谢您阅读我的问题。

我目前正在使用JavaFX-8,SceneBuilder和Eclipse。

我想用四个象限制作一个散点图,它有两个固定的数字轴(数据位置无关紧要,我只需要在每个象限上显示点...只关系点在哪个象限中)。每个象限必须具有特定颜色的背景。

我发现了这个问题,因此我尝试扩展ScatterChart,以覆盖方法layoutPlotChildren()。我尝试了一个最小的实现,看它是否可以与我的FXML一起运行(我确实将新组件导入到FXML中)。这是我的最低要求:

public class ScatterQuadrantChart extends ScatterChart {

public ScatterQuadrantChart(Axis xAxis, Axis yAxis) {

super(xAxis, yAxis);

} }

然后,我收到NotSuchMethodError初始化错误。我发现了一个类似的错误,但是有人在这里扩展了LineChart,但是我不太确定自己在课堂上需要做什么。

我尝试添加一个无参数的构造函数,但是我需要调用super和cant,因为我也不能调用" getXAxis()"方法。我该怎么办?

另外,剩下的另一个问题是,一旦我解决了这个问题,layoutPlotChildren()方法应该做什么?

谢谢阅读。

出现问题是因为FXMLLoader实例化类的默认机制是调用无参数构造函数。您的ScatterQuadrantChart没有无参数构造函数,因此NoSuchMethodError。

在Java 8之前,解决此问题的唯一方法是为您的类创建一个构建器类,如您所链接的文章中所述。 JavaFX 8引入了(但未提供文档)一种机制,该机制使用@NamedArg注释为FXMLLoader可以识别的构造函数参数指定值)。

因此,在Java 8中,您可以修改ScatterQuadrantChart:

public class ScatterQuadrantChart extends ScatterChart {

public ScatterQuadrantChart(@NamedArg("xAxis")Axis xAxis,

@NamedArg("yAxis)Axis yAxis) {

super(xAxis, yAxis);

}

}

然后您的FXML看起来像

我不知道SceneBuilder是否或如何与之交互,但是FXML将起作用。

对于实现,您将需要向图中添加一些节点以表示您的象限。我可能只将这些用于普通区域。在构造函数中创建它们,然后调用getPlotChildren().add(...)进行添加。然后在layoutPlotChildren()方法中,首先调用超类方法(它将对散布图节点进行布局),然后调整象限的大小和位置。您可以使用getXAxis().getDisplayPosition(...)从实际的分频器值中找出位置。

在现实生活中,应将样式类添加到象限中,以便可以使用CSS等外部样式,但是一个非常基本的实现可能看起来像

import javafx.beans.NamedArg;

import javafx.beans.property.Property;

import javafx.beans.property.SimpleObjectProperty;

import javafx.beans.value.ChangeListener;

import javafx.scene.chart.Axis;

import javafx.scene.chart.ScatterChart;

import javafx.scene.layout.Region;

public class ScatterQuadrantChart extends ScatterChart {

private final Property xQuadrantDivider = new SimpleObjectProperty<>();

private final Property yQuadrantDivider = new SimpleObjectProperty<>();

private final Region nwQuad ;

private final Region neQuad ;

private final Region swQuad ;

private final Region seQuad ;

public ScatterQuadrantChart(@NamedArg("xAxis") Axis xAxis,

@NamedArg("yAxis") Axis yAxis) {

super(xAxis, yAxis);

nwQuad = new Region();

neQuad = new Region();

swQuad = new Region();

seQuad = new Region();

nwQuad.setStyle("-fx-background-color: lightsalmon ;");

neQuad.setStyle("-fx-background-color: antiquewhite ;");

swQuad.setStyle("-fx-background-color: aqua ;");

seQuad.setStyle("-fx-background-color: lightskyblue ;");

getPlotChildren().addAll(nwQuad, neQuad, swQuad, seQuad);

ChangeListener quadListener = (obs, oldValue, newValue) -> layoutPlotChildren();

xQuadrantDivider.addListener(quadListener);

yQuadrantDivider.addListener(quadListener);

}

@Override

public void layoutPlotChildren() {

super.layoutPlotChildren();

X x = xQuadrantDivider.getValue();

Y y = yQuadrantDivider.getValue();

if (x != null && y != null) {

Axis xAxis = getXAxis();

Axis yAxis = getYAxis();

double xPixels = xAxis.getDisplayPosition(x);

double yPixels = yAxis.getDisplayPosition(y);

double totalWidth = xAxis.getWidth();

double totalHeight = yAxis.getHeight();

nwQuad.resizeRelocate(0, 0, xPixels, yPixels);

swQuad.resizeRelocate(0, yPixels, xPixels, totalHeight - yPixels);

neQuad.resizeRelocate(xPixels, 0, totalWidth - xPixels, yPixels);

seQuad.resizeRelocate(xPixels, yPixels, totalWidth - xPixels, totalHeight - yPixels);

}

}

public final Property xQuadrantDividerProperty() {

return this.xQuadrantDivider;

}

public final X getXQuadrantDivider() {

return this.xQuadrantDividerProperty().getValue();

}

public final void setXQuadrantDivider(final X xQuadrantDivider) {

this.xQuadrantDividerProperty().setValue(xQuadrantDivider);

}

public final Property yQuadrantDividerProperty() {

return this.yQuadrantDivider;

}

public final Y getYQuadrantDivider() {

return this.yQuadrantDividerProperty().getValue();

}

public final void setYQuadrantDivider(final Y yQuadrantDivider) {

this.yQuadrantDividerProperty().setValue(yQuadrantDivider);

}

}

测试代码:

import java.util.Random;

import java.util.stream.Stream;

import javafx.application.Application;

import javafx.scene.Scene;

import javafx.scene.chart.NumberAxis;

import javafx.scene.chart.XYChart.Data;

import javafx.scene.chart.XYChart.Series;

import javafx.scene.layout.BorderPane;

import javafx.stage.Stage;

public class ScatterQuadrantChartTest extends Application {

@Override

public void start(Stage primaryStage) {

final Random rng = new Random();

ScatterQuadrantChart chart = new ScatterQuadrantChart<>(new NumberAxis(), new NumberAxis());

Series series = new Series<>();

for (int i=0; i<20; i++) {

series.getData().add(new Data<>(rng.nextDouble() * 100, rng.nextDouble() * 100));

}

chart.getData().add(series);

chart.setXQuadrantDivider(50);

chart.setYQuadrantDivider(50);

BorderPane root = new BorderPane(chart);

Scene scene = new Scene(root, 600, 600);

primaryStage.setScene(scene);

primaryStage.show();

}

public static void main(String[] args) {

launch(args);

}

}

谢谢@James_D! FXML可以正常工作,并且可以完美加载而不会出错。 我现在遇到的问题是第二个问题:"如何实现" layoutPlotChildren"以绘制彩色背景?

使用示例实现更新了答案。

再次感谢@James_D! 我试过了代码,但象限不可见。 在设置样式类之前,我按原样尝试了代码,并删除了更改点状形状的CSS,以避免出现问题。 但是,这些区域是不可见的。 我尝试替换十六进制代码的颜色,但是它们仍然是透明的。

确保设置xQuadrantDivider和yQuadrantDivider值。 我更新了测试代码。

它像一个魅力! 会把它放到风格上,谢谢!! :D

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/529873
推荐阅读
相关标签
  

闽ICP备14008679号