View Javadoc

1   /*
2    *                Doelan development code
3    *
4    * This code may be freely distributed and modified under the
5    * terms of the GNU General Public Licence.  This should
6    * be distributed with the code. If you do not have a copy,
7    * see:
8    *
9    *      http://www.gnu.org/copyleft/gpl.txt
10   *
11   * Copyright (c) 2004-2005 ENS Microarray Platform
12   * Copyright for this code is held jointly by the individual
13   * authors.  These should be listed in @author doc comments.
14   *
15   * For more information on the Doelan project and its aims,
16   * or to join the Doelan mailing list, visit the home page
17   * at:
18   *
19   *      http://www.transcriptome.ens.fr/doelan
20   */
21  
22  package fr.ens.transcriptome.doelan;
23  
24  import java.awt.Color;
25  import java.awt.Font;
26  import java.awt.Image;
27  
28  import org.apache.log4j.Logger;
29  import org.jfree.chart.ChartColor;
30  import org.jfree.chart.ChartFactory;
31  import org.jfree.chart.JFreeChart;
32  import org.jfree.chart.axis.LogarithmicAxis;
33  import org.jfree.chart.plot.IntervalMarker;
34  import org.jfree.chart.plot.PlotOrientation;
35  import org.jfree.chart.plot.ValueMarker;
36  import org.jfree.chart.plot.XYPlot;
37  import org.jfree.chart.renderer.xy.XYItemRenderer;
38  import org.jfree.data.statistics.HistogramDataset;
39  import org.jfree.ui.Layer;
40  import org.jfree.ui.RectangleAnchor;
41  import org.jfree.ui.TextAnchor;
42  
43  /***
44   * This class allow to generate a plot.
45   * @author Laurent Jourdren
46   */
47  public class DoelanChart {
48  
49    // For log system
50    private static Logger log = Logger.getLogger(DoelanChart.class);
51  
52    private int width;
53    private int height;
54  
55    private double[] data;
56    private String title;
57    private String xAxisLegend;
58    private String yAxisLegend;
59    private String histCaption;
60    private boolean yLogAxis;
61  
62    private int bins = 1;
63    private double threshold = -1;
64    private boolean thresholdCaptionRight;
65    private static final int THRESHOLD_SIZE = 11;
66  
67    //
68    // Getters
69    //
70  
71    /***
72     * Set the number of bins
73     * @return Returns the bins
74     */
75    public int getBins() {
76      return bins;
77    }
78  
79    /***
80     * Get the data to plot
81     * @return Returns the data
82     */
83    public double[] getData() {
84      return data;
85    }
86  
87    /***
88     * Set the title of the plot.
89     * @return Returns the title
90     */
91    public String getTitle() {
92      return title;
93    }
94  
95    /***
96     * Get the value of the threshold.
97     * @return Returns the threshold
98     */
99    public double getThreshold() {
100     return threshold;
101   }
102 
103   /***
104    * Test if the position of the caption for the threshold is on the right.
105    * @return Returns the thresholdCaptionRight
106    */
107   public boolean isThresholdCaptionRight() {
108     return thresholdCaptionRight;
109   }
110 
111   /***
112    * Get the caption of the histogram
113    * @return Returns the histCaption
114    */
115   public String getHistCaption() {
116     return histCaption;
117   }
118 
119   /***
120    * Get the x axis legend
121    * @return Returns the xAxisLegend
122    */
123   public String getXAxisLegend() {
124     return xAxisLegend;
125   }
126 
127   /***
128    * Get the y axis legend
129    * @return Returns the yAxisLegend
130    */
131   public String getYAxisLegend() {
132     return yAxisLegend;
133   }
134 
135   /***
136    * Get the height of the image.
137    * @return Returns the height
138    */
139   public int getHeight() {
140     return height;
141   }
142 
143   /***
144    * Get the width of the image.
145    * @return Returns the width
146    */
147   public int getWidth() {
148     return width;
149   }
150 
151   /***
152    * Set the height of the image.
153    * @param height The height to set
154    */
155   public void setHeight(final int height) {
156     this.height = height;
157   }
158 
159   /***
160    * Set the width of the image.
161    * @param width The width to set
162    */
163   public void setWidth(final int width) {
164     this.width = width;
165   }
166 
167   /***
168    * Test if the Y axis is in log scale
169    * @return Returns the yLogAxis
170    */
171   public boolean isYLogAxis() {
172     return yLogAxis;
173   }
174 
175   /***
176    * Set the log scale for the y axis
177    * @param logAxis The yLogAxis to set
178    */
179   public void setYLogAxis(final boolean logAxis) {
180     yLogAxis = logAxis;
181   }
182 
183   //
184   // Setters
185   //
186 
187   /***
188    * Set the number of bins
189    * @param bins The bins to set
190    */
191   public void setBins(final int bins) {
192     this.bins = bins;
193   }
194 
195   /***
196    * set the data
197    * @param data The data to set
198    */
199   public void setData(final double[] data) {
200     this.data = data;
201   }
202 
203   /***
204    * Set the title of the plot.
205    * @param title The title to set
206    */
207   public void setTitle(final String title) {
208     this.title = title;
209   }
210 
211   /***
212    * Set the threshold
213    * @param threshold The threshold to set
214    */
215   public void setThreshold(final double threshold) {
216     this.threshold = threshold;
217   }
218 
219   /***
220    * Set the position of the caption for the threshold.
221    * @param thresholdCaptionRight The thresholdCaptionRight to set
222    */
223   public void setThresholdCaptionRight(final boolean thresholdCaptionRight) {
224     this.thresholdCaptionRight = thresholdCaptionRight;
225   }
226 
227   /***
228    * Set the histogram caption
229    * @param histCaption The histCaption to set
230    */
231   public void setHistCaption(final String histCaption) {
232     this.histCaption = histCaption;
233   }
234 
235   /***
236    * Set the x axis legend
237    * @param axisLegend The xAxisLegend to set
238    */
239   public void setXAxisLegend(final String axisLegend) {
240     xAxisLegend = axisLegend;
241   }
242 
243   /***
244    * Get the y axis legend
245    * @param axisLegend The yAxisLegend to set
246    */
247   public void setYAxisLegend(final String axisLegend) {
248     yAxisLegend = axisLegend;
249   }
250 
251   //
252   // Other methods
253   //
254 
255   private static double getMax(final double[] array) {
256 
257     double max = Double.MIN_VALUE;
258 
259     if (array == null)
260       return max;
261 
262     for (int i = 0; i < array.length; i++)
263       if (array[i] > max)
264         max = array[i];
265 
266     return max;
267   }
268 
269   private HistogramDataset getHistogramDataset() {
270 
271     HistogramDataset histogramdataset = new HistogramDataset();
272 
273     double max = getMax(getData());
274 
275     histogramdataset.addSeries(getHistCaption(), getData(), getBins(), 0,
276         ((int) (max / 10)) * 10 + 1);
277 
278     return histogramdataset;
279 
280   }
281 
282   /***
283    * Get the image
284    * @return an image of the plot
285    */
286   public Image getImage() {
287 
288     HistogramDataset histogramdataset = getHistogramDataset();
289 
290     // create the chart...
291     JFreeChart chart = ChartFactory.createHistogram(getTitle(),
292     // title
293         getXAxisLegend(), // domain axis label
294         getYAxisLegend(), // range axis label
295         histogramdataset, // data
296 
297         PlotOrientation.VERTICAL, // orientation
298         true, // include legend
299         true, // tooltips?
300         false // URLs?
301         );
302 
303     // get a reference to the plot for further customisation...
304     XYPlot plot = chart.getXYPlot();
305 
306     XYItemRenderer histRenderer = plot.getRenderer();
307 
308     histRenderer.setSeriesPaint(0, ChartColor.VERY_LIGHT_BLUE);
309 
310     if (getThreshold() != -1) {
311 
312       ValueMarker valueMarker = new ValueMarker(getThreshold());
313 
314       valueMarker.setPaint(Color.red);
315       valueMarker.setLabel("Threshold");
316       valueMarker.setLabelFont(new Font("SansSerif", 2, THRESHOLD_SIZE));
317       valueMarker.setLabelPaint(ChartColor.DARK_RED);
318       valueMarker.setLabelAnchor(RectangleAnchor.TOP);
319 
320       if (isThresholdCaptionRight())
321         valueMarker.setLabelTextAnchor(TextAnchor.TOP_RIGHT);
322       else
323         valueMarker.setLabelTextAnchor(TextAnchor.TOP_LEFT);
324 
325       valueMarker.setPaint(ChartColor.RED);
326       plot.addDomainMarker(valueMarker, Layer.FOREGROUND);
327 
328       IntervalMarker intervalMarker = new IntervalMarker(0, getThreshold());
329 
330       intervalMarker.setPaint(new Color(222, 222, 255, 64));
331 
332       plot.addDomainMarker(intervalMarker, Layer.BACKGROUND);
333 
334       chart.setAntiAlias(false);
335 
336       // set the background color for the chart...
337       chart.setBackgroundPaint(Color.white);
338 
339     }
340 
341     Image result = null;
342     try {
343 
344       if (isYLogAxis()) {
345         LogarithmicAxis yAxis = new LogarithmicAxis(getYAxisLegend());
346         yAxis.setAllowNegativesFlag(true);
347         plot.setRangeAxis(yAxis);
348       }
349 
350       result = chart.createBufferedImage(getWidth(), getHeight());
351     } catch (Error e) {
352       log.error("Catch error of JFreeChart: " + e.getMessage());
353     } catch (RuntimeException e) {
354       log.error("Catch runtime exception of JFreeChart: " + e.getMessage());
355     }
356 
357     return result;
358   }
359 }