How can I show JFreeChart in a web browser using the Stripes Framework

This is the situation: My page "metrics.jsp" contains a couple of variables that are needed to create a chart. "ProjectActionBean.java" calls several other Java classes that create JFreeChart. I can display the chart in a popup, but I want it to appear in the original browser window.

JFreeChart placeChart = ChartFactory.createBarChart( "ChartName", "", //x-axis label "", //y-axis label dataset, PlotOrientation.VERTICAL, false, //legend true, //tooltype false); //generate urls ChartFrame frame = new ChartFrame(name, placeChart); frame.pack(); frame.setVisible(true); 
+4
source share
3 answers

I wrote an application like this, so I can assure you that this is possible :)

Firstly, you need to get rid of all that graphical interface. You simply do not have a graphical interface on the server. This means that your ChartFrame frame reset. My basic procedure for creating a chart is as follows:

  private void createChart(XYPlot plot, String fileName, String caption) throws IOException { JFreeChart chart = new JFreeChart(caption, plot); chart.addSubtitle(this.subtitle); if (plot.getRangeAxis() instanceof LogarithmicAxis) { chart.addSubtitle(1, new TextTitle("(logarithmische Skala)")); } File file = new File(fileName); file.delete(); ChartUtilities.saveChartAsPNG(file, chart, CHART_WIDTH, CHART_HEIGHT); } 

This creates a file that you can use as an <img> on its website. Alternatively (but slightly more advanced), you can use ChartUtilities to create a stream that you can serve in response to a request for an image URL.

Another magic that is required is to tell Java that you are using graphical code without a graphical interface. You need to set the environment variable

 -Djava.awt.headless=true 

For a web application server such as Tomcat, this is included in the launch of the Tomcat script.


Update

ok yes no "ChartUtilities.saveChartAsPNG ();" just save the diagram in the file system? I want the user to be able to enter variables, and then the graph is displayed directly in the browser.

As long as you have only one user, writing images to the file system will work well for the scenario you are describing. In fact, this is how my first version worked: I had 4 <img> tags on my HTML response page from a form where the user specified the parameters; and they pointed to the names of 4 files with my images. Until you finish writing these files before returning the response to the user, this works fine.

Problems arise when you have multiple users. They can view views of graphs specified by another user. There are possible workarounds with encoding the user or session identifier in the diagram file names, but this becomes terribly real. There is a better way based on the dynamic generation of each image on demand individually.

I don't know how much you know about HTML / HTTP, so I hope I'm not going to bother you:

For any given HTTP request, you can return only one data stream. This is usually an HTML page, i.e. a stream of text. If you need images on your HTML page, you insert <img> links with different URLs into your HTML page, and you still just return the page with text. Then the browser goes ahead and requests images, selecting requests for those URLs that are indicated in the <img> tags. It is quite simple when your images are just files in the file system. If you need dynamically generated images, such as diagrams, then you need to come up with a URL for each type of image that you want to create, and map each of these URLs to a servlet that knows how to create such an image.

My application had 4 different diagrams on the same page, so my HTML page had 4 <img> tags with 4 different URLs that were mapped to the same servlet that produced the diagram, but there were some in the URL specified by the servlet parameters what kind of chart was needed. Upon receiving the request, the servlet will perform the JFreeChart magic, and then it will use ChartUtilities.writeChartAsPNG() to dump the generated image into the servlet output stream.

+5
source

You need to write a servlet that writes the image (stream of bytes) to the output stream for the client. No need to create files. Basically something like this should work:

 public class ChartServlet extends HttpServlet { @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException { JFreeChart chart = .. // create your chart ByteArrayOutputStream bos = new ByteArrayOutputStream(); ChartUtilities.writeChartAsPNG(bos, chart, width, height); response.setContentType("image/png"); OutputStream out = new BufferedOutputStream(response.getOutputStream()); out.write(bos.toByteArray()); out.flush(); out.close(); } } 

Then map it to some URL in your web.xml and use the "img" tag in HTML / JSP. Obviously, you can pass parameters to it, etc.

+2
source

If you want to stay within the Stripes framework, you can use the StreamingResolution custom extension, this way:

Create a new regular ActionBean implementation that will represent the URL of your diagram (for inclusion in your img tag):

 @DefaultHandler public Resolution view() { JFreeChart chart = ... return new ChartStreamingResolution(chart); } 

Custom StreamingResolution will look like this:

 public class ChartStreamingResolution extends StreamingResolution { private JFreeChart chart; public ChartStreamingResolution(JFreeChart chart) { super("image/png"); this.chart = chart; } @Override public void stream(HttpServletResponse response) { try { ByteArrayOutputStream bos = new ByteArrayOutputStream(); ChartUtilities.writeChartAsPNG(bos, chart, 400, 200); OutputStream out = new BufferedOutputStream(response.getOutputStream()); out.write(bos.toByteArray()); out.flush(); out.close(); } catch (Exception e) { //something sensible } } } 
+1
source

All Articles