KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jrobin > graph > RrdGraph


1 /* ============================================================
2  * JRobin : Pure java implementation of RRDTool's functionality
3  * ============================================================
4  *
5  * Project Info: http://www.jrobin.org
6  * Project Lead: Sasa Markovic (saxon@jrobin.org)
7  *
8  * Developers: Sasa Markovic (saxon@jrobin.org)
9  * Arne Vandamme (cobralord@jrobin.org)
10  *
11  * (C) Copyright 2003, by Sasa Markovic.
12  *
13  * This library is free software; you can redistribute it and/or modify it under the terms
14  * of the GNU Lesser General Public License as published by the Free Software Foundation;
15  * either version 2.1 of the License, or (at your option) any later version.
16  *
17  * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
18  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19  * See the GNU Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public License along with this
22  * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
23  * Boston, MA 02111-1307, USA.
24  */

25 package org.jrobin.graph;
26
27 import java.util.Iterator JavaDoc;
28 import java.io.File JavaDoc;
29 import java.io.FileOutputStream JavaDoc;
30 import java.io.IOException JavaDoc;
31 import java.io.Serializable JavaDoc;
32 import java.io.ByteArrayOutputStream JavaDoc;
33 import javax.imageio.ImageIO JavaDoc;
34 import javax.imageio.IIOImage JavaDoc;
35 import javax.imageio.ImageWriter JavaDoc;
36 import javax.imageio.ImageWriteParam JavaDoc;
37 import javax.imageio.stream.ImageOutputStream JavaDoc;
38 import java.awt.image.RenderedImage JavaDoc;
39 import java.awt.image.BufferedImage JavaDoc;
40 import java.awt.*;
41
42 import org.jrobin.core.RrdOpener;
43 import org.jrobin.core.RrdException;
44
45 /**
46  * <p>Class to represent JRobin graphs. This class needs an appropriate RrdGraphDef to generate graphs.</p>
47  *
48  * @author Arne Vandamme (cobralord@jrobin.org)
49  * @author Sasa Markovic (saxon@jrobin.org)
50  */

