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

eks*_*oom 2 java bubble-chart javafx

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

我知道我可以写一个"泡沫":

new XYChart.Data<Number,Number>(nbrOfMarketSegments, latestYearRevenue, radiusOfBubble);
Run Code Online (Sandbox Code Playgroud)

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

BubbleChart中

isn*_*bad 5

JavaFX图表是一段邪恶的代码.只有在您完全了解背后的代码库时才能实现自适应,这在某种程度上违背了信息隐藏的良好原则.在a中获取圆形气泡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()));
    }
}
Run Code Online (Sandbox Code Playgroud)

用法很简单:只需将图表创建代码行更改... = new BubbleChart()... = new CircularBubbleChart().其他一切都保持不变.

注意:此代码将Y-Radius更改为等于X-Radius,因此气泡半径将以X轴为单位.当然,您也可以以相反的方式获得以Y轴为单位的气泡半径.