2016-07-27 31 views
2

我正在编写一个javafx程序,该程序应该显示公司分析的BubbleChart。显示y轴去年的收入,x轴显示公司运营的细分市场的数量。气泡的半径取决于什么样的细分市场的公司在经营如何更改BubbleChart javafx中的气泡大小

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

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

的问题是,y轴最大值100(百万欧元),x轴最大值为20,这使得“气泡”非常平坦,如图所示(因为radiusOfBubble数字相对于最大数量的市场细分市场而言并不大, ,是否有任何方法可以使气泡更像圆形,即使x轴和y轴具有不同的跨距?

BubbleChart

回答

3

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

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

东西不起作用:

在其中创建数据节点的地方(方法createBubble)是私有的,所以你不能覆盖它来创建Circle!而非。 (除此之外 - 即使你有一个自定义数据节点,它也不会工作,因为BubbleChart中的布局代码忽略了所有不是Ellipse类型的数据节点,所以你最终会得到圆形的气泡,但所有的位置0/0)...)。

想到的下一件事是重写省略号轴的设置位置。但是,不,所有的布局代码都是单一的方法 - 没有为每个节点调用的方法,并且您可以覆盖以添加自定义布局代码。

解决方案:

所以,你必须要覆盖的方法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-Radius,因此气泡半径将以X轴为单位。当然,你也可以在相反的位置获得以Y轴为单位的气泡半径。

+0

谢谢!这非常有帮助! – ekstroom

相关问题