I released version 0.2 of the JFXUtils project I started recently, and now there is code for chart panning, and zooms are now animated. With panning and zooming working, I noticed that the default NumberAxis was not working at all how I would like. The tick positions remain in the same place no matter what the graph's bounds, and the values of the ticks then change to reflect the value. Well, with zooming and panning you will get for example a lower bound of "1432.34234", and this is exactly what NumberAxis will display. So, I created a replacement axis type called StableTicksAxis that keeps the ticks at the same data location for the given zoom level, which has a drastically better UI feel when the graph is changing rapidly during panning and zooming operations. It automatically computes the number and distance between tick marks based on the size of the graph, the graph label font, and the range of data displayed to maximize the number of tick marks without having the labels run into each other. When auto-ranging, it can force zero in the view like NumberAxis, and also like NumberAxis it can add some padding around the data, but unlike NumberAxis the amount of padding (as a percentage of graph size) is configurable.
Here is a screenshot of the example application using NumberAxis, after some panning and zooming operations:
And here are the results with StableTicksAxis:
The StableTicksAxis is still a bit of work in progress. I still plan on making more improvements and tweaks as I go along. For example the number of minor ticks is set at 3 and is not configurable, nor are the dividers. The code should be able to handle it, I just have them as private static fields rather than properties for now until I'm 100% sure about the code and until I find a good set of validation rules to keep from picking unreasonable parameters. Also, I'm not positive that the tick calculation logic will handle very large or small values very well. I also think when used as a vertical axis, the labels are a bit too close together, even though they don't overlap. The way padding is calculated when forceZeroInRange is true could also be improved slightly (although it's not bad at all now).
Here is the full list of changes: