Javafx StackedBarChart错误 [英] Javafx StackedBarChart bug

查看:64
本文介绍了Javafx StackedBarChart错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用一些StackedBarChart开发应用程序,但是我发现我认为是一个小错误,如果将图表的动画属性设置为false,则不会呈现负值.尝试下面的代码进行测试,有人知道如何解决吗?

I'm developing an application using some StackedBarChart but i've found what i think is a little bug, negative values are not rendered if the animated property of the chart is set to false. Try the code below to test it, anyone know how to solve it ?

谢谢.

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

}

推荐答案

是的,这似乎是JavaFX错误(Java 8u60).

Yes, this seems to be a JavaFX error (Java 8u60).

查看StackedBarChart的源代码,只有在项目节点的样式类中找到负"的情况下,才可以正确绘制负值的项目(请参见StackedBarChart#layoutPlotChildren).

Looking at the source code of StackedBarChart, an item with negative value gets drawn correctly only if "negative" is found in the style classes of the item's node (see StackedBarChart#layoutPlotChildren).

负"样式应由StackedBarChart#dataItemAdded设置.对于动画图表,将调用StackedBarChart#animateData,如果该项的值为负,则在节点上添加负"样式.

The "negative" style should be set by StackedBarChart#dataItemAdded. For animated charts StackedBarChart#animateData is called, where the "negative" style is added to the node if the item's value is negative.

对于非动画数据,将节点添加到聊天的绘图子级中,而无需更新样式类.

For non-animated data, the node gets added to the chat's plot children without updating the style class.

作为解决方法,请覆盖onesecondActiveBarChart的dataItemAdded:

As a workaround, override dataItemAdded of onesecondActiveBarChart:

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

这篇关于Javafx StackedBarChart错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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