4

これが状況です。私の「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);
4

3 に答える 3

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>これにより、 Web ページから提供できるファイルが作成されます。別の方法 (ただし、もう少し高度な方法) では、ChartUtilities を使用して、画像 URL の要求に応じて提供できるストリームを作成できます。

必要なもう 1 つのちょっとした魔法は、GUI なしでグラフィックス コードを実行していることを Java に伝えることです。環境変数を設定する必要があります

-Djava.awt.headless=true

Tomcat のような Web アプリケーション サーバーの場合、これは Tomcat の起動スクリプトに入ります。


アップデート

はい、「ChartUtilities.saveChartAsPNG();」はありません。グラフをファイル システムに保存するだけですか? ユーザーが変数を入力できるようにしてから、グラフをブラウザーに直接表示できるようにしたいと考えています。

ユーザーが 1 人しかいない限り、ファイル システムへのイメージの書き込みは、説明したシナリオで問題なく機能します。実際、私の最初のバージョンはこのように<img>動作しました。HTML 応答ページには、ユーザーがパラメーターを指定したフォームから 4 つのタグがありました。そして、私の画像を含む4つのファイルの名前を指しているもの。ユーザーに回答を返す前にこれらのファイルの書き込みを終了する限り、これは正常に機能します。

複数のユーザーがいる場合に問題が発生します。彼らは、他のユーザーが指定したグラフを表示することになる可能性があります。ユーザーの ID またはセッションをチャートのファイル名にエンコードすることで回避策が考えられますが、これは非常に高速です。各画像のオンデマンド動的生成に基づいて、より良い方法があります。

あなたが HTML/HTTP についてどれだけ知っているかはわかりませんが、これで退屈しないことを願っています。

特定の HTTP 要求に対して、単一のデータ ストリームのみを返すことができます。通常、これは HTML ページ、つまりテキストのストリームです。HTML ページに画像が必要な場合は<img>、別の URL を持つリンクをHTML ページに挿入します、テキストでいっぱいのページを返すだけです。ブラウザは次に進み、<img>タグに記載されている URL へのリクエストを開始して画像をリクエストします。これは、イメージがファイル システム内の単なるファイルである場合は非常に簡単です。グラフなどの画像を動的に生成する場合は、生成する画像の種類ごとに URL を考え、そのような画像を生成する方法を認識しているサーブレットにそれらの URL をそれぞれマップする必要があります。

私のアプリには 1 つのページに 4 つの異なるグラフがあったため、私の HTML ページには 4<img>つの異なる URL を持つ 4 つのタグがあり、それらはすべて同じグラフ生成サーブレットにマップされていましたが、URL には必要なグラフの種類をサーブレットに伝えるパラメータがいくつかありました。 . リクエストを受け取ると、サーブレットは JFreeChart マジックを実行しChartUtilities.writeChartAsPNG()、生成された画像をサーブレットの出力ストリームにダンプします。

于 2009-12-29T15:47:28.877 に答える
2

クライアントへの出力ストリームにイメージ (バイト ストリーム) を書き込むサーブレットを作成する必要があります。ファイルを作成する必要はありません。基本的に、次のようなものが機能するはずです。

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」タグから使用します。明らかに、パラメータなどを渡すことができます。

于 2009-12-29T17:34:02.323 に答える
1

Stripes フレームワーク内に留まりたい場合は、次のように StreamingResolution のカスタム拡張を使用できます。

チャートの URL を表す新しい通常の ActionBean 実装を作成します (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
        }
    }
}
于 2011-04-13T22:04:14.990 に答える