【问题标题】:Creating Text inside Bubble of JavaFX BubbleChart在 JavaFX BubbleChart 的气泡内创建文本
【发布时间】:2015-09-23 14:29:54
【问题描述】:

我的可视化中有一个 JavaFX BubbleChart,我需要能够在图表的每个气泡中创建/显示文本。在我的可视化中,我有许多 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 StackOverflow 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);
}

}

【问题讨论】:

  • 一个肮脏的技巧是继承 BubbleChart 并在布局期间为每个数据点添加文本到节点。一个不那么脏的版本是直接在nodes上操作。

标签: java user-interface javafx bubble-chart


【解决方案1】:

你从数据中得到的节点是一个 Stackpane,而 Stackpane 的形状是一个 Ellipse。您可能需要该椭圆在 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 方法。

【讨论】:

  • 你能绑定到region.widthProperty()(或从它派生的值)吗?这样您就不必访问Ellipse 并且将依赖更少的实现细节(因此它对实现更改会更加健壮)。
  • 对 region.getWidth() 的简短测试表明它没有设置。它总是返回零。
  • 是的,确实如此。你可以通过region.boundsInLocalProperty() 到达那里,但它变得很丑。
  • @James_D 所以这似乎是标签只显示三个点的原因,因为堆栈窗格的宽度设置为零。我添加了检查它是否真的是椭圆。所以这对于 BubbleChart 来说真的很特别,但需要注意 extraValue 作为半径的一个因素。
猜你喜欢
  • 2016-12-01
  • 1970-01-01
  • 2021-09-20
  • 1970-01-01
  • 2012-08-09
  • 2020-04-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多