KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jfree > chart > renderer > AreaXYRenderer


1 /* ======================================
2  * JFreeChart : a free Java chart library
3  * ======================================
4  *
5  * Project Info: http://www.jfree.org/jfreechart/index.html
6  * Project Lead: David Gilbert (david.gilbert@object-refinery.com);
7  *
8  * (C) Copyright 2000-2003, by Object Refinery Limited and Contributors.
9  *
10  * This library is free software; you can redistribute it and/or modify it under the terms
11  * of the GNU Lesser General Public License as published by the Free Software Foundation;
12  * either version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
15  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16  * See the GNU Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License along with this
19  * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
20  * Boston, MA 02111-1307, USA.
21  *
22  * -------------------
23  * AreaXYRenderer.java
24  * -------------------
25  * (C) Copyright 2002, 2003 by Hari and Contributors.
26  *
27  * Original Author: Hari (ourhari@hotmail.com);
28  * Contributor(s): David Gilbert (for Object Refinery Limited);
29  * Richard Atkinson;
30  * Christian W. Zuckschwerdt;
31  *
32  * $Id: AreaXYRenderer.java,v 1.22 2003/11/03 14:21:27 mungady Exp $
33  *
34  * Changes:
35  * --------
36  * 03-Apr-2002 : Version 1, contributed by Hari. This class is based on the StandardXYItemRenderer
37  * class (DG);
38  * 09-Apr-2002 : Removed the translated zero from the drawItem method - overridden the initialise()
39  * method to calculate it (DG);
40  * 30-May-2002 : Added tool tip generator to constructor to match super class (DG);
41  * 25-Jun-2002 : Removed unnecessary local variable (DG);
42  * 05-Aug-2002 : Small modification to drawItem method to support URLs for HTML image maps (RA);
43  * 01-Oct-2002 : Fixed errors reported by Checkstyle (DG);
44  * 07-Nov-2002 : Renamed AreaXYItemRenderer --> AreaXYRenderer (DG);
45  * 25-Mar-2003 : Implemented Serializable (DG);
46  * 01-May-2003 : Modified drawItem(...) method signature (DG);
47  * 27-Jul-2003 : Made line and polygon properties protected rather than private (RA);
48  * 30-Jul-2003 : Modified entity constructor (CZ);
49  * 20-Aug-2003 : Implemented Cloneable and PublicCloneable (DG);
50  * 16-Sep-2003 : Changed ChartRenderingInfo --> PlotRenderingInfo (DG);
51  * 07-Oct-2003 : Added renderer state (DG);
52  *
53  */

54
55 package org.jfree.chart.renderer;
56
57 import java.awt.Graphics2D JavaDoc;
58 import java.awt.Paint JavaDoc;
59 import java.awt.Polygon JavaDoc;
60 import java.awt.Shape JavaDoc;
61 import java.awt.Stroke JavaDoc;
62 import java.awt.geom.Line2D JavaDoc;
63 import java.awt.geom.Rectangle2D JavaDoc;
64 import java.io.Serializable JavaDoc;
65
66 import org.jfree.chart.CrosshairInfo;
67 import org.jfree.chart.axis.ValueAxis;
68 import org.jfree.chart.entity.EntityCollection;
69 import org.jfree.chart.entity.XYItemEntity;
70 import org.jfree.chart.labels.XYToolTipGenerator;
71 import org.jfree.chart.plot.PlotOrientation;
72 import org.jfree.chart.plot.PlotRenderingInfo;
73 import org.jfree.chart.plot.XYPlot;
74 import org.jfree.chart.urls.XYURLGenerator;
75 import org.jfree.data.XYDataset;
76 import org.jfree.util.PublicCloneable;
77
78 /**
79  * Area item renderer for an {@link XYPlot}. This class can draw (a) shapes at each
80  * point, or (b) lines between points, or (c) both shapes and lines, or (d)
81  * filled areas, or (e) filled areas and shapes.
82  *
83  * @author Hari
84  */

