Charts
One of the totally new (and cool) features of JavaFX 1.2 is the chart package, which includes built-in classes for area, bar, bubble, line, pie, and scatter charts. Figure 15 shows an area chart, Figure 16 a bar chart, Figure 17 a line chart, and Figure 18 a pie chart.
Creating a chart in JavaFX is quite simple. You instantiate one of the chart objects by using an object literal, assign data elements, and then install the chart object into the JavaFX scene graph. The following code creates the pie chart in Figure 18:
var scene: Scene; def title = "Pie Chart"; Stage { title: title width: 500 height: 500 scene: scene = Scene { content: [ PieChart { width: bind scene.width height: bind scene.height title: title pieValueLabelFormater: function(sliceValue:Number, slicePercentage:Number):String { "{%.2f sliceValue} (%{%.1f slicePercentage})"; } pieLabelVisible: true data: [ PieChart.Data {label: "Apples" value: 1.6001}, PieChart.Data {label: "Oranges" value: 2.2}, PieChart.Data {label: "Peaches" value: 3.2}, PieChart.Data {label: "Cherries" value: 1.0}, ] } ] } }
Notice the pieValueLabelFormater instance variable in this example. One of the nice features of JavaFX is that variables can hold functions. In this case, the variable, pieValueLabelFormater, holds a function that formats the values contained within the pie wedges. For pie charts, the Data class is defined within the PieChart class and is referenced as PieChart.Data. Unlike the Java language, JavaFX allows you to declare other public classes within the same script file.
Another interesting capability of the chart classes is that they use the inherent JavaFX trigger mechanism to allow you to update the chart data in real time. Instead of statically defining the data, as in the previous pie chart example, you can periodically insert values into the chart's data. This feature is useful for plotting data that is constantly changing, such as a stock price graph. The following code shows how to do this for a line chart:
var series = LineChart.Series {}; Stage { title: title width: 500 height: 500 scene: scene = Scene { content: [ LineChart { width: bind scene.width height: bind scene.height title: title xAxis: NumberAxis { lowerBound: 0 upperBound: 1000 tickUnit: 100 } yAxis: NumberAxis { lowerBound: 0.0 tickUnit: 0.1 upperBound: 3.0 formatTickLabel: function(value:Number):String { "{%.2f value}"; } } data: series } ] } }
As in the earlier pie chart example, LineChart contains two other classes in addition to LineChart:
- LineChart.Series holds the chart series.
- LineChart.Data holds the chart data that's contained within a series.
Because the data sequence variable within the series has an on replace trigger, whenever the data is updated the graph display is simultaneously updated to show the new data item. To add the new data item, simply insert it into the series.data sequence. For example, an update function might take a new value as an argument, creating a new Data item that's inserted it into the series.data sequence:
function update(x:Number) : Void { insert LineChart.Data { xValue: x yValue: Math.log10(x) } into series.data; }
The chart display will update immediately to show the change.