2014-12-04 149 views
4

是否有設置JavaFX條形圖欄寬度大小的方法?設置條形圖欄寬度大小

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

例如有一種方法來設置BarGap大小,但我找不到方法來設置條形圖列的最大寬度。

有沒有辦法解決這個問題?的基礎上

+0

什麼是「懷特」? – 2014-12-04 19:56:40

+0

我的意思是寬度。我的錯。 – 2014-12-04 19:58:46

回答

4

BarChart作品,這兩個barGapcategoryGap(在單獨的類別條之間的間隙)(在同一類別杆之間的間隙)可以通過用戶對圖表的一個給定的尺寸設定,因此,的寬度每次請求佈局時,條形圖都會在內部進行計算。

要在每個欄上設置最大寬度,我們必須相應地更改barGapcategoryGap。但是我們可以通過編程來實現,以響應圖表寬度的任何變化。

我們首先計算初始佈局的條寬。根據BarChart.layoutPlotChildren()

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

在由OP提供的示例中,給出的缺省空隙值(barGap=4categoryGap=10),所得到的是barWidth 37.4。

假設我們要設置的40個限度,而10最低類別的差距:

double maxBarWidth=40; 
double minCategoryGap=10; 

如果圖表的寬度增大時,現場的大小時,我們可以通過增加categoryGap限制barWidth

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時,將執行新的佈局,並且一些初始值會發生變化。通常需要兩次迭代來獲得所需的結果。

只要圖表寬度持續增長,我們就可以重複這個操作。

但是,如果圖表的寬度開始減小,類別之間的差距也應該被減少,而線條的寬度保持接近其最大:

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

將所有內容放在一起,聽現場寬度的變化:

... 
    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將在內部計算。

+0

你知道在Java 8u60或9是否會有列寬設置? – 2015-05-22 18:52:43

+0

我不知道這一點,JIRA對此沒有任何問題。 – 2015-05-22 19:07:46

+0

這不適合我。條形圖未顯示。調用setMaxBarWidth()方法後,barchart.setCategoryGap被設置爲NaN。 – mistletoe 2017-02-17 15:28:33

0

繼續JoséPereda的回答。您可以根據您的數據集設置圖表的寬度。與BarGap和CategoryGap設置器一起,您可以通過計算或反覆試驗來微調條的寬度。舉例來說,我做了以下事情以獲得更細的酒吧。我將一個空白圖形的寬度設置爲30(對於軸和標籤??),然後將100px添加到遊戲中每一輪的最大和最小寬度(最大爲網格窗寬度),從而限制空閒圖中用於填充條的空間。

Pane barchart1 = new Pane; 
CategoryAxis xAxis = new CategoryAxis(); 
NumberAxis yAxis = new NumberAxis(0,25,1); 
BarChart<String, Number> bc1 = 
     new BarChart<String, Number>(xAxis, yAxis); 
    // create Player chart 
    bc1.setTitle(G.getPlayerName(0)); 
    bc1.setTitle(null); 
    xAxis1.setLabel("Round"); 
    yAxis1.setLabel("Points"); 
    XYChart.Series series1 = new XYChart.Series(); 
    series1.setName("Pegging"); 
    XYChart.Series series3 = new XYChart.Series(); 
    series3.setName("Hand"); 
    XYChart.Series series5 = new XYChart.Series(); 
    series5.setName("Box"); 

    for (int i = 0; i < G.getRoundsSize(); i++) { 
     series1.getData().add(new XYChart.Data(Integer.toString(i + 1), G.getRound(i).getPlayerRoundData(0).getPegPoints())); 
     series3.getData().add(new XYChart.Data(Integer.toString(i + 1), G.getRound(i).getPlayerRoundData(0).getHandPoints())); 
     series5.getData().add(new XYChart.Data(Integer.toString(i + 1), G.getRound(i).getPlayerRoundData(0).getBoxPoints())); 
    } 
    bc1.getData(). addAll(series1, series3, series5); 
    bc1.setBarGap(0); 
    bc1.setCategoryGap(1.0); 
    bc1.setMaxHeight(180); 
    bc1.setMinHeight(180); 
    if(G.getRoundsSize() < 8){ 
     int wid = ((G.getRoundsSize() * 100) + 30); 
     bc1.setMaxWidth(wid); 
     bc1.setMinWidth(wid); 
    } else { 
     bc1.setMaxWidth(830); 
     bc1.setMinWidth(830); 
    } 
    barchart1.getChildren().add(bc1); 
相關問題