JavaFX BarChart的x轴标签位置不好

3

我有一个用于窗口的以下控制器:

package window;

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.chart.BarChart;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;

import java.util.Map;
import java.util.SortedMap;

public class StatisticsController {

    @FXML
    private BarChart<?, ?> barChartHistogram;

    private SortedMap<String, Integer> _points;

    @FXML
    private CategoryAxis xAxis;
    @FXML
    private NumberAxis yAxis;

    public void onLoad(SortedMap<String, Integer> points) {
        xAxis.setLabel("Numer indeksu");
        yAxis.setLabel("Ilość punktów");
        //barChartHistogram.setBarGap(0);
        XYChart.Series series1 = new XYChart.Series();
        int a = 10;
        series1.getData().add(new XYChart.Data("Tom", 10));
        series1.getData().add(new XYChart.Data("Andrew", 7));
        series1.getData().add(new XYChart.Data("Patrick", 5));


        /*for (Map.Entry<String, Integer> p: points.entrySet()) {
            series1.getData().add(new XYChart.Data<>(Integer.toString(a), p.getValue()));
            a += 10;
        }*/
        barChartHistogram.getData().addAll(series1);
        _points = points;
    }

}

此窗口的.fxml文件:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.chart.BarChart?>
<?import javafx.scene.chart.CategoryAxis?>
<?import javafx.scene.chart.NumberAxis?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane prefHeight="700.0" prefWidth="1000.0" xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="window.StatisticsController">
   <children>
      <BarChart fx:id="barChartHistogram" layoutX="12.0" layoutY="14.0" prefHeight="372.0" prefWidth="1500.0">
        <xAxis>
          <CategoryAxis side="BOTTOM" fx:id="xAxis" />
        </xAxis>
        <yAxis>
          <NumberAxis fx:id="yAxis" side="LEFT" />
        </yAxis>
      </BarChart>
   </children>
</AnchorPane>

除了一件事,一切都工作得很完美:

enter image description here

正如您所看到的,x轴标签工作得很好,但是x轴标签(我指的是列名),应该是TomAndrewPatrick,它们被放置在x轴的0位置上(通过这个混乱,您实际上可以读到Patrick)。问题出在哪里?我应该对UI进行一些更改吗?

我运行了你的代码,没有遇到问题。 - SedJ601
我使用 Java 8 - SedJ601
嗯,Java 8没有帮助,已经检查过了。 - minecraftplayer1234
1
遇到了非常类似的问题。经过长时间的调试和尝试多种解决方法后,我不得不承认这个问题确实无法修复,而且源于直方图类中的错误。我不知道他们怎么可能会错过这么显而易见的问题。 - Andrew Butenko
嗯...我刚看了你的另一个问题https://stackoverflow.com/q/48994521/203657,如果我使用按钮动态加载数据系列,我也能够重现布局错误。 - kleopatra
显示剩余3条评论
4个回答

9
我发现另一种解决方法。只需设置xAxis.setAnimated(false)即可。

这是更好的解决方法。手动设置容易出错。谢谢。 - BalGu

6

如果数据是动态设置的,则CategoryAxis的自动范围存在问题,这是一个错误

下面是一个(非fxml)示例,演示了使用粗略的hack-around解决此问题:手动设置类别而不是让图表/轴查找它们。

public class BarChartBug extends Application {

    private NumberAxis yAxis;
    private CategoryAxis xAxis;
    private BarChart<String, Number> barChart;

    private Parent createContent() {
        xAxis = new CategoryAxis();
        yAxis = new NumberAxis();
        barChart = new BarChart<>(xAxis, yAxis);

        Button initData = new Button("init");
        initData.setOnAction(e -> {
            xAxis.setLabel("Numer indeksu");
            yAxis.setLabel("Ilo punktw");
            XYChart.Series<String, Number> series1 = new XYChart.Series<>();
            series1.getData().add(new XYChart.Data<String, Number>("Tom", 10));
            series1.getData().add(new XYChart.Data<String, Number>("Andrew", 7));
            series1.getData().add(new XYChart.Data<String, Number>("Patrick", 5));

            // hack-around:
            // xAxis.setCategories(FXCollections.observableArrayList("Tom", "Andrew", "Patrick"));
            barChart.getData().addAll(series1);

            initData.setDisable(true);

        });
        BorderPane pane = new BorderPane(barChart);
        pane.setBottom(initData);
        return pane;

    }

    @Override
    public void start(Stage stage) throws Exception {
        stage.setScene(new Scene(createContent()));
        stage.setTitle(FXUtils.version());
        stage.show();
    }

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

    @SuppressWarnings("unused")
    private static final Logger LOG = Logger
            .getLogger(BarChartBug.class.getName());

}

你是完全正确的,其实我自己也明白了。无论如何,还是谢谢! - minecraftplayer1234

1
这是一个与动画属性相关的错误,你可以:
  • 设置 xAxis.setAnimated(false)
  • 或者
  • 将动画属性设置为false:<CategoryAxis animated="false" side="BOTTOM" fx:id="xAxis" />

0

这很有趣,但我在使用Java11时遇到了相同的问题https://youtu.be/2ZKzWciKtIc?t=36,当我的图表数据加载完毕后,类别标签从未显示出来。经过几次尝试,我决定将图表数据设置为时间线,并在完成后手动设置类别标签。

Duration duration = Duration.millis(300);
Platform.runLater(()->{
    Timeline timeline = new Timeline(
        new KeyFrame(duration,event -> {
            barChart.getData().clear();
            barChart.getData().add(series1);
            barChart.getData().addAll(series2);
            //Clear all bofore to evitate Exceptions
            catAxis.getCategories().clear();                           
        })
    );
    timeline.setCycleCount(1);
    timeline.setOnFinished(event -> {
    //Set animated as false, so if true all labels will be one in top of the others 
    barChart.setAnimated(false);
    //The trick that worked forr me
    catAxis.getCategories().addAll(lists);
});
timeline.play();  });

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接