I created a simple "business" sample app, including a report screen that uses a Barchart3D. But this is JavaFX, supposedly enabling business apps less boring than with Java+JFreeChart, so I wanted an animated chart, with this concept: when the screen is presented, all bars start at 0, and they "grow" up to the correct size for each dataset. No problem, I though: just create the dataset with bindings like
BarChart.Data { category: product.name value: bind product.units * zoom }
...where zoom is a variable that my animation timeline varies from 0 to 1 in 0,5 seconds.
The code works, but performance is terrible. The charts is updated at ~2fps maximum; there is clearly no incremental behavior, the entire chart is being reconstructed at each keyframe. I was under the delusion that once BarChart3D creates an initial drawing - which is basically a tree of scenegraph nodes - it could keep the binding of dataset values to properties of objects like the bar heights, so incremental changes driven by binding should be wicked fast. But it doesn't work that way.
My workaround was changing strategy, with a new animation that just zooms and rotates the entire chart with binding to BarChart3D's scaleX / scaleY / rotate properties. This worked very well, it's fast even in JavaFX Mobile.
Now in retrospect, I realize that my idea is not that simple to implement because the construction of the chart should have the ability to "propagate" bindings to the graphical nodes that compose the chart, and this may be difficult to do with a general solution that doesn't impose any cost in the more common case of input properties with no binding. But maybe you can do that just for some important cases, like the property Data.value, that is the most obvious candidate to benefit from smooth animation.
A different strategy could be: let the Chart classe have a method, or a read-only property, that returns the tree of scenegraph objects created to render that chart. Then I can have keyframe actions that navigate in this tree, locating specific shape objects that represent the bars, and change their height. This wouldn't be difficult or fragile if the chart builder assigns decent IDs to important nodes; and I can certainly imagine other useful reasons to have access to the chart's low-level scenegraph tree.
***
Now another problem with the same program. With the animated bar, it works reliably (although slowly) with the default timeline length of 0,5s. But if I change that to 5s so I can better evaluate its performance, the animation happens, but the JVM uses increasingly more memory, and it keeps using a full CPU core when the animation stops... and a few second after that the JVM crashes with a java.lang.OutOfMemoryError: Java heap space. Even in the "fixed" program where I only zoom and rotate the chart, if I enter and leave the report screen several times, each time repeating the chart animation, the JVM's memory grows a few Mb in each iteration until it finally dies with OOME. So there is evidence of some pretty bad memory leaking from the chart.
I can provide the program privagely, if it helps (although it's a pretty basic chart + animation sample); I just don't attach it in the bug because it's sample code for a magazine article that's yet unpublished.
BarChart.Data { category: product.name value: bind product.units * zoom }
...where zoom is a variable that my animation timeline varies from 0 to 1 in 0,5 seconds.
The code works, but performance is terrible. The charts is updated at ~2fps maximum; there is clearly no incremental behavior, the entire chart is being reconstructed at each keyframe. I was under the delusion that once BarChart3D creates an initial drawing - which is basically a tree of scenegraph nodes - it could keep the binding of dataset values to properties of objects like the bar heights, so incremental changes driven by binding should be wicked fast. But it doesn't work that way.
My workaround was changing strategy, with a new animation that just zooms and rotates the entire chart with binding to BarChart3D's scaleX / scaleY / rotate properties. This worked very well, it's fast even in JavaFX Mobile.
Now in retrospect, I realize that my idea is not that simple to implement because the construction of the chart should have the ability to "propagate" bindings to the graphical nodes that compose the chart, and this may be difficult to do with a general solution that doesn't impose any cost in the more common case of input properties with no binding. But maybe you can do that just for some important cases, like the property Data.value, that is the most obvious candidate to benefit from smooth animation.
A different strategy could be: let the Chart classe have a method, or a read-only property, that returns the tree of scenegraph objects created to render that chart. Then I can have keyframe actions that navigate in this tree, locating specific shape objects that represent the bars, and change their height. This wouldn't be difficult or fragile if the chart builder assigns decent IDs to important nodes; and I can certainly imagine other useful reasons to have access to the chart's low-level scenegraph tree.
***
Now another problem with the same program. With the animated bar, it works reliably (although slowly) with the default timeline length of 0,5s. But if I change that to 5s so I can better evaluate its performance, the animation happens, but the JVM uses increasingly more memory, and it keeps using a full CPU core when the animation stops... and a few second after that the JVM crashes with a java.lang.OutOfMemoryError: Java heap space. Even in the "fixed" program where I only zoom and rotate the chart, if I enter and leave the report screen several times, each time repeating the chart animation, the JVM's memory grows a few Mb in each iteration until it finally dies with OOME. So there is evidence of some pretty bad memory leaking from the chart.
I can provide the program privagely, if it helps (although it's a pretty basic chart + animation sample); I just don't attach it in the bug because it's sample code for a magazine article that's yet unpublished.