6

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.

JSON C11
  • 11,272
  • 7
  • 78
  • 65
Jiri Pur
  • 73
  • 3

1 Answers1

10

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);
    }
}
James_D
  • 201,275
  • 16
  • 291
  • 322
  • It works for me but I had to modify your code considerably to get a working example. (Eg what is `DateAxis`?). Can you expand the code in the question into a [MCVE]? – James_D Feb 10 '16 at 14:54
  • ok, my apologies. DateAxis is opensource code for date axis in javafx(http://myjavafx.blogspot.cz/2013/09/javafx-charts-display-date-values-on.html). But even if i tried it with Number axis i still have same results(Chart with values without series). And thats almost all , except imports and name of the class. – Jiri Pur Feb 10 '16 at 15:03
  • See update. You might need `applyCss()` and `layout()`. – James_D Feb 10 '16 at 15:05
  • That probably fixes your other question too. Please mark this as correct if it answers the question. – James_D Feb 10 '16 at 15:13
  • You don't need any reputation to mark a question as correct (which is not the same as voting); you will actually gain reputation by doing so. Just click on the check mark. – James_D Feb 10 '16 at 15:24