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

Posted

技术标签:

【中文标题】如何限制图例大小并使其可使用饼图滚动?和 javafx 布局【英文标题】:How to restrict legend size and making it scrollable with piechart? and javafx layouts 【发布时间】:2016-10-11 02:27:51 【问题描述】:

我在摆动面板上集成了 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 列图例导致图表缩小

【问题讨论】:

【参考方案1】:

如果您扩展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

【讨论】:

我现在明白了,这就像一个魅力!非常感谢,我非常感谢。但我一直在努力解决另一个问题。我正在使用 MVC 并且当我在模型中更新我的列表时,我可以看到饼图类中的列表也发生了变化,但屏幕上什么也没有出现。但饼图适用于预定义列表。在向列表中添加元素时,我也使用Platform.runLater()。这可能是什么原因造成的?【参考方案2】:

我认为默认情况下图例放置在底部。随着面板的宽度变大,您可以在默认位置显示图例。

您正在将 JFXPanel 添加到我认为不需要的 JScrollPane。

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

您可以直接将其添加到面板中

add(getJfxPanel(), BorderLayout.CENTER);

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

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

【讨论】:

以上是关于如何限制图例大小并使其可使用饼图滚动?和 javafx 布局的主要内容,如果未能解决你的问题,请参考以下文章

如何将对象作为数据类型传递给选择元素并使其可读以在其他地方使用它?

如何在 C# 中重新压缩 ODT 文件并使其可读?

您将使用啥架构来存储 100 亿条 MIME 消息并使其可删除和全文搜索,包括。附件

如何在Textview中检测网站链接并使其可点击[重复]

为属性设置默认值并使其可序列化

填充数组并使其可使用 Angular Material 过滤