在 JavaFX BubbleChart 的气泡内创建文本
Creating Text inside Bubble of JavaFX BubbleChart
我的可视化中有一个 JavaFX BubbleChart,我需要能够 create/display 在图表的每个气泡中显示文本。在我的可视化中,我有很多 XYChart.Series,每个系列只有 1 个气泡。对于每个系列,我都会 "series.setName("xxxx");" (其中 xxxx = 唯一系列名称)我需要能够在气泡内显示该系列名称。
我已经为显示系列名称的气泡图实现了工具提示(鼠标悬停事件),但我还需要在气泡内显示文本而不需要鼠标悬停。
为了有代码来处理,这里有一个 5 系列的基本示例。我将如何在每个气泡中添加文本?
谢谢。
public class bubbleChartTest extends Application {
@Override
public void start(Stage stage) {
final NumberAxis xAxis = new NumberAxis(0, 10, 1);
final NumberAxis yAxis = new NumberAxis(0, 10, 1);
final BubbleChart<Number, Number> bc = new BubbleChart<Number, Number>(xAxis, yAxis);
xAxis.setLabel("X Axis");
xAxis.setMinorTickCount(2);
yAxis.setLabel("Y Axis");
yAxis.setTickLabelGap(2);
bc.setTitle("Bubble Chart Whosebug Example");
XYChart.Series<Number, Number> series1 = new XYChart.Series<Number, Number>();
series1.setName("Series 1");
series1.getData().add(new XYChart.Data<Number, Number>(3, 7, 1.5));
XYChart.Series<Number, Number> series2 = new XYChart.Series<Number, Number>();
series2.setName("Series 2");
series2.getData().add(new XYChart.Data<Number, Number>(8, 3, 1));
XYChart.Series<Number, Number> series3 = new XYChart.Series<Number, Number>();
series3.setName("Series 3");
series3.getData().add(new XYChart.Data<Number, Number>(1, 9, 2));
XYChart.Series<Number, Number> series4 = new XYChart.Series<Number, Number>();
series4.setName("Series 4");
series4.getData().add(new XYChart.Data<Number, Number>(4, 1, 0.5));
XYChart.Series<Number, Number> series5 = new XYChart.Series<Number, Number>();
series5.setName("Series 5");
series5.getData().add(new XYChart.Data<Number, Number>(9, 9, 3));
Scene scene = new Scene(bc);
bc.getData().addAll(series1, series2, series3, series4, series5);
stage.setScene(scene);
stage.show();
for(XYChart.Series<Number, Number> series : bc.getData()) {
for(XYChart.Data<Number, Number> data : series.getData()) {
Tooltip.install(data.getNode(), new Tooltip(series.getName()));
}
}
}
public static void main(String[] args) {
launch(args);
}
}
你从数据中得到的节点是一个Stackpane,Stackpane的形状是一个椭圆。您可能需要该椭圆在 x 方向上的半径,并向 Stackpane 添加标签。但是需要设置Label的minWidth属性,否则只会显示三个点。你需要一个 属性 来保持动态字体大小,因为如果你想调整图表的大小,它应该看起来很漂亮。
您不需要太多代码就可以完成这项工作:
for (XYChart.Series<Number, Number> series : bc.getData()) {
for (XYChart.Data<Number, Number> data : series.getData()) {
Node bubble = data.getNode();
if (bubble != null && bubble instanceof StackPane) {
StackPane region = (StackPane) bubble;
if (region.getShape() != null && region.getShape() instanceof Ellipse) {
Ellipse ellipse = (Ellipse) region.getShape();
DoubleProperty fontSize = new SimpleDoubleProperty(10);
Label label = new Label(series.getName());
label.setAlignment(Pos.CENTER);
label.minWidthProperty().bind(ellipse.radiusXProperty());
//fontSize.bind(Bindings.when(ellipse.radiusXProperty().lessThan(40)).then(6).otherwise(10));
fontSize.bind(Bindings.divide(ellipse.radiusXProperty(), 5));
label.styleProperty().bind(Bindings.concat("-fx-font-size:", fontSize.asString(), ";"));
region.getChildren().add(label);
}
}
}
}
更新
James_D 提到在更改形状(例如 Shape)的情况下循环不是很稳健。所以我对它做了一些更改以请求椭圆实例。这有点像 BubbleChart 的原始 layoutPlotChildren 方法。
我的可视化中有一个 JavaFX BubbleChart,我需要能够 create/display 在图表的每个气泡中显示文本。在我的可视化中,我有很多 XYChart.Series,每个系列只有 1 个气泡。对于每个系列,我都会 "series.setName("xxxx");" (其中 xxxx = 唯一系列名称)我需要能够在气泡内显示该系列名称。
我已经为显示系列名称的气泡图实现了工具提示(鼠标悬停事件),但我还需要在气泡内显示文本而不需要鼠标悬停。
为了有代码来处理,这里有一个 5 系列的基本示例。我将如何在每个气泡中添加文本?
谢谢。
public class bubbleChartTest extends Application {
@Override
public void start(Stage stage) {
final NumberAxis xAxis = new NumberAxis(0, 10, 1);
final NumberAxis yAxis = new NumberAxis(0, 10, 1);
final BubbleChart<Number, Number> bc = new BubbleChart<Number, Number>(xAxis, yAxis);
xAxis.setLabel("X Axis");
xAxis.setMinorTickCount(2);
yAxis.setLabel("Y Axis");
yAxis.setTickLabelGap(2);
bc.setTitle("Bubble Chart Whosebug Example");
XYChart.Series<Number, Number> series1 = new XYChart.Series<Number, Number>();
series1.setName("Series 1");
series1.getData().add(new XYChart.Data<Number, Number>(3, 7, 1.5));
XYChart.Series<Number, Number> series2 = new XYChart.Series<Number, Number>();
series2.setName("Series 2");
series2.getData().add(new XYChart.Data<Number, Number>(8, 3, 1));
XYChart.Series<Number, Number> series3 = new XYChart.Series<Number, Number>();
series3.setName("Series 3");
series3.getData().add(new XYChart.Data<Number, Number>(1, 9, 2));
XYChart.Series<Number, Number> series4 = new XYChart.Series<Number, Number>();
series4.setName("Series 4");
series4.getData().add(new XYChart.Data<Number, Number>(4, 1, 0.5));
XYChart.Series<Number, Number> series5 = new XYChart.Series<Number, Number>();
series5.setName("Series 5");
series5.getData().add(new XYChart.Data<Number, Number>(9, 9, 3));
Scene scene = new Scene(bc);
bc.getData().addAll(series1, series2, series3, series4, series5);
stage.setScene(scene);
stage.show();
for(XYChart.Series<Number, Number> series : bc.getData()) {
for(XYChart.Data<Number, Number> data : series.getData()) {
Tooltip.install(data.getNode(), new Tooltip(series.getName()));
}
}
}
public static void main(String[] args) {
launch(args);
}
}
你从数据中得到的节点是一个Stackpane,Stackpane的形状是一个椭圆。您可能需要该椭圆在 x 方向上的半径,并向 Stackpane 添加标签。但是需要设置Label的minWidth属性,否则只会显示三个点。你需要一个 属性 来保持动态字体大小,因为如果你想调整图表的大小,它应该看起来很漂亮。
您不需要太多代码就可以完成这项工作:
for (XYChart.Series<Number, Number> series : bc.getData()) {
for (XYChart.Data<Number, Number> data : series.getData()) {
Node bubble = data.getNode();
if (bubble != null && bubble instanceof StackPane) {
StackPane region = (StackPane) bubble;
if (region.getShape() != null && region.getShape() instanceof Ellipse) {
Ellipse ellipse = (Ellipse) region.getShape();
DoubleProperty fontSize = new SimpleDoubleProperty(10);
Label label = new Label(series.getName());
label.setAlignment(Pos.CENTER);
label.minWidthProperty().bind(ellipse.radiusXProperty());
//fontSize.bind(Bindings.when(ellipse.radiusXProperty().lessThan(40)).then(6).otherwise(10));
fontSize.bind(Bindings.divide(ellipse.radiusXProperty(), 5));
label.styleProperty().bind(Bindings.concat("-fx-font-size:", fontSize.asString(), ";"));
region.getChildren().add(label);
}
}
}
}
更新
James_D 提到在更改形状(例如 Shape)的情况下循环不是很稳健。所以我对它做了一些更改以请求椭圆实例。这有点像 BubbleChart 的原始 layoutPlotChildren 方法。