【问题标题】:How can I display a JFreeChart in web browser with Stripes Framework如何使用 Stripes 框架在 Web 浏览器中显示 JFreeChart
【发布时间】:2009-12-29 15:31:39
【问题描述】:

情况是这样的: 我的“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);

【问题讨论】:

    标签: java web-applications jfreechart stripes


    【解决方案1】:

    我已经写了一个这样的应用程序,所以我可以向你保证它是可行的:)

    首先,您需要摆脱任何 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 页面中添加图片,您可以将具有不同 URL 的 <img> 链接插入到您的 HTML 页面中,而您仍然只是返回一个充满文本的页面。浏览器 then 继续并通过触发对<img> 标记中提到的那些 URL 的请求来请求图像。当您的图像只是文件系统中的文件时,这非常容易。如果您想要动态生成的图像(例如图表),那么您必须为要生成的每种图像想出一个 URL,并将这些 URL 中的每一个映射到一个知道如何生成此类图像的 servlet。

    我的应用在一个页面上有 4 个不同的图表,所以我的 HTML 页面有 4 个 <img> 标记和 4 个不同的 URL,它们都映射到同一个图表生成 servlet,但是 URL 中有一些参数告诉 servlet想要什么样的图表。收到请求后,servlet 将执行 JFreeChart 魔术,然后使用ChartUtilities.writeChartAsPNG() 将生成的图像转储到 servlet 的输出流。

    【讨论】:

    • 好吧是的不是'ChartUtilities.saveChartAsPNG();'只是将图表保存到文件系统中?我希望用户能够输入变量,然后在浏览器中直接显示一个图表。我能用你提供给我的代码做到这一点吗?非常感谢
    • 不,这就是我所说的“高级”选项。我会用一些提示更新我的答案。
    【解决方案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”标签。显然你可以给它传递参数等等。

    【讨论】:

      【解决方案3】:

      如果您想留在 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
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-08-06
        • 2013-12-22
        • 2018-07-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多