Monday, December 16, 2013

DateAxis310

Aloha everybody,
Last week I was traveling to Dierk König in Zurich by train which gave me some time for some coding...as always :)
Because I use JSR310 (date and time API) in my Sensor Network project and I was trying to visualize some data in a JavaFX line chart.
In principle this should be no problem BUT there is no date axis in the JavaFX charts API.
Lucky me that some people ran into the same problem before me and created a date axis already. There are two implementations I knew which are the one from Pedro Duque Vieira (@P_Duke) which you could find here

http://pixelduke.wordpress.com/2013/12/13/dateaxis-and-xybarchart-update/

the other date axis implementation was made by Christian Schudt and can be found here

http://myjavafx.blogspot.de/2013/09/javafx-charts-display-date-values-on.html

Both implementations are using java.util.Date and so are not usable for me (well you can of course use the Instant class to convert LocalDateTime to Date but I don't like that approach). 
So I converted the implementation from Christian Schudt (because it was the first I found on the web) to a version that takes java.time.LocalDateTime instead of java.util.Date.
I focused really on getting things to work and it might be that the result is not 100% bullet proof, so feel free to test it, fork it or submit patches.
The next little problem I ran into was the missing StringConverter that can convert java.time.LocalDateTime values into a String...so I created one :)
With this you can now define the format of the date axis labels which is really useful.

For those of you who can't wait to get the code...please find a little repository on bitbucket here which contains the sources and a little demo:

https://bitbucket.org/hansolo/dateaxis310

Now there's not much more to say than thanx to Pedro and Christian for their work and to show you a little screenshot of the DateAxis310 in action...


If you would like to see some code...here you go...

// Use a special StringConverter to format axis labels
StringConverter<LocalDateTime> stringConverter = 
  new StringConverter<LocalDateTime>() {
    @Override public String toString(LocalDateTime localDateTime) {
      DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd.MM.yy\nHH:mm:ss");
      return dtf.format(localDateTime);
    }
    @Override public LocalDateTime fromString(String s) {
      return LocalDateTime.parse(s);
    }

};

// Create a new DateAxis
DateAxis310 dateAxis = new DateAxis310();    
dateAxis.setTickLabelFormatter(stringConverter);

// Create a new NumberAxis
NumberAxis numberAxis = new NumberAxis();
numberAxis.setLabel("Temperature [°C]");

// Create a data series
XYChart.Series series = new XYChart.Series<LocalDateTime, Number>();

series.setName("Temperature [°C]");

// Now add some data to the series
List<XYChart.Data<LocalDateTime, Number>> data = new ArrayList<>();
data.add(new XYChart.Data<>(LocalDateTime.of(2013, 1, 13, 0, 0, 0), 8));
data.add(new XYChart.Data<>(LocalDateTime.of(2013, 2, 27, 0, 0, 0), 4));
data.add(new XYChart.Data<>(LocalDateTime.of(2013, 3, 27, 0, 0, 0), 1));
data.add(new XYChart.Data<>(LocalDateTime.of(2013, 4, 27, 0, 0, 0), 7));
data.add(new XYChart.Data<>(LocalDateTime.of(2013, 5, 27, 0, 0, 0), 5));
data.add(new XYChart.Data<>(LocalDateTime.of(2013, 6, 27, 0, 0, 0), 3));

series.getData().setAll(data);        

// Create the LineChart
LineChart<LocalDateTime, Number> lineChart = 
  new LineChart<>(dateAxis, numberAxis);
lineChart.setTitle("Temperature Chart");
lineChart.getData().add(series);

lineChart.setAnimated(false);
...

As you can see the DateAxis310 can be used in the same way as the other axis of the JavaFX chart api.

And that's it for today...keep coding...

1 comment: