簡體   English   中英

如何在Stripes Framework的Web瀏覽器中顯示JFreeChart

[英]How can I display a JFreeChart in web browser with Stripes Framework

情況就是這樣:我的'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);

我寫了這樣的應用程序,所以我可以向你保證這是可行的:)

首先,你需要擺脫任何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頁面中插入帶有不同URL的<img>鏈接,而您仍然只是返回一個充滿文本的頁面。 然后瀏覽器繼續並通過發射過在提到的URL的請求請求圖像<img>標簽。 當您的圖像只是文件系統中的文件時,這非常容易。 如果您想要動態生成的圖像(如圖表),則必須考慮要生成的每種圖像的URL,並將每個URL映射到知道如何生成此類圖像的servlet。

我的應用程序在一個頁面上有4個不同的圖表,因此我的HTML頁面有4個帶有4個不同URL的<img>標記,這些標記都映射到同一個生成圖表的servlet,但是URL中有一些參數告訴servlet什么類型的圖表被通緝。 收到請求后,servlet將執行JFreeChart魔術,然后使用ChartUtilities.writeChartAsPNG()將生成的圖像轉儲到servlet的輸出流。

您需要編寫一個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”標記。 顯然你可以傳遞參數等。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM