如何更改 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 轴具有如此不同的跨度,有没有办法使气泡更像圆形?
JavaFX 图表是一段邪恶的代码。仅当您完全了解背后的代码库时才有可能进行适应,这在某种程度上违背了信息隐藏的良好原则。在 BubbleChart
中制作圆形气泡就是其中一种改编。
您可以做的最简单的事情是继承 BubbleChart
并创建您自己的圆形气泡。
不起作用的东西:
创建数据节点的地方(方法createBubble
)是私有的,所以你不能覆盖它来创建Circle
s。 (除此之外——即使你有一个自定义数据节点,它也不会工作,因为 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轴为单位的气泡半径
我正在编写一个 javafx
程序,该程序应该显示 BubbleChart
用于公司分析。 y 轴显示去年的收入,x 轴显示公司经营的细分市场数量。泡沫的半径取决于公司经营的细分市场。
我知道我可以写成"bubble":
new XYChart.Data<Number,Number>(nbrOfMarketSegments, latestYearRevenue, radiusOfBubble);
问题是 y 轴最大值为 100(百万欧元),x 轴最大值为 20,这使得 "bubbles" 非常扁平,就像图片中那样(因为 radiusOfBubble
数字是与最大细分市场数相比大,与最大收入相比小。我的问题是,即使 x 轴和 y 轴具有如此不同的跨度,有没有办法使气泡更像圆形?
JavaFX 图表是一段邪恶的代码。仅当您完全了解背后的代码库时才有可能进行适应,这在某种程度上违背了信息隐藏的良好原则。在 BubbleChart
中制作圆形气泡就是其中一种改编。
您可以做的最简单的事情是继承 BubbleChart
并创建您自己的圆形气泡。
不起作用的东西:
创建数据节点的地方(方法createBubble
)是私有的,所以你不能覆盖它来创建Circle
s。 (除此之外——即使你有一个自定义数据节点,它也不会工作,因为 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轴为单位的气泡半径