JavaFX 图表是一段邪恶的代码。只有当您确切了解背后的代码库时,才能进行适应,这在某种程度上违背了信息隐藏的良好原则。在BubbleChart 中弄圆气泡就是其中一种改编。
您可以做的最简单的事情是继承BubbleChart 并创建自己的圆形气泡。
不起作用的事情:
创建数据节点的地方(方法createBubble)是私有的,所以你不能覆盖它来创建Circles。 (除此之外 - 即使你有一个自定义数据节点,它也不会工作,因为BubbleChart 中的布局代码会忽略所有不是Ellipse 类型的数据节点,所以你最终会有圆形气泡但是都在位置 (0/0)...)。
接下来想到的是覆盖设置省略号轴的位置。但是不,所有布局代码都是一个方法 - 没有为每个节点调用的 layoutNode(Node)-方法,您可以覆盖它以添加自定义布局代码。
解决方案:
所以你必须重写方法layoutPlotChildren,调用基础实现,然后改变所有节点的Y半径:
public class CircularBubbleChart<X, Y> extends BubbleChart<X, Y> {
public CircularBubbleChart(Axis<X> xAxis, Axis<Y> yAxis) {
super(xAxis, yAxis);
}
public CircularBubbleChart(Axis<X> xAxis, Axis<Y> yAxis, ObservableList<Series<X, Y>> data) {
super(xAxis, yAxis, data);
}
@Override
protected void layoutPlotChildren() {
super.layoutPlotChildren();
getData().stream().flatMap(series -> series.getData().stream())
.map(Data::getNode)
.map(StackPane.class::cast)
.map(StackPane::getShape)
.map(Ellipse.class::cast)
.forEach(ellipse -> ellipse.setRadiusY(ellipse.getRadiusX()));
}
}
使用很简单:只需将图表创建代码行从... = new BubbleChart() 更改为... = new CircularBubbleChart()。其他一切都保持不变。
注意:此代码将 Y 半径更改为等于 X 半径,因此气泡半径将以 X 轴为单位。当然,你也可以反方向得到一个气泡半径,以Y轴为单位。