vantilator
vantilator

Reputation: 33

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

I integrated javafx piechart on my swing panel its working fine, but my data list is too big to fit in the legend and the legend is expanding which causes the piechart getting smaller. Id like to make it scrollable but couldnt find any solution. Im new to javafx.

Also what layout would you suggest for piechart panel and scene to fit in the jpanel? As you see my piechart panel doesnt fill the scene. I dont want my chart to shrink.

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

one column legend

one column legend

2 column legend causes chart to shrink

2 column legend causes chart to shrink

Upvotes: 3

Views: 1583

Answers (2)

Peter
Peter

Reputation: 1612

If you extend PieChart you can access the Legend directly as it is protected, see : Chart

By doing that you can do something along these lines:

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

Note: If you go for this approach, I recommend updating this: legend.setPrefWidth(100); to be more specific to your LegendItem's. As this won't be the best solution for large display names


By substituting the above into your code and adding a few test items to cause the need for the scroll bars, I got the following:

enter image description here


Layout wise I don't think you need the Group and scroll panes you're currently using. If you update your getScene() method to the below you should see a small improvement:

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

For further improvements hopefully the following posts can help:

Upvotes: 3

Beniton Fernando
Beniton Fernando

Reputation: 1533

I think by default the legends are placed in the bottom. As the width of the panel is more you can display the legend in default position.

And you are adding the JFXPanel to a JScrollPane which i think is not required.

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

you can directly add it the panel

add(getJfxPanel(), BorderLayout.CENTER);

And the panel which you are adding the JFxPanel would be occupying the whole region of right side. I am not sure what layout that panel has, so i am not sure if it occupy the entire right side region.

And if you really want it scrollable you need to set the size of the JFXPanel based on the data you have for the piechart and place it inside the JScrollpane as you did.

Upvotes: 1

Related Questions