如何更改 BubbleChart javafx 中的气泡大小

How to change bubble size in BubbleChart javafx

我正在编写一个 javafx 程序,该程序应该显示 BubbleChart 用于公司分析。 y 轴显示去年的收入,x 轴显示公司经营的细分市场数量。泡沫的半径取决于公司经营的细分市场。

我知道我可以写成"bubble":

new XYChart.Data<Number,Number>(nbrOfMarketSegments, latestYearRevenue, radiusOfBubble);

问题是 y 轴最大值为 100(百万欧元),x 轴最大值为 20,这使得 "bubbles" 非常扁平,就像图片中那样(因为 radiusOfBubble 数字是与最大细分市场数相比大,与最大收入相比小。我的问题是,即使 x 轴和 y 轴具有如此不同的跨度,有没有办法使气泡更像圆形?

BubbleChart

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轴为单位的气泡半径