JavaFX图表 - CategoryAixis调整大小问题 [英] JavaFX Charting - CategoryAixis Resize Issue

查看:861
本文介绍了JavaFX图表 - CategoryAixis调整大小问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个用户可调整大小的图表。当图表变小时,CategoryAxis旋转,您不能再看到大多数类别标签。下面是一个显示问题的gif:





有什么办法阻止标签旋转?



我知道我可以添加一个监听器到旋转属性,如果旋转改变旋转回0。但是,当我这样做并不妨碍间距调整,所以标签只是被切断(你只看到标签的最后几个字符)。



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

  import javafx.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 Horizo​​ntalBarExample extends应用程序{
@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.tickLabelRotationProperties()。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,长数据标签号+ i));

bc.getData()。add(series1);

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

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


解决方案

问题不容易解决(IMO)。



发生了什么



Java 8u60的CategoryAxis代码内部维护一个私人 effectiveTickLabelRotation 成员。由于内部实现,此成员有时会覆盖为公开可用的 tickLabelRotationProperty 设置的任何值。所以你真的没有太多的控制功能。



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

它覆盖的是类轴被设置为autoRanging,因此您可以将autoRanging设置为false,并使用 CategoryAxis :: setCategory 方法手动设置类别。这种修复问题,因为然后当图表变小时,不使用effectiveRotation,它尊重你想要的旋转,文本保持垂直。



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



获取此功能的选项



简而言之,它是一种破碎的...你:


  1. 接受默认行为

  2. 记录错误请求修正,或

  3. 您将CategoryAxis代码复制到一个新类中,例如Horizo​​ntallyLabelledCategoryAxis,进行一些修改,以允许布局算法按您的意愿工作,并使用该新类代替原始的CategoryAxis。

选项3有点棘手,但可行。



>建议的解决方法



这么说,如果您的UI可以接受的话,

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


I have a user-resizable chart. When the chart gets smaller the CategoryAxis rotates and you can no longer see most of the category labels. Here is a gif showing the problem:

Is there any way to stop the labels from rotating?

I know I can add a listener to the rotation property and rotate it back to 0 if the rotation changes. However, when I do that it doesn't prevent the spacing from adjusting, so the labels just get cut off (you only see the last few characters of the label).

Here is the code for the included gif, you'll see the problem as you resize the window:

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);
    }
}

解决方案

This issue is not easily fixable (IMO).

What's going on

The CategoryAxis code for Java 8u60 internally maintains a private effectiveTickLabelRotation member. This member can at times, due to the internal implementation, override whatever value you set for the publicly available tickLabelRotationProperty. So you don't really have much control over the functionality.

Various (failed) attempts to fix it using public API

One way that it overrides is when the the category axis is set to autoRanging, so you can set autoRanging to false and also manually set the categories using the CategoryAxis::setCategory method. This kind of fixes the issue because then the effectiveRotation is not used when the graph gets small, it respects the rotation you want and the text stays vertical.

However, even with switching auto ranging off and manually setting categories, there are other quirks in the implementation which prevent a reasonable result. The internal layout algorithm for the CategoryAxis still thinks that the category labels have been rotated, so it does not allocate enough space for the labels when the chart gets smaller. The CategoryAxis class is final so the layout logic can't be overridden in a subclass. A quick hack would be set a minimum width for the axis, yAxis.setMinWidth(200);. Unfortunately the CategoryAxis layout algorithm does not respect the min width setting either.

Options to get this functionality

In short, it's all kind of broken ... you either:

  1. Accept the default behavior as is, OR
  2. You log a bug requesting a fix, OR
  3. You copy the CategoryAxis code to a new class, e.g. HorizontallyLabelledCategoryAxis, make some modifications to allow the layout algorithm to work as you wish and use that new class in place of the original CategoryAxis.

Option 3 is a bit tricky, but doable.

Suggested Work-around

All that said, the approach (e.g. work-around) I'd recommend, if it is acceptable for your UI, is simply not to let the chart get small enough that its layout screws up.

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

这篇关于JavaFX图表 - CategoryAixis调整大小问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