Charts JavaFX图表-类别调整问题
我有一个用户可调整大小的图表。当图表变小时,类别轴将旋转,您将无法再看到大多数类别标签。下面是显示问题的gif: 有没有办法阻止标签旋转 我知道我可以将侦听器添加到rotation属性,并在旋转更改时将其旋转回0。但是,当我这样做时,它不会阻止间距的调整,因此标签只是被切断(您只看到标签的最后几个字符) 以下是包含的gif的代码,在调整窗口大小时,您会看到问题:Charts JavaFX图表-类别调整问题,charts,javafx-8,Charts,Javafx 8,我有一个用户可调整大小的图表。当图表变小时,类别轴将旋转,您将无法再看到大多数类别标签。下面是显示问题的gif: 有没有办法阻止标签旋转 我知道我可以将侦听器添加到rotation属性,并在旋转更改时将其旋转回0。但是,当我这样做时,它不会阻止间距的调整,因此标签只是被切断(您只看到标签的最后几个字符) 以下是包含的gif的代码,在调整窗口大小时,您会看到问题: import javafx.application.Application; import javafx.scene.Scene;
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);
}
}
导入javafx.application.application;
导入javafx.scene.scene;
导入javafx.scene.chart.BarChart;
导入javafx.scene.chart.CategoryAxis;
导入javafx.scene.chart.NumberAxis;
导入javafx.scene.chart.XYChart;
导入javafx.stage.stage;
公共类HorizontalBarExample扩展了应用程序{
@凌驾
公众假期开始(阶段){
NumberAxis xAxis=新NumberAxis();
CategoryAxis yAxis=新CategoryAxis();
条形图bc=新条形图(xAxis,yAxis);
公元前30年挫折(0d);
bc.setCategoryGap(0);
xAxis.setticklabel旋转(90);
yAxis.ticklableRotationProperty().set(0d);
XYChart.Series系列1=新的XYChart.Series();
系列1.集合名(“示例”);
对于(int i=0;i<10;i++)
series1.getData().add(新的XYChart.Data(Math.random()*5000,“长数据标签号”+i));
bc.getData().add(series1);
场景=新场景(bc,800600);
舞台场景;
stage.show();
}
公共静态void main(字符串[]args){
发射(args);
}
}
这个问题不容易解决(IMO)
发生什么事了
Java 8u60的CategoryAxis代码在内部维护一个私有有效的TickLabelRotation
成员。由于内部实现的原因,此成员有时可以覆盖为公共可用的tickLabelRotationProperty
设置的任何值。因此,您对功能没有太多控制权
使用公共API修复它的各种尝试(失败)
它覆盖的一种方式是将类别轴设置为自动范围时,因此可以将自动范围设置为false,还可以使用CategoryAxis::setCategory
方法手动设置类别。这种方法解决了这个问题,因为当图形变小时,不会使用effectiveRotation,它尊重您想要的旋转,并且文本保持垂直
然而,即使关闭自动测距和手动设置类别,在实现过程中也存在其他问题,从而无法获得合理的结果。CategoryAxis的内部布局算法仍然认为类别标签已经旋转,因此当图表变小时,它没有为标签分配足够的空间。CategoryAxis类是final类,因此不能在子类中重写布局逻辑。快速破解将设置轴的最小宽度,yAxis.setMinWidth(200)代码>。不幸的是,CategoryAxis布局算法也不考虑最小宽度设置
获取此功能的选项
简言之,它都坏了。。。你可以:
按原样接受默认行为,或
您请求修复,或
将CategoryAxis代码复制到一个新类,例如HorizontallyLabelledCategoryAxis,进行一些修改以允许布局算法按您的意愿工作,并使用该新类代替原始CategoryAxis李>
选项3有点棘手,但可行
建议的解决办法
综上所述,如果你的UI可以接受的话,我推荐的方法(例如,变通)就是不要让图表变得太小,以至于布局出错
VBox chartHolder = new VBox(bc);
VBox.setVgrow(bc, Priority.ALWAYS);
bc.setMinHeight(300);
Scene scene = new Scene(chartHolder, 800, 600);
我想说,这是一个bug:如果空间变小,水平显示所有标签,那么无论类别轴应该做什么,旋转都不是可行的选项之一(忽略每个n'th可能是或不是,或者在鼠标悬停在类别上,然后只显示该类别之前不显示任何n'th)