85 public class AreaXYRenderer extends AbstractXYItemRenderer implements XYItemRenderer,
86                                                                       Cloneable JavaDoc,
87                                                                       PublicCloneable,
88                                                                       Serializable JavaDoc {
89
90     /** Useful constant for specifying the type of rendering (shapes only). */
91     public static final int SHAPES = 1;
92
93     /** Useful constant for specifying the type of rendering (lines only). */
94     public static final int LINES = 2;
95
96     /** Useful constant for specifying the type of rendering (shapes and lines). */
97     public static final int SHAPES_AND_LINES = 3;
98
99     /** Useful constant for specifying the type of rendering (area only). */
100     public static final int AREA = 4;
101
102     /** Useful constant for specifying the type of rendering (area and shapes). */
103     public static final int AREA_AND_SHAPES = 5;
104
105     /** A flag indicating whether or not shapes are drawn at each XY point. */
106     private boolean plotShapes;
107
108     /** A flag indicating whether or not lines are drawn between XY points. */
109     private boolean plotLines;
110
111     /** A flag indicating whether or not Area are drawn at each XY point. */
112     private boolean plotArea;
113
114     /** A flag that controls whether or not the outline is shown. */
115     private boolean showOutline;
116
117     /** A working line (to save creating thousands of instances). */
118     protected transient Line2D JavaDoc line;
119
120     /** Area of the complete series */
121     protected transient Polygon JavaDoc pArea = null;
122
123     /**
124      * Constructs a new renderer.
125      */

126     public AreaXYRenderer() {
127
128         this(AREA);
129
130     }
131
132     /**
133      * Constructs a new renderer.
134      *
135      * @param type the type of the renderer.
136      */

137     public AreaXYRenderer(int type) {
138         this(type, null, null);
139     }
140
141     /**
142      * Constructs a new renderer.
143      * <p>
144      * To specify the type of renderer, use one of the constants: SHAPES, LINES,
145      * SHAPES_AND_LINES, AREA or AREA_AND_SHAPES.
146      *
147      * @param type the type of renderer.
148      * @param toolTipGenerator the tool tip generator to use. <code>null</code> is none.
149      * @param urlGenerator the URL generator (null permitted).
150      */

151     public AreaXYRenderer(int type,
152                           XYToolTipGenerator toolTipGenerator, XYURLGenerator urlGenerator) {
153
154         super();
155         setToolTipGenerator(toolTipGenerator);
156         setURLGenerator(urlGenerator);
157
158         if (type == SHAPES) {
159             this.plotShapes = true;
160         }
161         if (type == LINES) {
162             this.plotLines = true;
163         }
164         if (type == SHAPES_AND_LINES) {
165             this.plotShapes = true;
166             this.plotLines = true;
167         }
168         if (type == AREA) {
169             this.plotArea = true;
170         }
171         if (type == AREA_AND_SHAPES) {
172             this.plotArea = true;
173             this.plotShapes = true;
174         }
175         this.line = new Line2D.Double JavaDoc(0.0, 0.0, 0.0, 0.0);
176         showOutline = false;
177
178     }
179
180     /**
181      * Returns a flag that controls whether or not outlines of the areas are drawn.
182      *
183      * @return the flag.
184      */

185     public boolean isOutline() {
186         return showOutline;
187     }
188
189     /**
190      * Sets a flag that controls whether or not outlines of the areas are drawn.
191      *
192      * @param show the flag.
193      */

194     public void setOutline(boolean show) {
195         showOutline = show;
196     }
197
198     /**
199      * Returns true if shapes are being plotted by the renderer.
200      *
201      * @return <code>true</code> if shapes are being plotted by the renderer.
202      */

203     public boolean getPlotShapes() {
204         return this.plotShapes;
205     }
206
207     /**
208      * Returns true if lines are being plotted by the renderer.
209      *
210      * @return <code>true</code> if lines are being plotted by the renderer.
211      */

212     public boolean getPlotLines() {
213         return this.plotLines;
214     }
215
216     /**
217      * Returns true if Area is being plotted by the renderer.
218      *
219      * @return <code>true</code> if Area is being plotted by the renderer.
220      */

221     public boolean getPlotArea() {
222         return this.plotArea;
223     }
224
225     /**
226      * Initialises the renderer. Here we calculate the Java2D y-coordinate for
227      * zero, since all the bars have their bases fixed at zero.
228      *
229      * @param g2 the graphics device.
230      * @param dataArea the area inside the axes.
231      * @param plot the plot.
232      * @param data the data.
233      * @param info an optional info collection object to return data back to the caller.
234      *
235      * @return The number of passes required by the renderer.
236      */

237     public XYItemRendererState initialise(Graphics2D JavaDoc g2,
238                                           Rectangle2D JavaDoc dataArea,
239                                           XYPlot plot,
240                                           XYDataset data,
241                                           PlotRenderingInfo info) {
242
243         return super.initialise(g2, dataArea, plot, data, info);
244
245     }
246
247     /**
248      * Draws the visual representation of a single data item.
249      *
250      * @param g2 the graphics device.
251      * @param state the renderer state.
252      * @param dataArea the area within which the data is being drawn.
253      * @param info collects information about the drawing.
254      * @param plot the plot (can be used to obtain standard color information etc).
255      * @param domainAxis the domain axis.
256      * @param rangeAxis the range axis.
257      * @param dataset the dataset.
258      * @param series the series index (zero-based).
259      * @param item the item index (zero-based).
260      * @param crosshairInfo information about crosshairs on a plot.
261      * @param pass the pass index.
262      */

263     public void drawItem(Graphics2D JavaDoc g2,
264                          XYItemRendererState state,
265                          Rectangle2D JavaDoc dataArea,
266                          PlotRenderingInfo info,
267                          XYPlot plot,
268                          ValueAxis domainAxis,
269                          ValueAxis rangeAxis,
270                          XYDataset dataset,
271                          int series,
272                          int item,
273                          CrosshairInfo crosshairInfo,
274                          int pass) {
275
276         // Get the item count for the series, so that we can know which is the end of the series.
277
int itemCount = dataset.getItemCount(series);
278
279         Paint JavaDoc paint = getItemPaint(series, item);
280         Stroke JavaDoc seriesStroke = getItemStroke(series, item);
281         g2.setPaint(paint);
282         g2.setStroke(seriesStroke);
283
284         // get the data point...
285
Number JavaDoc x1 = dataset.getXValue(series, item);
286         Number JavaDoc y1 = dataset.getYValue(series, item);
287         double transX1 = domainAxis.translateValueToJava2D(x1.doubleValue(), dataArea,
288                                                            plot.getDomainAxisEdge());
289         double transY1 = rangeAxis.translateValueToJava2D(y1.doubleValue(), dataArea,
290                                                           plot.getRangeAxisEdge());
291
292         if (item == 0) {
293             // Create a new Area for the series
294
pArea = new Polygon JavaDoc();
295
296             // start from Y = 0
297
double transY2 = rangeAxis.translateValueToJava2D(0.0, dataArea,
298                                                               plot.getRangeAxisEdge());
299
300             // The first point is (x, 0)
301
if (plot.getOrientation() == PlotOrientation.VERTICAL) {
302                 pArea.addPoint((int) transX1, (int) transY2);
303             }
304             else if (plot.getOrientation() == PlotOrientation.HORIZONTAL) {
305                 pArea.addPoint((int) transY2, (int) transX1);
306             }
307         }
308
309         // Add each point to Area (x, y)
310
if (plot.getOrientation() == PlotOrientation.VERTICAL) {
311             pArea.addPoint((int) transX1, (int) transY1);
312         }
313         else if (plot.getOrientation() == PlotOrientation.HORIZONTAL) {
314             pArea.addPoint((int) transY1, (int) transX1);
315         }
316         Shape JavaDoc shape = null;
317         if (this.plotShapes) {
318             shape = getItemShape(series, item);
319             if (plot.getOrientation() == PlotOrientation.VERTICAL) {
320                 shape = createTransformedShape(shape, transX1, transY1);
321             }
322             else if (plot.getOrientation() == PlotOrientation.HORIZONTAL) {
323                 shape = createTransformedShape(shape, transY1, transX1);
324             }
325             g2.draw(shape);
326         }
327         else {
328             if (plot.getOrientation() == PlotOrientation.VERTICAL) {
329                 shape = new Rectangle2D.Double JavaDoc(transX1 - 2, transY1 - 2, 4.0, 4.0);
330             }
331             else if (plot.getOrientation() == PlotOrientation.HORIZONTAL) {
332                 shape = new Rectangle2D.Double JavaDoc(transY1 - 2, transX1 - 2, 4.0, 4.0);
333             }
334         }
335
336         if (this.plotLines) {
337             if (item > 0) {
338                 // get the previous data point...
339
Number JavaDoc x0 = dataset.getXValue(series, item - 1);
340                 Number JavaDoc y0 = dataset.getYValue(series, item - 1);
341                 double transX0 = domainAxis.translateValueToJava2D(x0.doubleValue(), dataArea,
342                                                                    plot.getDomainAxisEdge());
343                 double transY0 = rangeAxis.translateValueToJava2D(y0.doubleValue(), dataArea,
344                                                                   plot.getRangeAxisEdge());
345
346                 if (plot.getOrientation() == PlotOrientation.VERTICAL) {
347                     line.setLine(transX0, transY0, transX1, transY1);
348                 }
349                 else if (plot.getOrientation() == PlotOrientation.HORIZONTAL) {
350                     line.setLine(transY0, transX0, transY1, transX1);
351                 }
352                 g2.draw(line);
353             }
354         }
355
356         // Check if the item is the last item for the series.
357
// and number of items > 0. We can't draw an area for a single point.
358
if (this.plotArea && item > 0 && item == (itemCount - 1)) {
359
360             double transY2 = rangeAxis.translateValueToJava2D(0.0, dataArea,
361                                                               plot.getRangeAxisEdge());
362
363             if (plot.getOrientation() == PlotOrientation.VERTICAL) {
364                 // Add the last point (x,0)
365
pArea.addPoint((int) transX1, (int) transY2);
366             }
367             else if (plot.getOrientation() == PlotOrientation.HORIZONTAL) {
368                 // Add the last point (x,0)
369
pArea.addPoint((int) transY2, (int) transX1);
370             }
371
372             // fill the polygon
373
g2.fill(pArea);
374
375             // draw an outline around the Area.
376
if (showOutline) {
377                 g2.setStroke(plot.getOutlineStroke());
378                 g2.setPaint(plot.getOutlinePaint());
379                 g2.draw(pArea);
380             }
381         }
382
383         // do we need to update the crosshair values?
384
if (plot.isDomainCrosshairLockedOnData()) {
385             if (plot.isRangeCrosshairLockedOnData()) {
386                 // both axes
387
crosshairInfo.updateCrosshairPoint(x1.doubleValue(), y1.doubleValue(),
388                                                    transX1, transY1);
389             }
390             else {
391                 // just the horizontal axis...
392
crosshairInfo.updateCrosshairX(x1.doubleValue());
393
394             }
395         }
396         else {
397             if (plot.isRangeCrosshairLockedOnData()) {
398                 // just the vertical axis...
399
crosshairInfo.updateCrosshairY(y1.doubleValue());
400             }
401         }
402
403         // collect entity and tool tip information...
404
if (state.getInfo() != null) {
405             EntityCollection entities = state.getInfo().getOwner().getEntityCollection();
406             if (entities != null && shape != null) {
407                 String JavaDoc tip = null;
408                 if (getToolTipGenerator() != null) {
409                     tip = getToolTipGenerator().generateToolTip(dataset, series, item);
410                 }
411                 String JavaDoc url = null;
412                 if (getURLGenerator() != null) {
413                     url = getURLGenerator().generateURL(dataset, series, item);
414                 }
415                 XYItemEntity entity = new XYItemEntity(shape, dataset, series, item, tip, url);
416                 entities.addEntity(entity);
417             }
418         }
419
420     }
421
422     /**
423      * Returns a clone of the renderer.
424      *
425      * @return A clone.
426      *
427      * @throws CloneNotSupportedException if the renderer cannot be cloned.
428      */

429     public Object JavaDoc clone() throws CloneNotSupportedException JavaDoc {
430         return super.clone();
431     }
432     
433 }
434
Popular Tags