51 public class RrdGraph extends RrdOpener implements Serializable JavaDoc
52 {
53     // ================================================================
54
// -- Members
55
// ================================================================
56
private Grapher grapher;
57     private BufferedImage JavaDoc img;
58
59     private boolean useImageSize = false;
60     
61     
62     // ================================================================
63
// -- Constructors
64
// ================================================================
65
/**
66      * Constructs a new JRobin graph object, without a shared database pool.
67      */

68     public RrdGraph()
69     {
70         super( false, true );
71     }
72
73     /**
74      * Constructs a new JRobin graph object.
75      * @param usePool True if this object should use RrdDbPool
76      */

77     public RrdGraph( boolean usePool )
78     {
79         super( usePool, true );
80     }
81
82     /**
83      * Constructs a new JRobin graph object from the supplied definition.
84      * @param graphDef Graph definition.
85      */

86     public RrdGraph( RrdGraphDef graphDef )
87     {
88         this( graphDef, false );
89     }
90
91     /**
92      * Constructs a new JRobin graph from the supplied definition.
93      * @param graphDef Graph definition.
94      * @param usePool True if this should object should use RrdDbPool
95      */

96     public RrdGraph( RrdGraphDef graphDef, boolean usePool )
97     {
98         super( usePool, true );
99         grapher = new Grapher( graphDef, this );
100     }
101     
102     
103     // ================================================================
104
// -- Public mehods
105
// ================================================================
106
/**
107      * Determines if graph creation should specify dimensions for the chart graphing
108      * are, of for the entire image size. Default is the only the chart graphing
109      * area, this has an impact on the entire image size.
110      * @param specImgSize True if the dimensions for the entire image will be specified, false if only for the chart area.
111      */

112     public void specifyImageSize( boolean specImgSize )
113     {
114         this.useImageSize = specImgSize;
115     }
116     
117     /**
118      * Sets the graph definition to use for the graph construction.
119      * @param graphDef Graph definition.
120      */

121     public void setGraphDef( RrdGraphDef graphDef )
122     {
123         img = null;
124         grapher = new Grapher( graphDef, this );
125     }
126     
127     /**
128      * Creates and saves a graph image with default dimensions as a PNG file.
129      * By default the chart area is 400 by 100 pixels, the size of the entire image is dependant
130      * on number of title/legend/comment lines and some other settings.
131      * @param path Path to the PNG file to be created.
132      * @throws IOException Thrown in case of I/O error.
133      * @throws RrdException Thrown in case of JRobin specific error.
134      */

135     public void saveAsPNG( String JavaDoc path ) throws RrdException, IOException JavaDoc
136     {
137         saveAsPNG( path, 0, 0 );
138     }
139     
140     /**
141      * Creates and saves a graph image with custom chart dimensions as a PNG file.
142      * The resulting size of the entire image is also influenced by many other settings like number of comment lines.
143      * @param path Path to the PNG file to be created.
144      * @param width Width of the chart area in pixels.
145      * @param height Height of the chart area in pixels.
146      * @throws IOException Thrown in case of I/O error.
147      * @throws RrdException Thrown in case of JRobin specific error.
148      */

149     public void saveAsPNG( String JavaDoc path, int width, int height ) throws RrdException, IOException JavaDoc
150     {
151         File JavaDoc imgFile = new File JavaDoc( path );
152
153         if ( shouldGenerate(imgFile) )
154             ImageIO.write( getBufferedImage(width, height, BufferedImage.TYPE_INT_RGB), "png", imgFile );
155     }
156
157     /**
158      * Creates and saves a graph image with default dimensions as a GIF file.
159      * By default the chart area is 400 by 100 pixels, the size of the entire image is dependant
160      * on number of title/legend/comment lines and some other settings.
161      * @param path Path to the GIF file to be created.
162      * @throws IOException Thrown in case of I/O error.
163      * @throws RrdException Thrown in case of JRobin specific error.
164      */

165     public void saveAsGIF( String JavaDoc path ) throws RrdException, IOException JavaDoc
166     {
167         saveAsGIF( path, 0, 0 );
168     }
169     
170     /**
171      * Creates and saves a graph image with custom chart dimensions as a GIF file.
172      * The resulting size of the entire image is also influenced by many other settings like number of comment lines.
173      * @param path Path to the GIF file to be created.
174      * @param width Width of the chart area in pixels.
175      * @param height Height of the chart area in pixels.
176      * @throws IOException Thrown in case of I/O error.
177      * @throws RrdException Thrown in case of JRobin specific error.
178      */

179     public void saveAsGIF(String JavaDoc path, int width, int height) throws RrdException, IOException JavaDoc
180     {
181         File JavaDoc imgFile = new File JavaDoc( path );
182
183         if ( shouldGenerate(imgFile) )
184         {
185             GifEncoder gifEncoder = new GifEncoder( getBufferedImage(width, height, BufferedImage.TYPE_BYTE_INDEXED) );
186             FileOutputStream JavaDoc stream = new FileOutputStream JavaDoc( path, false );
187
188             gifEncoder.encode(stream);
189
190             stream.close();
191         }
192     }
193
194     /**
195      * Creates and saves a graph image with default dimensions as a JPEG file.
196      * By default the chart area is 400 by 100 pixels, the size of the entire image is dependant
197      * on number of title/legend/comment lines and some other settings.
198      * @param path Path to the JPEG file to be created.
199      * @param quality JPEG quality, between 0 (= low) and 1.0f (= high).
200      * @throws IOException Thrown in case of I/O error.
201      */

202     public void saveAsJPEG( String JavaDoc path, float quality ) throws RrdException, IOException JavaDoc
203     {
204         saveAsJPEG( path, 0, 0, quality );
205     }
206     
207     /**
208      * Creates and saves a graph image with custom chart dimensions as a JPEG file.
209      * The resulting size of the entire image is also influenced by many other settings like number of comment lines.
210      * @param path Path to the JPEG file to be created.
211      * @param width Width of the chart area in pixels.
212      * @param height Height of the chart area in pixels.
213      * @param quality JPEG quality, between 0 (= low) and 1.0f (= high).
214      * @throws IOException Thrown in case of I/O error.
215      */

216     public void saveAsJPEG( String JavaDoc path, int width, int height, float quality ) throws RrdException, IOException JavaDoc
217     {
218         File JavaDoc imgFile = new File JavaDoc( path );
219
220         if ( !shouldGenerate(imgFile) )
221             return;
222
223         // Based on http://javaalmanac.com/egs/javax.imageio/JpegWrite.html?l=rel
224
// Retrieve jpg image to be compressed
225
RenderedImage JavaDoc rndImage = getBufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
226     
227         // Find a jpeg writer
228
ImageWriter JavaDoc writer = null;
229         Iterator JavaDoc iter = ImageIO.getImageWritersByFormatName("jpg");
230         if (iter.hasNext()) {
231             writer = (ImageWriter JavaDoc)iter.next();
232         }
233
234         // Prepare output file
235
ImageOutputStream JavaDoc ios = ImageIO.createImageOutputStream(new File JavaDoc(path));
236         writer.setOutput(ios);
237
238         // Set the compression quality
239
ImageWriteParam JavaDoc iwparam = new JpegImageWriteParam();
240         iwparam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT) ;
241         iwparam.setCompressionQuality(quality);
242
243         // Write the image
244
writer.write(null, new IIOImage JavaDoc(rndImage, null, null), iwparam);
245
246         // Cleanup
247
ios.flush();
248         writer.dispose();
249         ios.close();
250     }
251     
252     /**
253      * Returns graph with default chart dimensions (400 by 100) as an array of PNG bytes.
254      * @return Array of PNG bytes.
255      * @throws IOException Thrown in case of I/O error.
256      */

