Curve fitting and styling AreaChart

I was experimenting today with extending AreaChart to do curve fitting for some example code I was hacking on. It is also a example of what can be done with styling JavaFX charts with CSS. Here is the result:

Curve Fitting

I have to admit I did not work out all the Math myself for the curve fitting I found a great article on CodeProject “Draw a Smooth Curve through a Set of 2D Points with Bezier Primitives”. Then ported the code to Java from C# and wired it up to our AreaChart. My version is not the most efficient as we do not yet have the correct API hooks to make it easy but we are thinking about how to add them. The current implementation extends AreaChart and overrides the layoutPlotChildren() method. That method creates all the nodes need for the chart and populates the node properties of the Series and Data items. So I can call super to let the standard code do its job then look at the Path elements for the stroked Path and filled Path that make up the AreaChart. I can then replace the LineTo elements with CubicCurveTo with the new control points calculated with the maths from the article. This way everything like auto ranging and animation still works as expected. The only waste is we are creating all the LineTo object and then throwing them away to replace them with CubicCurveTo objects. So here is the code that does this:

CSS Styling

This is just the standard AreaChart in terms of the nodes its drawing with. The first part of the CSS is styling the main chart node and its background. We are using a dark gray texture as the background, adding a 1px black border and a drop shadow. Also adjusting the padding a little.

Next we are looking at the background of the plot area, this is the rectangular area bordered by the two axis. We are using two background images here one a colored glow and the second is transparent white gridlines. The first image is sized to “cover” the whole area of the plot background and the second is tiled to fill. We also add black borders to the top and right to complete a box around the plot area including the two axis lines.

The line that connects the data points we are styling to be 2px wide and white.

.chart-series-area-line {
-fx-stroke: white;
-fx-stroke-width: 2px;
}

The filled area under the line we are styling with a linear gradient from white on the left to 100% transparent white on the right. We also use a blend mode to get the desired effect when blending with the colored background of the plot area.

Source Code

14 Comments

There seems to be a problem with the deployment. I am using chrome, I had to set “always run java vm for this site”, and then hit refresh button to make the example run. Only setting “always run java vm for this site” isn’t enough.

Great Effort,
but when i try to change the class to extend LineChart
i get a RuntimeException
Caused by: java.lang.ClassCastException: javafx.scene.shape.Path cannot be cast to javafx.scene.Group at CurvedFittedAreaChart.layoutPlotChildren(CurvedFittedAreaChart.java:28)
any comments ?

Great job,
I`ve try use your smooth line area chart with a line chart, I have a problem with cast exception in here:
final Path seriesLine = (Path)((Group)series.getNode()).getChildren().get(1);
final Path fillPath = (Path)((Group)series.getNode()).getChildren().get(0);

There is an issue with the graph. For example if we try to build a line through the points (2,2) (6,6) and (12,7) (**hence not starting from origin 0) there is an extension of the graph from the initial point (in our case (2,2)). The line graph does not start at (2,2) but lets say (1.5, 1.75). Any idea how to fix this?