comparison flys-artifacts/src/main/java/de/intevation/flys/exports/ChartExportHelper.java @ 152:956445dd601d

Added a helper class to export charts. flys-artifacts/trunk@1585 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Mon, 28 Mar 2011 10:48:27 +0000
parents
children 084995dd1c9c
comparison
equal deleted inserted replaced
151:4eddbb219866 152:956445dd601d
1 /*
2 * Copyright (c) 2011 by Intevation GmbH
3 *
4 * This program is free software under the LGPL (>=v2.1)
5 * Read the file LGPL.txt coming with the software for details
6 * or visit http://www.gnu.org/licenses/ if it does not exist.
7 */
8 package de.intevation.flys.exports;
9
10 import com.lowagie.text.Document;
11 import com.lowagie.text.DocumentException;
12 import com.lowagie.text.PageSize;
13 import com.lowagie.text.Rectangle;
14
15 import com.lowagie.text.pdf.PdfContentByte;
16 import com.lowagie.text.pdf.PdfTemplate;
17 import com.lowagie.text.pdf.PdfWriter;
18
19 import java.awt.Graphics2D;
20 import java.awt.Transparency;
21
22 import java.awt.geom.Rectangle2D.Double;
23
24 import java.awt.geom.Rectangle2D;
25
26 import java.awt.image.BufferedImage;
27
28 import java.io.IOException;
29 import java.io.OutputStream;
30 import java.io.OutputStreamWriter;
31 import java.io.UnsupportedEncodingException;
32
33 import javax.imageio.ImageIO;
34
35 import org.apache.batik.svggen.SVGGraphics2D;
36 import org.apache.batik.svggen.SVGGraphics2DIOException;
37
38 import org.apache.log4j.Logger;
39
40 import org.jfree.chart.JFreeChart;
41
42 import de.intevation.artifacts.CallContext;
43
44 import de.intevation.artifacts.common.utils.XMLUtils;
45
46
47 /**
48 * This class is a helper class which supports some methods to export charts
49 * into specific formats.
50 *
51 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
52 */
53 public class ChartExportHelper {
54
55 /**
56 * Constant field to define A4 as default page size.
57 */
58 private static final String DEFAULT_PAGE_SIZE = "A4";
59
60 /**
61 * Constant field to define UTF-8 as default encoding.
62 */
63 private static final String DEFAULT_ENCODING = "UTF-8";
64
65 /**
66 * Logger used for logging with log4j.
67 */
68 private static Logger log = Logger.getLogger(ChartExportHelper.class);
69
70
71 /**
72 * A method to export a <code>JFreeChart</code> as image to an
73 * <code>OutputStream</code> with a given format, width and height.
74 *
75 * @param out OutputStream
76 * @param chart JFreeChart object to be exported.
77 * @param format Format (e.g. png, gif, jpg)
78 * @param width Width, the image used to be
79 * @param height Height, the image used to be
80 *
81 * @throws IOException if writing image to OutputStream failed.
82 */
83 public static void exportImage(
84 OutputStream out,
85 JFreeChart chart,
86 String format,
87 int width,
88 int height
89 )
90 throws IOException
91 {
92 log.info("export chart as png");
93
94 ImageIO.write(
95 chart.createBufferedImage(
96 width, height, Transparency.BITMASK, null
97 ),
98 format,
99 out
100 );
101 }
102
103
104 /**
105 * A method to export a <code>JFreeChart</code> as SVG to an
106 * <code>OutputStream</code>.
107 *
108 * @param out OutputStream
109 * @param chart JFreeChart to be exported
110 * @param encoding Encoding, defaults to {@link #DEFAULT_ENCODING} if null
111 * @param width Width the svg used to be
112 * @param height Height the svg used to be
113 */
114 public static void exportSVG(
115 OutputStream out,
116 JFreeChart chart,
117 String encoding,
118 int width,
119 int height
120 ) {
121 log.info("export chart as svg");
122
123 if (encoding == null)
124 encoding = DEFAULT_ENCODING;
125
126 org.w3c.dom.Document document = XMLUtils.newDocument();
127 SVGGraphics2D graphics = new SVGGraphics2D(document);
128
129 chart.draw(graphics, new Rectangle2D.Double(0.0D, 0.0D,width,height));
130
131 try {
132 graphics.stream(new OutputStreamWriter(out, encoding));
133 }
134 catch (SVGGraphics2DIOException svge) {
135 log.error("Error while writing svg export to output stream.", svge);
136 }
137 catch (UnsupportedEncodingException uee) {
138 log.error("Unsupported encoding: " + encoding, uee);
139 }
140 }
141
142
143 /**
144 * A method to export a <code>JFreeChart</code> as PDF to an
145 * <code>OutputStream</code>.
146 *
147 * @param out OutputStream
148 * @param chart JFreeChart
149 * @param pageFormat String to specify a page format, {@link
150 * #DEFAULT_PAGE_SIZE} is used if no pageFormat is given
151 * @param landscape If this is true, the pdf is delivered in landscape
152 * format
153 * @param marginLeft Space to left border
154 * @param marginRight Space to right border
155 * @param marginTop Space to upper border
156 * @param marginBottom Space to lower border
157 */
158 public static void exportPDF(
159 OutputStream out,
160 JFreeChart chart,
161 String pageFormat,
162 float marginLeft,
163 float marginRight,
164 float marginTop,
165 float marginBottom,
166 CallContext context
167 ) {
168 log.info("export chart as pdf.");
169
170 if (pageFormat == null)
171 pageFormat = DEFAULT_PAGE_SIZE;
172
173 // max size of the chart
174 Rectangle page = PageSize.getRectangle(pageFormat);
175 float pageWidth = page.getWidth();
176 float pageHeight = page.getHeight();
177
178 // the chart width
179 int chartWidth = (Integer) context.getContextValue("chart.width");
180 int chartHeight = (Integer) context.getContextValue("chart.height");
181
182 boolean landscape = chartWidth > chartHeight ? true : false;
183
184 float width = 0;
185 float height = 0;
186 if (landscape) {
187 width = pageHeight;
188 height = pageWidth;
189 }
190 else {
191 width = pageWidth;
192 height = pageHeight;
193 }
194
195 float spaceX = width - marginLeft - marginRight;
196 if (chartWidth > spaceX) {
197 log.warn("Width of the chart is too big for pdf -> resize it now.");
198 double ratio = ((double)spaceX) / chartWidth;
199 chartWidth *= ratio;
200 chartHeight *= ratio;
201 log.debug("Resized chart to " + chartWidth + "x" + chartHeight);
202 }
203
204 float spaceY = height - marginTop - marginBottom;
205 if (chartHeight > spaceY) {
206 log.warn("Height of the chart is too big for pdf -> resize it now.");
207 double ratio = ((double)spaceY) / chartHeight;
208 chartWidth *= ratio;
209 chartHeight *= ratio;
210 log.debug("Resized chart to " + chartWidth + "x" + chartHeight);
211 }
212
213 Document document = null;
214 if (landscape) {
215 document = new Document(page.rotate());
216 log.debug("Create landscape pdf.");
217 }
218 else
219 document = new Document(page);
220
221 try {
222 PdfWriter writer = PdfWriter.getInstance(document, out);
223
224 document.addSubject(chart.getTitle().getText());
225 document.addCreationDate();
226 document.open();
227
228 PdfContentByte content = writer.getDirectContent();
229
230 PdfTemplate template = content.createTemplate(width, height);
231 Graphics2D graphics = template.createGraphics(width, height);
232
233 double[] origin = getCenteredAnchor(
234 marginLeft, marginRight, marginBottom, marginTop,
235 width, height,
236 chartWidth, chartHeight);
237
238 Rectangle2D area = new Rectangle2D.Double(
239 origin[0], origin[1], chartWidth, chartHeight);
240
241 chart.draw(graphics, area);
242 graphics.dispose();
243 content.addTemplate(template, 0f, 0f);
244 }
245 catch (DocumentException de) {
246 log.error("Error while exporting chart to pdf.", de);
247 }
248 finally {
249 document.close();
250 }
251 }
252
253
254 /**
255 * This method returns the anchor of the chart so that the chart is centered
256 * according to the given parameters.
257 *
258 * @param mLeft Left margin
259 * @param mRight Right margin
260 * @param mBottom Bottom margin
261 * @param mTop Top margin
262 * @param width The complete width of the drawing area.
263 * @param height The complete height of the drawing area.
264 * @param chartWidth The width of the chart.
265 * @param chartHeight The height of the chart.
266 *
267 * @return an array that contains the anchor for a chart with the given
268 * parameters. The first value is the x point, the second value is the y
269 * point.
270 */
271 public static double[] getCenteredAnchor(
272 double mLeft, double mRight, double mBottom, double mTop,
273 double width, double height,
274 double chartWidth, double chartHeight
275 ) {
276 if (log.isDebugEnabled()) {
277 log.debug("Calculate centered origin...");
278 log.debug("-> PDF width : " + width);
279 log.debug("-> PDF height : " + height);
280 log.debug("-> Chart width : " + chartWidth);
281 log.debug("-> Chart height : " + chartHeight);
282 log.debug("-> margin left : " + mLeft);
283 log.debug("-> margin right : " + mRight);
284 log.debug("-> margin bottom: " + mBottom);
285 log.debug("-> margin top : " + mTop);
286 }
287
288 double[] origin = new double[2];
289
290 double centerX = width / 2;
291 double centerY = height / 2;
292
293 origin[0] = centerX - chartWidth / 2;
294 origin[1] = centerY - chartHeight / 2;
295
296 origin[0] = origin[0] >= mLeft ? origin[0] : mLeft;
297 origin[1] = origin[1] >= mTop ? origin[1] : mTop;
298
299 if (log.isDebugEnabled()) {
300 log.debug("==> centered left origin: " + origin[0]);
301 log.debug("==> centered top origin: " + origin[1]);
302 }
303
304 return origin;
305 }
306 }
307 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :

http://dive4elements.wald.intevation.org