如何限制图例大小并使其可以用饼图滚动?和 javafx 布局

How to restrict legend size and making it scrollable with piechart? and javafx layouts

我在我的 swing 面板上集成了 javafx 饼图,它工作正常,但我的数据列表太大,无法放入图例中,图例正在扩展,导致饼图变小。我想让它可滚动但找不到任何解决方案。我是 javafx 的新手。

另外,您建议饼图面板和场景采用哪种布局以适应 jpanel?如您所见,我的饼图面板没有填满整个场景。我不想让我的图表缩小。

public PieChartPanel() {
    this.setLayout(new BorderLayout());
    add(new JScrollPane(getJfxPanel()), BorderLayout.CENTER);
}

public JFXPanel getJfxPanel() {
    if (jfxPanel == null) {
        jfxPanel = new JFXPanel();
        jfxPanel.setScene(getScene());
    }
    return jfxPanel;
}

public Scene getScene() {
    if (scene == null) {
        Group root = new Group();
        scene = new Scene(root, Color.ALICEBLUE);

        javafx.scene.control.ScrollPane scroll = new ScrollPane();
        scroll.setFitToHeight(true);
        scroll.setFitToWidth(true);
        scroll.setContent(getPieChart());

        root.getChildren().addAll(scroll);

    }
    return scene;
}

private PieChart getPieChart() {
    if (pieChart == null) {
        ObservableList<PieChart.Data> pieChartData = FXCollections.observableArrayList();
        pieChart = new PieChart(pieChartData);
        pieChart.setTitle("Toplam Talep (Ünite) Grafiği");
        pieChart.setLabelLineLength(20);
        pieChart.setLegendSide(Side.RIGHT);
        pieChart.setClockwise(true);
    }
    return pieChart;
}

一列图例

2 列图例导致图表缩小

我认为默认情况下图例位于底部。由于面板的宽度更大,您可以在默认位置显示图例。

并且您正在将 JFXPanel 添加到 JScrollPane,我认为这不是必需的。

add(new JScrollPane(getJfxPanel()), BorderLayout.CENTER);

可以直接添加面板

add(getJfxPanel(), BorderLayout.CENTER);

并且您要添加 JFxPanel 的面板将占据右侧的整个区域。我不确定那个面板有什么布局,所以我不确定它是否占据了整个右侧区域。

如果您确实希望它可滚动,则需要根据您拥有的饼图数据设置 JFXPanel 的大小,并将其放置在 JScrollpane 中。

如果扩展 PieChart,您可以直接访问 Legend protected,请参阅:Chart

通过这样做,您可以按照以下方式做一些事情:

public class CustomPieChart extends PieChart {
    public CustomPieChart(ObservableList<PieChart.Data> data){
        super(data);
        setLabelLineLength(20);
        createScrollableLegend();
        setLegendSide(Side.RIGHT);
        setClockwise(true);
    }

    private void createScrollableLegend(){
        Legend legend = (Legend) getLegend();
        if(legend != null){
            legend.setPrefWidth(100);
            ScrollPane scrollPane = new ScrollPane(legend);
            scrollPane.setHbarPolicy(ScrollBarPolicy.NEVER);
            scrollPane.setVbarPolicy(ScrollBarPolicy.AS_NEEDED);
            scrollPane.maxHeightProperty().bind(heightProperty());
            setLegend(scrollPane);
        }
    }
}

注意:如果您采用这种方法,我建议更新此:legend.setPrefWidth(100); 以更具体地针对您的 LegendItem。因为这不是大型显示名称的最佳解决方案


通过将上面的代码替换到您的代码中并添加一些测试项目以导致需要滚动条,我得到了以下内容:


在布局方面,我认为您不需要当前使用的 Group 和滚动窗格。如果您将 getScene() 方法更新为以下,您应该会看到一个小改进:

public Scene getScene() {
    VBox root = new VBox();
    Scene scene = new Scene(root, Color.ALICEBLUE);
    root.getChildren().addAll(getPieChart());
    return scene;
}

如需进一步改进,希望以下帖子可以提供帮助:

  • JavaFX layout that scales with parent
  • JavaFX: How to make my custom component use all available space from parent layout?
  • Chart resizing