257     public byte[] getPNGBytes() throws IOException JavaDoc, RrdException
258     {
259         return getPNGBytes( 0, 0 );
260     }
261     
262     /**
263      * Returns graph with custom chart dimensions as an array of PNG bytes.
264      * @param width Width of the chart area in pixels.
265      * @param height Height of the chart area in pixels.
266      * @return Array of PNG bytes.
267      * @throws IOException Thrown in case of I/O error.
268      */

269     public byte[] getPNGBytes( int width, int height ) throws IOException JavaDoc, RrdException
270     {
271         ByteArrayOutputStream JavaDoc outputStream = new ByteArrayOutputStream JavaDoc();
272         
273         ImageIO.write(getBufferedImage(width, height, BufferedImage.TYPE_INT_RGB), "png", outputStream );
274                 
275         return outputStream.toByteArray();
276     }
277
278     /**
279      * Returns graph with default chart dimensions (400 by 100) as an array of JPEG bytes.
280      * @param quality JPEG quality, between 0 (= low) and 1.0f (= high).
281      * @return Array of PNG bytes.
282      * @throws IOException Thrown in case of I/O error.
283      */

284     public byte[] getJPEGBytes( float quality ) throws IOException JavaDoc, RrdException
285     {
286         return getJPEGBytes( 0, 0, quality );
287     }
288     
289     /**
290      * Returns graph with custom chart dimensions as an array of JPEG bytes.
291      * @param width Width of the chart area in pixels.
292      * @param height Height of the chart area in pixels.
293      * @param quality JPEG quality, between 0 (= low) and 1.0f (= high).
294      * @return Array of JPEG bytes.
295      * @throws IOException Thrown in case of I/O error.
296      */

297     public byte[] getJPEGBytes( int width, int height, float quality ) throws IOException JavaDoc, RrdException
298     {
299         ByteArrayOutputStream JavaDoc outputStream = new ByteArrayOutputStream JavaDoc();
300         
301         // Retrieve jpg image to be compressed
302
RenderedImage JavaDoc rndImage = getBufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
303     
304         // Find a jpeg writer
305
ImageWriter JavaDoc writer = null;
306         Iterator JavaDoc iter = ImageIO.getImageWritersByFormatName("jpg");
307         if (iter.hasNext()) {
308             writer = (ImageWriter JavaDoc)iter.next();
309         }
310
311         // Prepare output file
312
ImageOutputStream JavaDoc ios = ImageIO.createImageOutputStream(outputStream);
313         writer.setOutput(ios);
314
315         // Set the compression quality
316
ImageWriteParam JavaDoc iwparam = new JpegImageWriteParam();
317         iwparam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT) ;
318         iwparam.setCompressionQuality(quality);
319
320         // Write the image
321
writer.write(null, new IIOImage JavaDoc(rndImage, null, null), iwparam);
322
323         // Cleanup
324
ios.flush();
325         writer.dispose();
326         ios.close();
327         
328         return outputStream.toByteArray();
329     }
330
331     /**
332      * Returns graph with default chart dimensions (400 by 100) as an array of GIF bytes.
333      * @return Array of GIF bytes.
334      * @throws IOException Thrown in case of I/O error.
335      */

336     public byte[] getGIFBytes() throws RrdException, IOException JavaDoc
337     {
338         return getGIFBytes( 0, 0 );
339     }
340     
341     /**
342      * Returns graph with custom chart dimensions as an array of GIF bytes.
343      * @param width Width of the chart area in pixels.
344      * @param height Height of the chart area in pixels.
345      * @return Array of GIF bytes.
346      * @throws IOException Thrown in case of I/O error.
347      */

348     public byte[] getGIFBytes(int width, int height) throws RrdException, IOException JavaDoc
349     {
350         BufferedImage JavaDoc image = getBufferedImage(width, height, BufferedImage.TYPE_BYTE_INDEXED);
351         ByteArrayOutputStream JavaDoc bStream = new ByteArrayOutputStream JavaDoc();
352     
353         GifEncoder gifEncoder = new GifEncoder( image );
354         gifEncoder.encode( bStream );
355         
356         return bStream.toByteArray();
357     }
358
359     /**
360      * Returns the underlying BufferedImage of a graph with custom dimensions.
361      * Specifying 0 for both width and height will result in a auto-sized graph.
362      * @param width Width of the chart area in pixels.
363      * @param height Height of the chart area in pixels.
364      * @return BufferedImage containing the graph.
365      * @throws IOException Thrown in case of I/O error.
366      * @throws RrdException Thrown in case of JRobin specific error.
367      */

