JavaFX图表 - CategoryAixis调整大小问题

时间:2015-10-06 20:21:30

标签: charts javafx-8

我有一个用户可调整大小的图表。当图表变小时,CategoryAxis会旋转,您将无法再看到大多数类别标签。这是一个显示问题的GIF:

Example of Issue

有没有办法阻止标签旋转?

我知道我可以为rotation属性添加一个侦听器,并在旋转更改时将其旋转回0。但是,当我这样做时,它不会阻止间距调整,因此标签会被切断(您只能看到标签的最后几个字符)。

这是包含的gif的代码,在调整窗口大小时你会看到问题:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.chart.BarChart;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.stage.Stage;

public class HorizontalBarExample extends Application {
    @Override
    public void start(Stage stage)  {
        NumberAxis xAxis = new NumberAxis();
        CategoryAxis yAxis = new CategoryAxis();
        BarChart<Number, String> bc = new BarChart<Number, String>(xAxis, yAxis);
        bc.setBarGap(0d);
        bc.setCategoryGap(0);

        xAxis.setTickLabelRotation(90);
        yAxis.tickLabelRotationProperty().set(0d);

        XYChart.Series<Number, String> series1 = new XYChart.Series<>();
        series1.setName("example");

        for (int i = 0; i < 10; i++)
            series1.getData().add(new XYChart.Data<Number, String>(Math.random() * 5000, "long data label number" + i));

        bc.getData().add(series1);

        Scene scene = new Scene(bc, 800, 600);
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args)  {
        launch(args);
    }
}

1 个答案:

答案 0 :(得分:4)

此问题不易修复(IMO)。

进行了什么

Java 8u60的CategoryAxis代码在内部维护一个私有effectiveTickLabelRotation成员。由于内部实施,该成员有时可以覆盖您为公开可用的tickLabelRotationProperty设置的任何值。所以你真的无法控制这些功能。

各种(失败的)尝试使用公共API修复它

它覆盖的一种方法是当类别轴设置为autoRanging时,您可以将autoRanging设置为false,并使用CategoryAxis::setCategory方法手动设置类别。这种方法解决了这个问题,因为当图形变小时,不会使用effectiveRotation,它会尊重您想要的旋转并且文本保持垂直。

然而,即使切换自动量程并手动设置类别,实施中还有其他怪癖会阻止合理的结果。 CategoryAxis的内部布局算法仍然认为类别标签已经旋转,因此当图表变小时,它不会为标签分配足够的空间。 CategoryAxis类是最终的,因此布局逻辑不能在子类中重写。快速黑客将设置轴的最小宽度yAxis.setMinWidth(200);。不幸的是,CategoryAxis布局算法也不尊重最小宽度设置。

获取此功能的选项

简而言之,它已经完全崩溃了......你要么:

  1. 按原样接受默认行为,或
  2. log a bug请求修复,或
  3. 您将CategoryAxis代码复制到新类,例如Horizo​​ntallyLabelledCategoryAxis,进行一些修改以允许布局算法按您的意愿工作,并使用该新类代替原始的CategoryAxis。
  4. 选项3有点棘手,但可行。

    建议的解决方法

    所有这一切,我推荐的方法(例如解决方法),如果你的用户界面可以接受的话,就是不要让图表变得足够小以至于它的布局搞砸了。

    VBox chartHolder = new VBox(bc);
    VBox.setVgrow(bc, Priority.ALWAYS);
    bc.setMinHeight(300);
    Scene scene = new Scene(chartHolder, 800, 600);