设置条形图列宽度大小 [英] Set Bar Chart column width size

查看:242
本文介绍了设置条形图列宽度大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法设置JavaFX条形图列的宽度大小?

Is there a way to set JavaFX Bar Chart column width size?

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.chart.BarChart;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.stage.Stage;

public class BarChartSample extends Application {
    final static String austria = "Austria";
    final static String brazil = "Brazil";
    final static String france = "France";
    final static String italy = "Italy";
    final static String usa = "USA";

    @Override public void start(Stage stage) {
        stage.setTitle("Bar Chart Sample");
        final CategoryAxis xAxis = new CategoryAxis();
        final NumberAxis yAxis = new NumberAxis();
        final BarChart<String,Number> bc = 
            new BarChart<String,Number>(xAxis,yAxis);
        bc.setTitle("Country Summary");
        xAxis.setLabel("Country");       
        yAxis.setLabel("Value");

        XYChart.Series series1 = new XYChart.Series();
        series1.setName("2003");       
        series1.getData().add(new XYChart.Data(austria, 25601.34));
        series1.getData().add(new XYChart.Data(brazil, 20148.82));
        series1.getData().add(new XYChart.Data(france, 10000));
        series1.getData().add(new XYChart.Data(italy, 35407.15));
        series1.getData().add(new XYChart.Data(usa, 12000));      

        XYChart.Series series2 = new XYChart.Series();
        series2.setName("2004");
        series2.getData().add(new XYChart.Data(austria, 57401.85));
        series2.getData().add(new XYChart.Data(brazil, 41941.19));
        series2.getData().add(new XYChart.Data(france, 45263.37));
        series2.getData().add(new XYChart.Data(italy, 117320.16));
        series2.getData().add(new XYChart.Data(usa, 14845.27));  

        XYChart.Series series3 = new XYChart.Series();
        series3.setName("2005");
        series3.getData().add(new XYChart.Data(austria, 45000.65));
        series3.getData().add(new XYChart.Data(brazil, 44835.76));
        series3.getData().add(new XYChart.Data(france, 18722.18));
        series3.getData().add(new XYChart.Data(italy, 17557.31));
        series3.getData().add(new XYChart.Data(usa, 92633.68));  

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

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

例如,有一种方法可以设置setBarGap但是我找不到设置条形图列最大宽度的方法。

For example there is a way to setBarGap size but I can't find a way to set the maximum width of a Bar Chart column.

有没有办法解决这个问题?

Is there a way to solve this?

推荐答案

BarChart 的工作原理是 barGap (用户可以设置同一类别中条形间的差距)和 categoryGap (单独类别中条形间的间隙),因此对于给定尺寸的图表,宽度为每次请求布局时都会在内部计算条形。

BarChart works on the basis that both barGap (gap between bars in the same category) and categoryGap (gap between bars in separate categories) can be set by the user, so for a given size of chart, the width of the bars is calculated internally every time a layout is requested.

要在每个条上设置最大宽度,我们必须更改 barGap categoryGap 。但我们可以通过编程方式进行,以响应图表宽度的任何变化。

To set a maximum width on every bar, we have to change either barGap or categoryGap accordingly. But we can do it programmatically, to respond to any change in the width of the chart.

让我们首先计算初始布局的条宽。根据 BarChart.layoutPlotChildren()

Let's first calculate the bar width for an initial layout. According to BarChart.layoutPlotChildren():

double catSpace = xAxis.getCategorySpacing();
double avilableBarSpace = catSpace - (bc.getCategoryGap() + bc.getBarGap());
double barWidth = (avilableBarSpace / bc.getData().size()) - bc.getBarGap();

在OP提供的示例中,给出默认的间隙值( barGap = 4 categoryGap = 10 ),结果 barWidth 为37.4。

In the example provided by the OP, given the default gap values (barGap=4, categoryGap=10), the resulting barWidth is 37.4.

我们假设我们要设置40的限制,最小类别差距为10:

Let's assume we want to set a limit of 40, and a minimum category gap of 10:

double maxBarWidth=40;
double minCategoryGap=10;

如果在调整场景大小时图表的宽度增加,我们可以限制 barWidth 通过增加 categoryGap

If the chart's width increases when the scene is resized, we could limit barWidth by increasing categoryGap:

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-while循环:我们修改 categoryGap 执行新布局并更改一些初始值。通常需要两次迭代才能得到理想的结果。

Note the do-while loop: as we modify categoryGap a new layout is performed and some initial values change. It takes usually two iterations to get the desired result.

只要图表的宽度不断增长,我们就可以重复此操作。

We can repeat this operation as long as the chart's width keeps growing.

但如果图表的宽度开始下降,则类别之间的差距也应该减小,而条形宽度保持接近其最大值:

But if the chart's width starts decreasing, the gap between categories should be decreased too, while the bar width stays close to its maximum:

double barWidth=0;
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);

将所有内容放在一起,并聆听场景宽度变化:

Putting everything together, and listening to scene width changes:

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

    double maxBarWidth=40;
    double minCategoryGap=10;

    scene.widthProperty().addListener((obs,n,n1)->{
        if(bc.getData().size()==0) return;

        if(n!=null && (n1.doubleValue()>n.doubleValue())){
            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);
        }

        if(n!=null && (n1.doubleValue()<n.doubleValue()) && bc.getCategoryGap()>minCategoryGap){
            double barWidth=0;
            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);
        }
    });

请注意,在其余情况下, barWidth 将在内部计算。

Note that in the rest of the cases, barWidth will be calculated internally.

这篇关于设置条形图列宽度大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