368     public BufferedImage JavaDoc getBufferedImage( int width, int height ) throws IOException JavaDoc, RrdException
369     {
370         return getBufferedImage( width, height, BufferedImage.TYPE_INT_RGB );
371     }
372
373     /**
374      * Returns panel object so that graph can be easily embedded in swing applications.
375      * @return Swing JPanel object with graph embedded in panel.
376      */

377     public ChartPanel getChartPanel() throws RrdException, IOException JavaDoc
378     {
379         ChartPanel p = new ChartPanel();
380         p.setChart( getBufferedImage(0, 0, BufferedImage.TYPE_INT_RGB) );
381         
382         return p;
383     }
384
385     /**
386      * Renders the graph onto a specified Graphics2D object.
387      * Specifying 0 for both width and height will result in a auto-sized graph.
388      * @param graphics Handle to a Graphics2D object to render the graph on.
389      * @param width Width of the chart area in pixels.
390      * @param height Height of the chart area in pixels.
391      * @throws RrdException Thrown in case of JRobin specific error.
392      * @throws IOException Thrown in case of I/O error
393      */

394     public void renderImage( Graphics2D graphics, int width, int height ) throws RrdException, IOException JavaDoc
395     {
396         if ( useImageSize )
397             grapher.renderImage( width, height, graphics, true );
398         else
399             grapher.renderImage( width, height, graphics, false );
400     }
401
402     /**
403      * This retrieves the ExportData object associated with the reduced dataset of this Graph.
404      * This method assumes the graph or at least the dataset has already been calculated.
405      *
406      * @return ExportData object containing the reduced dataset.
407      * @throws RrdException Thrown in case of JRobin specific error.
408      */

409     public ExportData getExportData() throws RrdException {
410         return grapher.createExportData();
411     }
412
413     /**
414      * This retrieves the ExportData object associated with the reduced dataset of this Graph,
415      * by calculating the dataset on the spot. Use this if you want to retrieve the associated
416      * ExportData without generating the actual graph.
417      *
418      * @return ExportData object containing the reduced dataset.
419      * @throws RrdException Thrown in case of JRobin specific error.
420      * @throws IOException Thrown in case of I/O error
421      */

422     public ExportData fetchExportData() throws RrdException, IOException JavaDoc {
423         return grapher.fetch( Grapher.DEFAULT_WIDTH );
424     }
425
426     /**
427      * This retrieves the ExportData object associated with the reduced dataset of this Graph,
428      * by calculating the dataset on the spot. Use this if you want to retrieve the associated
429      * ExportData without generating the actual graph, or if you wish to re-calculate the
430      * associated dataset for a different number of rows.
431      *
432      * @param maxRows Ballpark figure 'maximum number of rows' that the dataset can contain.
433      * Note that this is not an absolute maximum and can be overruled in some cases.
434      * @return ExportData object containing the reduced dataset.
435      * @throws RrdException Thrown in case of JRobin specific error.
436      * @throws IOException Thrown in case of I/O error
437      */

438     public ExportData fetchExportData( int maxRows ) throws RrdException, IOException JavaDoc {
439         return grapher.fetch( maxRows );
440     }
441
442     // ================================================================
443
// -- Private methods
444
// ================================================================
445
/**
446      * This method checks if the graph should be generated. This would be the case if the requested
447      * image file does not yet exist, or (in case the generation is set to be lazy) the last modified
448      * timestamp of the image file is before the last updated timestamp of the used datasources.
449      * @param imgFile Image file to check against.
450      * @return True if graph generation should be done, false if not.
451      * @throws IOException Thrown in case of I/O error.
452      * @throws RrdException Thrown in case of JRobin specific error.
453      */

454     private boolean shouldGenerate( File JavaDoc imgFile ) throws RrdException, IOException JavaDoc
455     {
456         if ( !imgFile.exists() )
457             return true;
458
459         return grapher.shouldGenerate( imgFile.lastModified() );
460     }
461
462     private BufferedImage JavaDoc getBufferedImage(int width, int height, int colorType) throws RrdException, IOException JavaDoc
463     {
464         // Always regenerate graph
465
if ( useImageSize )
466             img = grapher.createImageGlobal( width, height, colorType );
467         else
468             img = grapher.createImage( width, height, colorType );
469         
470         return img;
471     }
472 }
473
Popular Tags