Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8091045

[XYChart] [ValueAxis] Robustness against null as data value

XMLWordPrintable

      There are typically three valid y-values for a x-value in a data-series:

      1) Regular value: y-value for a specific x-value is a regular number
      2) Erroneous value: y-value for a specific x-value is an erroneous value
      3) Not existing value: y-value for a specific x-value does not exist

      It seems to be natural that 2) is represented by y-value = Double.NaN and 3) by y-value = null.

      The current implementation of e.g. LineChart and NumberAxis does not visualizes a Series meaningful if other y-values then 1) (regular y-values) are present. But after all it does not throw an Exception if 2) (Double.NaN y-values) are present.
      But the current implementation does not accept 3) (null y-values)... a NullPointerException is thrown (see example below).

      Due to this behaviour it is impossible to write a custom chart based on XYChart and ValueAxis which can handle null y-values.

      Anyway, I would like to suggest the improvement that XYChart and ValueAxis are robust to the use of null as values.

      =============================================
      Example Use-Case:
      =============================================

      import javafx.application.Application;
      import javafx.collections.FXCollections;
      import javafx.collections.ObservableList;
      import javafx.scene.Scene;
      import javafx.scene.chart.LineChart;
      import javafx.scene.chart.NumberAxis;
      import javafx.scene.chart.XYChart.Data;
      import javafx.scene.chart.XYChart.Series;
      import javafx.stage.Stage;

      public class Test extends Application {

      @SuppressWarnings("unchecked")
      @Override
      public void start(Stage stage) throws Exception {
      Data<Number, Number> element1 = new Data<Number, Number>(1, 1);
      Data<Number, Number> element2 = new Data<Number, Number>(2, Double.NaN);
      Data<Number, Number> element3 = new Data<Number, Number>(3, 3);
      Data<Number, Number> element4 = new Data<Number, Number>(4, null);
      Data<Number, Number> element5 = new Data<Number, Number>(5, 5);
      ObservableList<Data<Number, Number>> dataList = FXCollections.observableArrayList(element1, element2, element3, element4, element5);
      Series<Number, Number> series = new Series<>(dataList);
      ObservableList<Series<Number, Number>> seriesList = FXCollections.observableArrayList(series);

      LineChart<Number, Number> root = new LineChart<Number, Number>(new NumberAxis(), new NumberAxis(), seriesList);
      stage.setScene(new Scene(root));
      stage.show();
      }

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

      }

      =============================================
      Exception:
      =============================================
      Exception in Application start method
      java.lang.reflect.InvocationTargetException
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.lang.reflect.Method.invoke(Method.java:483)
      at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:363)
      at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:303)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.lang.reflect.Method.invoke(Method.java:483)
      at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
      Caused by: java.lang.RuntimeException: Exception in Application start method
      at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:875)
      at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$147(LauncherImpl.java:157)
      at com.sun.javafx.application.LauncherImpl$$Lambda$48/128893786.run(Unknown Source)
      at java.lang.Thread.run(Thread.java:745)
      Caused by: java.lang.NullPointerException
      at javafx.scene.chart.ValueAxis.invalidateRange(ValueAxis.java:437)
      at javafx.scene.chart.LineChart.updateAxisRange(LineChart.java:176)
      at javafx.scene.chart.XYChart.layoutChartChildren(XYChart.java:663)
      at javafx.scene.chart.Chart$1.layoutChildren(Chart.java:88)
      at javafx.scene.Parent.layout(Parent.java:1074)
      at javafx.scene.Parent.layout(Parent.java:1080)
      at javafx.scene.Scene.doLayoutPass(Scene.java:532)
      at javafx.scene.Scene.preferredSize(Scene.java:1612)
      at javafx.scene.Scene.impl_preferredSize(Scene.java:1686)
      at javafx.stage.Window$9.invalidated(Window.java:765)
      at javafx.beans.property.BooleanPropertyBase.markInvalid(BooleanPropertyBase.java:109)
      at javafx.beans.property.BooleanPropertyBase.set(BooleanPropertyBase.java:143)
      at javafx.stage.Window.setShowing(Window.java:841)
      at javafx.stage.Window.show(Window.java:856)
      at javafx.stage.Stage.show(Stage.java:255)
      at de.lit.ribbonfx.Test.start(Test.java:29)
      at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$153(LauncherImpl.java:821)
      at com.sun.javafx.application.LauncherImpl$$Lambda$51/583498922.run(Unknown Source)
      at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$166(PlatformImpl.java:323)
      at com.sun.javafx.application.PlatformImpl$$Lambda$45/1051754451.run(Unknown Source)
      at com.sun.javafx.application.PlatformImpl.lambda$null$164(PlatformImpl.java:292)
      at com.sun.javafx.application.PlatformImpl$$Lambda$47/879507389.run(Unknown Source)
      at java.security.AccessController.doPrivileged(Native Method)
      at com.sun.javafx.application.PlatformImpl.lambda$runLater$165(PlatformImpl.java:291)
      at com.sun.javafx.application.PlatformImpl$$Lambda$46/1775282465.run(Unknown Source)
      at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
      at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
      at com.sun.glass.ui.win.WinApplication.lambda$null$141(WinApplication.java:102)
      at com.sun.glass.ui.win.WinApplication$$Lambda$37/1109371569.run(Unknown Source)
      ... 1 more
      Exception running application de.lit.ribbonfx.Test

            Unassigned Unassigned
            aliebelt Andreas Liebelt
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Imported: