Peter Penzov
Peter Penzov

Reputation: 1588

Limit width size of Bar chart

I created simple example of Bar Chart but I notices that size of the bar fits the chart. How I can limit the size? Foe example I would like to limit the width size.

enter image description here

Upvotes: 3

Views: 4247

Answers (1)

José Pereda
José Pereda

Reputation: 45456

As we already discussed here, to set a maximum width on every bar, we have to change either barGap or categoryGap accordingly, every time the scene or the chart are resized.

The only difference from the refered question, is we have to resize the chart the first time is displayed.

Based on the same code, let's create the setMaxBarWidth() method:

private final NumberAxis yAxis = new NumberAxis();
private final CategoryAxis xAxis = new CategoryAxis();
private final BarChart<String,Number> bc = new BarChart<>(xAxis,yAxis);

private void setMaxBarWidth(double maxBarWidth, double minCategoryGap){
    double barWidth=0;
    do{
        double catSpace = xAxis.getCategorySpacing();
        double avilableBarSpace = catSpace - (bc.getCategoryGap() + bc.getBarGap());
        barWidth = (avilableBarSpace / bc.getData().size()) - bc.getBarGap();
        if (barWidth >maxBarWidth){
            avilableBarSpace=(maxBarWidth + bc.getBarGap())* bc.getData().size();
            bc.setCategoryGap(catSpace-avilableBarSpace-bc.getBarGap());
        }
    } while(barWidth>maxBarWidth);

    do{
        double catSpace = xAxis.getCategorySpacing();
        double avilableBarSpace = catSpace - (minCategoryGap + bc.getBarGap());
        barWidth = Math.min(maxBarWidth, (avilableBarSpace / bc.getData().size()) - bc.getBarGap());
        avilableBarSpace=(barWidth + bc.getBarGap())* bc.getData().size();
        bc.setCategoryGap(catSpace-avilableBarSpace-bc.getBarGap());
    } while(barWidth < maxBarWidth && bc.getCategoryGap()>minCategoryGap);
}

And now create the chart of your pic, but with a width of 40px:

@Override 
public void start(Stage stage) {
    bc.setTitle("1");
    xAxis.setLabel("Groups");       
    yAxis.setLabel("Value");

    XYChart.Series series1 = new XYChart.Series();
    series1.setName("Groups");       
    series1.getData().add(new XYChart.Data("kk", 1));

    Scene scene  = new Scene(bc,800,600);
    bc.getData().addAll(series1);
    stage.setScene(scene);
    stage.show();

    setMaxBarWidth(40, 10);
    bc.widthProperty().addListener((obs,b,b1)->{
        Platform.runLater(()->setMaxBarWidth(40, 10));
    });
}

chart

EDIT

I've wrapped the call to setMaxBarWidth() with Platform.runLater(), so the scene graph has time to refresh properly the chart, avoiding several repaints during the while loops. Also, I've moved the listener to bc.widthProperty(), in case the chart is embedded in other containers.

Upvotes: 5

Related Questions