情况如下: 我的'metrics.jsp'页面提交了创建图表所需的几个变量。 'ProjectActionBean.java'调用了一些创建JFreeChart的其他java类。我可以在弹出窗口中显示图表,但我希望它显示在原始浏览器窗口中。
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);
答案 0 :(得分:5)
我写了这样的应用程序,所以我可以向你保证这是可行的:)
首先,你需要摆脱任何GUI。您只是在服务器上没有GUI。这意味着您的ChartFrame frame
被转储。我创建图表的主要例程如下:
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);
}
这会创建一个文件,您可以从网页上将其作为<img>
提供。或者(但更高级),您可以使用ChartUtilities创建一个流,您可以提供该流以响应对图像URL的请求。
需要的另一个神奇之处就是告诉Java你在没有GUI的情况下运行图形代码。您需要设置环境变量
-Djava.awt.headless=true
对于像Tomcat这样的Web应用服务器,这将进入Tomcat启动脚本。
<强>更新强>
好的,是的,不是'ChartUtilities.saveChartAsPNG();'只需将图表保存到文件系统中?我希望用户能够输入变量,然后在浏览器中直接将图表显示回来。
只要您只有一个用户,将图像写入文件系统就可以适用于您描述的场景。事实上,这就是我的第一个版本的工作方式:我的HTML响应页面中有4个<img>
标签,来自用户指定参数的表单;那些用我的图像指出了4个文件的名字。只要在将答案返回给用户之前完成这些文件的编写,这就可以了。
当您有多个用户时会出现问题。他们最终可以查看其他用户指定的图表。将用户的ID或会话编码到图表文件名中有可能的解决方法,但这很快就会变得难看。有一种更好的方法,基于每个图像的按需动态生成,单独使用。
我不知道你对HTML / HTTP有多了解,所以我希望我不会厌倦你:
对于任何给定的HTTP请求,您只能返回单个数据流。通常,这是一个HTML页面,即文本流。如果您想要HTML页面中的图片,则可以在HTML页面中插入包含不同网址的<img>
个链接,并且仍然只返回一个充满文字的页面。浏览器然后继续并通过触发<img>
标记中提到的那些URL的请求来请求图像。当您的图像只是文件系统中的文件时,这非常容易。如果您想要动态生成的图像(如图表),则必须考虑要生成的每种图像的URL,并将每个URL映射到知道如何生成此类图像的servlet。
我的应用程序在一个页面上有4个不同的图表,所以我的HTML页面有4个<img>
标签,其中有4个不同的URL都映射到同一个图表生成servlet,但是URL中有一些参数被告知servlet需要什么样的图表。收到请求后,servlet将执行JFreeChart魔术,然后使用ChartUtilities.writeChartAsPNG()
将生成的图像转储到servlet的输出流。
答案 1 :(得分:2)
您需要编写一个servlet,它将图像(字节流)写入到客户端的输出流中。无需创建文件。基本上这样的事情应该有效:
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();
}
}
然后将其映射到web.xml中的某个url,并使用HTML / JSP中的“img”标记。显然你可以将参数传递给它等。
答案 2 :(得分:1)
如果你想留在Stripes框架内,你可以使用StreamingResolution的自定义扩展,因此:
创建一个新的常规ActionBean实现,它将代表您的图表的URL(包含在您的img标记中):
@DefaultHandler
public Resolution view() {
JFreeChart chart = ...
return new ChartStreamingResolution(chart);
}
自定义StreamingResolution看起来像这样:
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
}
}
}