I made a really short app, which uses javafx to generate a chart. App shows the right values(chart) but when I do snapshot, image shows just an axis and labels, but not the series and values.
stage.setTitle("Line Chart Sample");
final DateAxis xAxis = new DateAxis();
final NumberAxis yAxis = new NumberAxis();
xAxis.setLabel("Number of Month");
yAxis.setLabel("Count");
final LineChart<Date, Number> lineChart = new LineChart<>(xAxis,yAxis);
Scene scene = new Scene(lineChart,1000,700);
lineChart.setTitle("Stock Monitoring, 2010");
XYChart.Series series = new XYChart.Series();
series.setName("My portfolio");
series.getData().add(new XYChart.Data(new GregorianCalendar(2012, 11, 15).getTime(), 23));
series.getData().add(new XYChart.Data(new GregorianCalendar(2012, 11, 16).getTime(), 14));
series.getData().add(new XYChart.Data(new GregorianCalendar(2012, 11, 17).getTime(), 15));
series.getData().add(new XYChart.Data(new GregorianCalendar(2012, 11, 18).getTime(), 24));
series.getData().add(new XYChart.Data(new GregorianCalendar(2012, 11, 19).getTime(), 34));
series.getData().add(new XYChart.Data(new GregorianCalendar(2012, 11, 20).getTime(), 36));
series.getData().add(new XYChart.Data(new GregorianCalendar(2012, 11, 21).getTime(), 22));
lineChart.getData().add(series);
stage.setScene(scene);
stage.show();
WritableImage img = new WritableImage(1000, 700);
File file = new File("saved.png");
scene.snapshot(img);
RenderedImage renderedImage = SwingFXUtils.fromFXImage(img, null);
ImageIO.write(renderedImage,"png", file);
here is a saved file
here is a screenshot from app
I have no idea what I am doing wrong.
By default, charts are animated. The snapshot is happening before the (brief) animation is complete, so the data don't appear. Call
lineChart.setAnimated(false);
It is probably also sensible to force layout and application of CSS (which determines how the lines and nodes for the data are drawn). Typically these are only done on the first scene rendering, so it is possible your snapshot takes place before these happen. You need to do this by calling
lineChart.applyCss();
lineChart.layout();
after the chart has been added to a scene, and after the data have been added to the chart.
Here is an SSCCE:
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javafx.application.Application;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.Scene;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.image.WritableImage;
import javafx.stage.Stage;
public class SnapshotChart extends Application {
@Override
public void start(Stage stage) throws IOException {
stage.setTitle("Line Chart Sample");
final NumberAxis xAxis = new NumberAxis();
final NumberAxis yAxis = new NumberAxis();
xAxis.setLabel("Number of Month");
yAxis.setLabel("Count");
final LineChart<Number, Number> lineChart = new LineChart<>(xAxis,yAxis);
lineChart.setAnimated(false);
Scene scene = new Scene(lineChart,1000,700);
lineChart.setTitle("Stock Monitoring, 2010");
XYChart.Series<Number, Number> series = new XYChart.Series<>();
series.setName("My portfolio");
series.getData().add(new XYChart.Data<>(1, 23));
series.getData().add(new XYChart.Data<>(2, 14));
series.getData().add(new XYChart.Data<>(3, 15));
series.getData().add(new XYChart.Data<>(4, 24));
series.getData().add(new XYChart.Data<>(5, 34));
series.getData().add(new XYChart.Data<>(6, 36));
series.getData().add(new XYChart.Data<>(7, 22));
lineChart.getData().add(series);
lineChart.applyCss();
lineChart.layout();
stage.setScene(scene);
stage.show();
WritableImage img = new WritableImage(1000, 700);
File file = new File("saved.png");
scene.snapshot(img);
RenderedImage renderedImage = SwingFXUtils.fromFXImage(img, null);
ImageIO.write(renderedImage,"png", file);
}
public static void main(String[] args) {
launch(args);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With