2015-09-02 70 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

谢谢你的提示,我没有深查等等。 –