2015-09-02 54 views
2

我正在開發一個應用程序使用一些StackedBarChart,但我發現我認爲是一個小錯誤,如果圖表的動畫屬性設置爲false,則不呈現負值。試試下面的代碼來測試它,任何人都知道如何解決它?Javafx StackedBarChart bug

在此先感謝。

import javafx.application.Application; 
import javafx.application.Platform; 
import javafx.event.EventHandler; 
import javafx.scene.Scene; 
import javafx.scene.chart.CategoryAxis; 
import javafx.scene.chart.NumberAxis; 
import javafx.scene.chart.StackedBarChart; 
import javafx.scene.chart.XYChart; 
import javafx.scene.layout.VBox; 
import javafx.stage.Stage; 
import javafx.stage.WindowEvent; 

import java.text.SimpleDateFormat; 
import java.util.Date; 
import java.util.Locale; 

/** 
* Created by fabiofrumento on 28/04/15. 
*/ 
public class Scratch extends Application { 

    private static final SimpleDateFormat ONESECOND_CHART_DATE_FORMAT = new SimpleDateFormat("HH:mm:ss", 
                          Locale.ENGLISH); 
    private boolean stopThreads; 

    CategoryAxis xAxisActive = new CategoryAxis(); 
    CategoryAxis xAxisReactive = new CategoryAxis(); 
    NumberAxis yAxisActive = new NumberAxis(); 
    NumberAxis yAxisReactive = new NumberAxis(); 

    { 
     xAxisActive.setLabel("Time"); 
     xAxisReactive.setLabel("Time"); 
     yAxisActive.setLabel("animated = false"); 
     yAxisReactive.setLabel("animated = true"); 
    } 

    private StackedBarChart<String, Number> onesecondActiveBarChart   = new StackedBarChart<String, Number>(xAxisActive, 
                                yAxisActive); 
    private StackedBarChart<String, Number> onesecondReactiveBarChart  = new StackedBarChart<String, Number>(xAxisReactive, 
                                yAxisReactive); 
    private XYChart.Series<String, Number> onesecondActiveConsumedSerie = new XYChart.Series<>(); 
    private XYChart.Series<String, Number> onesecondActiveGeneratedSerie = new XYChart.Series<>(); 
    private XYChart.Series<String, Number> onesecondReactiveConsumedSerie = new XYChart.Series<>(); 
    private XYChart.Series<String, Number> onesecondReactiveGeneratedSerie = new XYChart.Series<>(); 

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

    @Override 
    public void start(Stage primaryStage) throws 
              Exception { 
     VBox root = new VBox(); 

     initCharts(); 

     root.getChildren() 
      .addAll(onesecondActiveBarChart, 
        onesecondReactiveBarChart); 
     Scene scene = new Scene(root, 
           1024, 
           768); 

     primaryStage.setTitle("JecomoduleUI"); 
     primaryStage.setScene(scene); 
     primaryStage.setFullScreen(true); 
     primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>() { 
      @Override 
      public void handle(WindowEvent event) { 
       stopThreads = true; 
      } 
     }); 

     primaryStage.show(); 
     new Thread(new Runnable() { 
      @Override 
      public void run() { 
       while (!stopThreads) { 
        try { 
         Thread.sleep(1000); 
         Platform.runLater(new Runnable() { 
          @Override 
          public void run() { 
           updateActiveData(); 
          } 
         }); 
        } catch (InterruptedException e) { 
         e.printStackTrace(); 
        } 
       } 
      } 
     }).start(); 

    } 

    private void initCharts() { 
     onesecondActiveConsumedSerie.setName("Cons. W"); 
     onesecondActiveGeneratedSerie.setName("Gen. W"); 
     onesecondReactiveConsumedSerie.setName("Cons. VAR"); 
     onesecondReactiveGeneratedSerie.setName("Gen.. VAR"); 
     onesecondActiveBarChart.getData() 
           .addAll(onesecondActiveConsumedSerie, 
             onesecondActiveGeneratedSerie); 
     onesecondActiveBarChart.setAnimated(false); 
     onesecondReactiveBarChart.getData() 
           .addAll(onesecondReactiveConsumedSerie, 
             onesecondReactiveGeneratedSerie); 
    } 

    void updateActiveData() { 
     Date format = new Date(); 
     Integer oneSecondActiveConsumedValue; 
     Integer oneSecondActiveGeneratedValue; 
     Double rand = Math.random(); 
     Integer rnd = new Double(1000l + rand * 9000l).intValue(); 
     if (rnd % 2 == 0) { 
      oneSecondActiveConsumedValue = rnd; 
      oneSecondActiveGeneratedValue = 0; 
     } else { 
      oneSecondActiveConsumedValue = 0; 
      oneSecondActiveGeneratedValue = 0 - rnd; 
     } 
     onesecondActiveConsumedSerie.getData() 
            .add(new XYChart.Data<String, Number>(ONESECOND_CHART_DATE_FORMAT.format(format), 
                      oneSecondActiveConsumedValue)); 
     if (onesecondActiveConsumedSerie.getData() 
             .size() > 10) 
      onesecondActiveConsumedSerie.getData() 
             .remove(0); 
     onesecondActiveGeneratedSerie.getData() 
            .add(new XYChart.Data<String, Number>(ONESECOND_CHART_DATE_FORMAT.format(format), 
                      oneSecondActiveGeneratedValue)); 
     if (onesecondActiveGeneratedSerie.getData() 
             .size() > 10) 
      onesecondActiveGeneratedSerie.getData() 
             .remove(0); 

     onesecondReactiveConsumedSerie.getData() 
             .add(new XYChart.Data<String, Number>(ONESECOND_CHART_DATE_FORMAT.format(format), 
                      oneSecondActiveConsumedValue)); 
     if (onesecondReactiveConsumedSerie.getData() 
              .size() > 10) 
      onesecondReactiveConsumedSerie.getData() 
              .remove(0); 
     onesecondReactiveGeneratedSerie.getData() 
             .add(new XYChart.Data<String, Number>(ONESECOND_CHART_DATE_FORMAT.format(format), 
                      oneSecondActiveGeneratedValue)); 
     if (onesecondReactiveGeneratedSerie.getData() 
              .size() > 10) 
      onesecondReactiveGeneratedSerie.getData() 
              .remove(0); 
    } 

} 

回答

3

是的,這似乎是一個JavaFX錯誤(Java 8u60)。

查看StackedBarChart的源代碼,只有在項目節點的樣式類中發現「否定」時,纔會正確繪製具有負值的項目(請參閱StackedBarChart#layoutPlotChildren)。

「負面」風格應由StackedBarChart#dataItemAdded設置。對於動畫圖表StackedBarChart#animateData被調用,其中如果項目的值爲負,則將「負面」樣式添加到節點。

對於非動畫數據,節點被添加到聊天的情節子節點中,而不更新樣式類。


作爲一種變通方法,覆蓋onesecondActiveBarChart的dataItemAdded

private StackedBarChart<String, Number> onesecondActiveBarChart = new StackedBarChart<String, Number>(xAxisActive, yAxisActive) { 
    @Override 
    protected void dataItemAdded(XYChart.Series<String,Number> series, int itemIndex, XYChart.Data<String,Number> item) { 
     super.dataItemAdded(series, itemIndex, item); 

     Node bar = item.getNode(); 
     double barVal = item.getYValue().doubleValue(); 

     if (barVal < 0) { 
      bar.getStyleClass().add("negative"); 
     } 
    }  
}; 
+0

謝謝你的提示,我沒有深查等等。 –