BAR
BAR

Reputation: 17081

JavaFX set BarChart xAxis/width to size

I want to force the X size of my BarChart but can't. Is there a way to implement this? Maybe by overwriting a function in BarChart?

import com.milkyway.trader.missionControl.OptionHistorySingleton;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.chart.*;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class SetBarChartBarSizeExample extends Application {

    VBox root = new VBox();

    @Override
    public void start(Stage primaryStage) throws Exception {
        CategoryAxis xAxis = new CategoryAxis();
        NumberAxis yAxis = new NumberAxis();

        BarChart<String, Number> chart = new BarChart<>(xAxis,yAxis);
        chart.setLegendVisible(false);
        root.getChildren().add(chart);


        chart.setBarGap(5);
        chart.setCategoryGap(0);

        // Doesn't work.
        //xAxis.maxWidthProperty().bind(root.widthProperty());
        xAxis.setMaxWidth(20);
        chart.setMaxWidth(20);



        XYChart.Series series1 = new XYChart.Series();
        XYChart.Data barA = new XYChart.Data("A", 100);
        XYChart.Data barB = new XYChart.Data("B", -100);
        series1.getData().addAll(barA, barB);

        chart.getData().addAll(series1);


        Scene scene = new Scene(root, 400, 200);
        primaryStage.setScene(scene);
        primaryStage.setHeight(600);
        primaryStage.setWidth(400);
        primaryStage.show();
    }

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

Upvotes: 0

Views: 822

Answers (1)

James_D
James_D

Reputation: 209320

By default, the minimum width of a chart is a value computed from the number of bars, the minimum width required to display each bar, the minimum width required to display the y-axis, and other settings such as the padding and margin. The minimum width of your chart is greater than 20, so when you set the maximum width to 20, there is a conflict between the minimum and maximum width (both of these constraints cannot be met at the same time). The chart chooses to respect the minimum width over the maximum width in this circumstance, so you see the width of the chart at the minimum that its computed width will allow.

You can allow any maximum width to be respected by setting the minimum width to zero. In the following change to your code, you will get a chart of width 20 (but be aware that this is not enough space to display the bars, so all you will see is the y-axis):

 @Override
public void start(Stage primaryStage) throws Exception {
    CategoryAxis xAxis = new CategoryAxis();
    NumberAxis yAxis = new NumberAxis();

    BarChart<String, Number> chart = new BarChart<>(xAxis,yAxis);
    chart.setLegendVisible(false);
    root.getChildren().add(chart);


    chart.setBarGap(5);
    chart.setCategoryGap(0);

    chart.setMinWidth(0);
    chart.setMaxWidth(20);



    XYChart.Series series1 = new XYChart.Series();
    XYChart.Data barA = new XYChart.Data("A", 100);
    XYChart.Data barB = new XYChart.Data("B", -100);
    series1.getData().addAll(barA, barB);

    chart.getData().addAll(series1);


    Scene scene = new Scene(root, 400, 200);
    primaryStage.setScene(scene);
    primaryStage.setHeight(600);
    primaryStage.setWidth(400);
    primaryStage.show();
}

If you just want the chart to resize with the window, the VBox will do that by default, so you only need to set the minimum width to zero for that to happen:

    chart.setMinWidth(0);
    // chart.setMaxWidth(20);

Upvotes: 1

Related Questions