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

时间:2016-07-27 12:40:57

标签: java javafx bubble-chart

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

我知道我可以写一个“泡沫”:

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

问题是y轴最大值为100(百万欧元),x轴最大值为20,这使得“气泡”非常平坦,如图所示(因为radiusOfBubble数字比较大最大市场细分数量与最大收入相比较小。我的问题是,即使x轴和y轴具有不同的跨度,有没有办法让气泡更像圆圈?

BubbleChart

1 个答案:

答案 0 :(得分:5)

JavaFX图表是一段邪恶的代码。只有在您完全了解背后的代码库时才能实现自适应,这在某种程度上违背了信息隐藏的良好原则。在BubbleChart中获取圆形气泡是其中一种适应方式。

您可以做的最简单的事情是继承BubbleChart并创建自己的圆形气泡。

不起作用的事情:

创建数据节点的位置(方法createBubble)是私有的,因此您无法覆盖它以创建Circle。 (除此之外 - 即使你有一个自定义数据节点,它也无法正常工作,因为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-Radius更改为等于X-Radius,因此气泡半径将以X轴为单位。当然,你也可以反过来获得以Y轴为单位的气泡半径。