JavaFX Charts

JavaFX has some pretty charts in the latest 1.2 SDK.  This post has a general overview, including the javafx.scene.chart class hierarchy and a great demo of all the charts with an excellent click transition.

image image  image

1d vs 2d (Pies vs Everything Else)

Well lets go 1d, a pie chart.  The series of data that fits a pie chart is just a pie label and its value

   1: def pieChart = PieChart {

   2:     title: "Sample Pie"

   3:     data: [

   4:         PieChart.Data { label: "Apples" value: 34  }

   5:         PieChart.Data { label: "Oranges" value: 27 }

   6:         PieChart.Data { label: "Bananas" value: 16 }

   7:         PieChart.Data { label: "Grapes" value: 50 }

   8:         PieChart.Data { label: "Cherries" value: 6 }

   9:         PieChart.Data { label: "Raspberry" value: 7 }

  10:     ]

  11: }

Code snippet taken from How do I create charts and graphs? – not much of a tutorial, but a link to some better references later.

The most important thing is that most charts, with the exception of the pie chart, inherit from XYChart. 

This means that while you may think a simple Bar Chart is just a series of Y values, its actually a bunch (series) of X categories with a complimentary data series (or two or three or more) plotted against those category values.  In the below example are 5 x-categories, with three data series (each a different colour)


I would think there should be a SimpleBarChart which only takes one data series and has an interface more like a pie chart, I think it would be a fun exercise as a JavaFX student to roll your own, extend chart, perhaps use Mixins of various pie-chart features (if possible)

The concept of two axis lends itself better to line charts where you are plotting anywhere in the XY space that is allowed.

BarChart Gotchas

Its not as automatic as you’d like.  The BarChart wouldn’t display until I defined my XCategories and set my Y limits (valueAxis). 

   1: BarChart {

   2:     categoryAxis: CategoryAxis {

   3:         categories: ["Child", "Teen", "Peaking", "Middle-Aged", "Grand-parenting", "Refined"]

   4:     }

   5:     valueAxis: NumberAxis {

   6:         lowerBound: 0

   7:         upperBound: 80

   8:         tickUnit: 10

   9:         label: "Age"

  10:     }

It would be nice in future to have an auto-resize=true flag which does as much magic as the proportional: true flag in the LinearGradient class.

Setting Data in Bar Charts

Order is important in the series, as you add a datapoint to the series, it gets assigned in a Bar Chart to the first item in the categories above.

Although a category field exists in the Data item, it doesn’t correlate to the category in the X-axis above.

   1: data: [BarChart.Series {

   2:         name: "The series",

   3:         data: [

   4:             BarChart.Data {category: "Child", value: 10},

   5:             BarChart.Data {category: "Refined", value: 80},

   6:             BarChart.Data {category: "Peaking", value: 25},

   7:             BarChart.Data {category: "Middle-Aged", value: 40}

   8:             BarChart.Data {category: "Grand-parenting", value:60}

   9:             BarChart.Data {category: "Teen", value:16}

  10:         ]}

  11:      ]


The data follows the order of the series, the category in the BarChart.Data literal is ignored – likely used for a different purpose :)  Note to self, RTM (or perhaps file a bug, what I read in the API sounds like I’m doing it right?)


Binding the data to a variable

The bar charts data and categories can be bound to another variable, and the variable updated by something else.  In the below code I was able to add an onMouseClicked event to the bar chart so that when the series title or one of the existing bars were clicked, an additional category and random value data point where added to the chart.


Other Intro’s to JavaFX Charts

Creating XYCharts in JavaFX – The continuation of Dean Iverson’s blog about how to do each of the XY Charts, nice use of the for loop function to prepare the chart data.

Animated Bar Charts – Sexy way to dress up the bars with Fills (gradients or different coloured paints for the bars) and KeyFrames to animate them

What’s New In JavaFX 1.2 Technology: JavaFX Charts – The most detailed blog entry I found about charts from Sun/Oracle so far.  It actually went in depth to all chart types quite well and covered feeding in data from an RSS feed for a stock graph application

Paul Bakker

JavaFX Folder Visualiser – Using BackgroundTasks to update a folder pie chart view

JavaFX Charts – A great rundown of all the chart types with their usage

Interactivity with Web Services

So what about interactivity?  Live feeds from RESTful services are done with the HTTPRequest, then invoking a PullParser on it.  The ShoppingMashup is the first simple example of this, but its real simple and doesnt get too much into the how.

The first thing I had to do though was learn how to use Web Services in WS.  Not wanting to go too off topic, there is a HTTPRequest and a PullParser.  The PullParser does the work of reading an input stream from the HTTPRequest and processing a JSON or XML request.  My issue with it just seems to be the way that you access the XPath or JSON data.  I would have liked a more concise interface, too many if START_ARRAY_ELEMENT, if END_VALUE to make it feel testable.  And you can’t use the same uniform interface to read a JSON resource as you do an XML one.  No where near as simple as what you can get through Grails. I’ll elaborate in a future post.

The best examples to help me get started on a JSON feed though was Coffee Shop, in particular JSONPullParser.fx.  Other tutorials for talking to RESTful service that may help: JavaFX RESTful Web Services Invocation (using XML to talk to a home grown feed), pet catalog javafx example application and JavaFX Twitter Client – all referenced from Connect to a web service or RSS feed on the JavaFX Learn page

See TwitterTrend.fx and TwitterTrendClient.fx

My next TODO is to poll a few days worth of twitter trends and graph them.  And since this post has gone on long enough, I’ll defer that to my next one 🙂