KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jfree > chart > renderer > category > BarRenderer3D


1 /* ===========================================================
2  * JFreeChart : a free chart library for the Java(tm) platform
3  * ===========================================================
4  *
5  * (C) Copyright 2000-2006, by Object Refinery Limited and Contributors.
6  *
7  * Project Info: http://www.jfree.org/jfreechart/index.html
8  *
9  * This library is free software; you can redistribute it and/or modify it
10  * under the terms of the GNU Lesser General Public License as published by
11  * the Free Software Foundation; either version 2.1 of the License, or
12  * (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17  * License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
22  * USA.
23  *
24  * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
25  * in the United States and other countries.]
26  *
27  * ------------------
28  * BarRenderer3D.java
29  * ------------------
30  * (C) Copyright 2001-2006, by Serge V. Grachov and Contributors.
31  *
32  * Original Author: Serge V. Grachov;
33  * Contributor(s): David Gilbert (for Object Refinery Limited);
34  * Tin Luu;
35  * Milo Simpson;
36  * Richard Atkinson;
37  * Rich Unger;
38  * Christian W. Zuckschwerdt;
39  *
40  * $Id: BarRenderer3D.java,v 1.10.2.4 2006/09/05 16:40:01 mungady Exp $
41  *
42  * Changes
43  * -------
44  * 31-Oct-2001 : First version, contributed by Serge V. Grachov (DG);
45  * 15-Nov-2001 : Modified to allow for null data values (DG);
46  * 13-Dec-2001 : Added tooltips (DG);
47  * 16-Jan-2002 : Added fix for single category or single series datasets,
48  * pointed out by Taoufik Romdhane (DG);
49  * 24-May-2002 : Incorporated tooltips into chart entities (DG);
50  * 11-Jun-2002 : Added check for (permitted) null info object, bug and fix
51  * reported by David Basten. Also updated Javadocs. (DG);
52  * 19-Jun-2002 : Added code to draw labels on bars (TL);
53  * 26-Jun-2002 : Added bar clipping to avoid PRExceptions (DG);
54  * 05-Aug-2002 : Small modification to drawCategoryItem method to support URLs
55  * for HTML image maps (RA);
56  * 06-Aug-2002 : Value labels now use number formatter, thanks to Milo
57  * Simpson (DG);
58  * 08-Aug-2002 : Applied fixed in bug id 592218 (DG);
59  * 20-Sep-2002 : Added fix for categoryPaint by Rich Unger, and fixed errors
60  * reported by Checkstyle (DG);
61  * 24-Oct-2002 : Amendments for changes in CategoryDataset interface and
62  * CategoryToolTipGenerator interface (DG);
63  * 05-Nov-2002 : Replaced references to CategoryDataset with TableDataset (DG);
64  * 06-Nov-2002 : Moved to the com.jrefinery.chart.renderer package (DG);
65  * 28-Jan-2003 : Added an attribute to control the shading of the left and
66  * bottom walls in the plot background (DG);
67  * 25-Mar-2003 : Implemented Serializable (DG);
68  * 10-Apr-2003 : Removed category paint usage (DG);
69  * 13-May-2003 : Renamed VerticalBarRenderer3D --> BarRenderer3D and merged with
70  * HorizontalBarRenderer3D (DG);
71  * 30-Jul-2003 : Modified entity constructor (CZ);
72  * 19-Aug-2003 : Implemented Cloneable and PublicCloneable (DG);
73  * 07-Oct-2003 : Added renderer state (DG);
74  * 08-Oct-2003 : Removed clipping (replaced with flag in CategoryPlot to
75  * control order in which the data items are processed) (DG);
76  * 20-Oct-2003 : Fixed bug (outline stroke not being used for bar
77  * outlines) (DG);
78  * 21-Oct-2003 : Bar width moved into CategoryItemRendererState (DG);
79  * 24-Nov-2003 : Fixed bug 846324 (item labels not showing) (DG);
80  * 27-Nov-2003 : Added code to respect maxBarWidth setting (DG);
81  * 02-Feb-2004 : Fixed bug where 'drawBarOutline' flag is not respected (DG);
82  * 10-Feb-2004 : Small change to drawItem() method to make cut-and-paste
83  * overriding easier (DG);
84  * 04-Oct-2004 : Fixed bug with item label positioning when plot alignment is
85  * horizontal (DG);
86  * 05-Nov-2004 : Modified drawItem() signature (DG);
87  * 20-Apr-2005 : Renamed CategoryLabelGenerator
88  * --> CategoryItemLabelGenerator (DG);
89  * 25-Apr-2005 : Override initialise() method to fix bug 1189642 (DG);
90  * 09-Jun-2005 : Use addEntityItem from super class (DG);
91  */

92
93 package org.jfree.chart.renderer.category;
94
95 import java.awt.AlphaComposite JavaDoc;
96 import java.awt.Color JavaDoc;
97 import java.awt.Composite JavaDoc;
98 import java.awt.Font JavaDoc;
99 import java.awt.Graphics2D JavaDoc;
100 import java.awt.Image JavaDoc;
101 import java.awt.Paint JavaDoc;
102 import java.awt.Stroke JavaDoc;
103 import java.awt.geom.GeneralPath JavaDoc;
104 import java.awt.geom.Line2D JavaDoc;
105 import java.awt.geom.Point2D JavaDoc;
106 import java.awt.geom.Rectangle2D JavaDoc;
107 import java.io.IOException JavaDoc;
108 import java.io.ObjectInputStream JavaDoc;
109 import java.io.ObjectOutputStream JavaDoc;
110 import java.io.Serializable JavaDoc;
111
112 import org.jfree.chart.Effect3D;
113 import org.jfree.chart.axis.CategoryAxis;
114 import org.jfree.chart.axis.ValueAxis;
115 import org.jfree.chart.entity.EntityCollection;
116 import org.jfree.chart.labels.CategoryItemLabelGenerator;
117 import org.jfree.chart.labels.ItemLabelAnchor;
118 import org.jfree.chart.labels.ItemLabelPosition;
119 import org.jfree.chart.plot.CategoryPlot;
120 import org.jfree.chart.plot.Marker;
121 import org.jfree.chart.plot.Plot;
122 import org.jfree.chart.plot.PlotOrientation;
123 import org.jfree.chart.plot.PlotRenderingInfo;
124 import org.jfree.chart.plot.ValueMarker;
125 import org.jfree.data.Range;
126 import org.jfree.data.category.CategoryDataset;
127 import org.jfree.io.SerialUtilities;
128 import org.jfree.text.TextUtilities;
129 import org.jfree.ui.LengthAdjustmentType;
130 import org.jfree.ui.RectangleAnchor;
131 import org.jfree.ui.RectangleEdge;
132 import org.jfree.ui.TextAnchor;
133 import org.jfree.util.PublicCloneable;
134
135 /**
136  * A renderer for bars with a 3D effect, for use with the
137  * {@link org.jfree.chart.plot.CategoryPlot} class.
138  *
139  * @author Serge V. Grachov
140  */

141 public class BarRenderer3D extends BarRenderer
142                            implements Effect3D, Cloneable JavaDoc, PublicCloneable,
143                                       Serializable JavaDoc {
144
145     /** For serialization. */
146     private static final long serialVersionUID = 7686976503536003636L;
147     
148     /** The default x-offset for the 3D effect. */
149     public static final double DEFAULT_X_OFFSET = 12.0;
150
151     /** The default y-offset for the 3D effect. */
152     public static final double DEFAULT_Y_OFFSET = 8.0;
153
154     /** The default wall paint. */
155     public static final Paint JavaDoc DEFAULT_WALL_PAINT = new Color JavaDoc(0xDD, 0xDD, 0xDD);
156
157     /** The size of x-offset for the 3D effect. */
158     private double xOffset;
159
160     /** The size of y-offset for the 3D effect. */
161     private double yOffset;
162
163     /** The paint used to shade the left and lower 3D wall. */
164     private transient Paint JavaDoc wallPaint;
165
166     /**
167      * Default constructor, creates a renderer with a ten pixel '3D effect'.
168      */

169     public BarRenderer3D() {
170         this(DEFAULT_X_OFFSET, DEFAULT_Y_OFFSET);
171     }
172
173     /**
174      * Constructs a new renderer with the specified '3D effect'.
175      *
176      * @param xOffset the x-offset for the 3D effect.
177      * @param yOffset the y-offset for the 3D effect.
178      */

179     public BarRenderer3D(double xOffset, double yOffset) {
180
181         super();
182         this.xOffset = xOffset;
183         this.yOffset = yOffset;
184         this.wallPaint = DEFAULT_WALL_PAINT;
185         // set the default item label positions
186
ItemLabelPosition p1 = new ItemLabelPosition(ItemLabelAnchor.INSIDE12,
187                 TextAnchor.TOP_CENTER);
188         setPositiveItemLabelPosition(p1);
189         ItemLabelPosition p2 = new ItemLabelPosition(ItemLabelAnchor.INSIDE12,
190                 TextAnchor.TOP_CENTER);
191         setNegativeItemLabelPosition(p2);
192
193     }
194
195     /**
196      * Returns the x-offset for the 3D effect.
197      *
198      * @return The 3D effect.
199      */

200     public double getXOffset() {
201         return this.xOffset;
202     }
203
204     /**
205      * Returns the y-offset for the 3D effect.
206      *
207      * @return The 3D effect.
208      */

209     public double getYOffset() {
210         return this.yOffset;
211     }
212
213     /**
214      * Returns the paint used to highlight the left and bottom wall in the plot
215      * background.
216      *
217      * @return The paint.
218      */

219     public Paint JavaDoc getWallPaint() {
220         return this.wallPaint;
221     }
222
223     /**
224      * Sets the paint used to hightlight the left and bottom walls in the plot
225      * background.
226      *
227      * @param paint the paint.
228      */

229     public void setWallPaint(Paint JavaDoc paint) {
230         this.wallPaint = paint;
231     }
232
233
234     /**
235      * Initialises the renderer and returns a state object that will be passed
236      * to subsequent calls to the drawItem method. This method gets called
237      * once at the start of the process of drawing a chart.
238      *
239      * @param g2 the graphics device.
240      * @param dataArea the area in which the data is to be plotted.
241      * @param plot the plot.
242      * @param rendererIndex the renderer index.
243      * @param info collects chart rendering information for return to caller.
244      *
245      * @return The renderer state.
246      */

247     public CategoryItemRendererState initialise(Graphics2D JavaDoc g2,
248                                                 Rectangle2D JavaDoc dataArea,
249                                                 CategoryPlot plot,
250                                                 int rendererIndex,
251                                                 PlotRenderingInfo info) {
252
253         Rectangle2D JavaDoc adjusted = new Rectangle2D.Double JavaDoc(dataArea.getX(),
254                 dataArea.getY() + getYOffset(), dataArea.getWidth()
255                 - getXOffset(), dataArea.getHeight() - getYOffset());
256         CategoryItemRendererState state = super.initialise(g2, adjusted, plot,
257                 rendererIndex, info);
258         return state;
259         
260     }
261     
262     /**
263      * Draws the background for the plot.
264      *
265      * @param g2 the graphics device.
266      * @param plot the plot.
267      * @param dataArea the area inside the axes.
268      */

269     public void drawBackground(Graphics2D JavaDoc g2, CategoryPlot plot,
270                                Rectangle2D JavaDoc dataArea) {
271
272         float x0 = (float) dataArea.getX();
273         float x1 = x0 + (float) Math.abs(this.xOffset);
274         float x3 = (float) dataArea.getMaxX();
275         float x2 = x3 - (float) Math.abs(this.xOffset);
276
277         float y0 = (float) dataArea.getMaxY();
278         float y1 = y0 - (float) Math.abs(this.yOffset);
279         float y3 = (float) dataArea.getMinY();
280         float y2 = y3 + (float) Math.abs(this.yOffset);
281
282         GeneralPath JavaDoc clip = new GeneralPath JavaDoc();
283         clip.moveTo(x0, y0);
284         clip.lineTo(x0, y2);
285         clip.lineTo(x1, y3);
286         clip.lineTo(x3, y3);
287         clip.lineTo(x3, y1);
288         clip.lineTo(x2, y0);
289         clip.closePath();
290
291         // fill background...
292
Paint JavaDoc backgroundPaint = plot.getBackgroundPaint();
293         if (backgroundPaint != null) {
294             g2.setPaint(backgroundPaint);
295             g2.fill(clip);
296         }
297
298         GeneralPath JavaDoc leftWall = new GeneralPath JavaDoc();
299         leftWall.moveTo(x0, y0);
300         leftWall.lineTo(x0, y2);
301         leftWall.lineTo(x1, y3);
302         leftWall.lineTo(x1, y1);
303         leftWall.closePath();
304         g2.setPaint(getWallPaint());
305         g2.fill(leftWall);
306
307         GeneralPath JavaDoc bottomWall = new GeneralPath JavaDoc();
308         bottomWall.moveTo(x0, y0);
309         bottomWall.lineTo(x1, y1);
310         bottomWall.lineTo(x3, y1);
311         bottomWall.lineTo(x2, y0);
312         bottomWall.closePath();
313         g2.setPaint(getWallPaint());
314         g2.fill(bottomWall);
315
316         // higlight the background corners...
317
g2.setPaint(Color.lightGray);
318         Line2D JavaDoc corner = new Line2D.Double JavaDoc(x0, y0, x1, y1);
319         g2.draw(corner);
320         corner.setLine(x1, y1, x1, y3);
321         g2.draw(corner);
322         corner.setLine(x1, y1, x3, y1);
323         g2.draw(corner);
324
325         // draw background image, if there is one...
326
Image JavaDoc backgroundImage = plot.getBackgroundImage();
327         if (backgroundImage != null) {
328             Composite JavaDoc originalComposite = g2.getComposite();
329             g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC,
330                     plot.getBackgroundAlpha()));
331             g2.drawImage(backgroundImage, (int) x1, (int) y3,
332                     (int) (x3 - x1 + 1), (int) (y1 - y3 + 1), null);
333             g2.setComposite(originalComposite);
334         }
335
336     }
337
338     /**
339      * Draws the outline for the plot.
340      *
341      * @param g2 the graphics device.
342      * @param plot the plot.
343      * @param dataArea the area inside the axes.
344      */

345     public void drawOutline(Graphics2D JavaDoc g2, CategoryPlot plot,
346                             Rectangle2D JavaDoc dataArea) {
347
348         float x0 = (float) dataArea.getX();
349         float x1 = x0 + (float) Math.abs(this.xOffset);
350         float x3 = (float) dataArea.getMaxX();
351         float x2 = x3 - (float) Math.abs(this.xOffset);
352
353         float y0 = (float) dataArea.getMaxY();
354         float y1 = y0 - (float) Math.abs(this.yOffset);
355         float y3 = (float) dataArea.getMinY();
356         float y2 = y3 + (float) Math.abs(this.yOffset);
357
358         GeneralPath JavaDoc clip = new GeneralPath JavaDoc();
359         clip.moveTo(x0, y0);
360         clip.lineTo(x0, y2);
361         clip.lineTo(x1, y3);
362         clip.lineTo(x3, y3);
363         clip.lineTo(x3, y1);
364         clip.lineTo(x2, y0);
365         clip.closePath();
366
367         // put an outline around the data area...
368
Stroke JavaDoc outlineStroke = plot.getOutlineStroke();
369         Paint JavaDoc outlinePaint = plot.getOutlinePaint();
370         if ((outlineStroke != null) && (outlinePaint != null)) {
371             g2.setStroke(outlineStroke);
372             g2.setPaint(outlinePaint);
373             g2.draw(clip);
374         }
375
376     }
377
378     /**
379      * Draws a grid line against the domain axis.
380      *
381      * @param g2 the graphics device.
382      * @param plot the plot.
383      * @param dataArea the area for plotting data (not yet adjusted for any
384      * 3D effect).
385      * @param value the Java2D value at which the grid line should be drawn.
386      *
387      */

388     public void drawDomainGridline(Graphics2D JavaDoc g2,
389                                    CategoryPlot plot,
390                                    Rectangle2D JavaDoc dataArea,
391                                    double value) {
392
393         Line2D JavaDoc line1 = null;
394         Line2D JavaDoc line2 = null;
395         PlotOrientation orientation = plot.getOrientation();
396         if (orientation == PlotOrientation.HORIZONTAL) {
397             double y0 = value;
398             double y1 = value - getYOffset();
399             double x0 = dataArea.getMinX();
400             double x1 = x0 + getXOffset();
401             double x2 = dataArea.getMaxY();
402             line1 = new Line2D.Double JavaDoc(x0, y0, x1, y1);
403             line2 = new Line2D.Double JavaDoc(x1, y1, x2, y1);
404         }
405         else if (orientation == PlotOrientation.VERTICAL) {
406             double x0 = value;
407             double x1 = value + getXOffset();
408             double y0 = dataArea.getMaxY();
409             double y1 = y0 - getYOffset();
410             double y2 = dataArea.getMinY();
411             line1 = new Line2D.Double JavaDoc(x0, y0, x1, y1);
412             line2 = new Line2D.Double JavaDoc(x1, y1, x1, y2);
413         }
414         Paint JavaDoc paint = plot.getDomainGridlinePaint();
415         Stroke JavaDoc stroke = plot.getDomainGridlineStroke();
416         g2.setPaint(paint != null ? paint : Plot.DEFAULT_OUTLINE_PAINT);
417         g2.setStroke(stroke != null ? stroke : Plot.DEFAULT_OUTLINE_STROKE);
418         g2.draw(line1);
419         g2.draw(line2);
420
421     }
422
423     /**
424      * Draws a grid line against the range axis.
425      *
426      * @param g2 the graphics device.
427      * @param plot the plot.
428      * @param axis the value axis.
429      * @param dataArea the area for plotting data (not yet adjusted for any
430      * 3D effect).
431      * @param value the value at which the grid line should be drawn.
432      *
433      */

434     public void drawRangeGridline(Graphics2D JavaDoc g2,
435                                   CategoryPlot plot,
436                                   ValueAxis axis,
437                                   Rectangle2D JavaDoc dataArea,
438                                   double value) {
439
440         Range range = axis.getRange();
441
442         if (!range.contains(value)) {
443             return;
444         }
445
446         Rectangle2D JavaDoc adjusted = new Rectangle2D.Double JavaDoc(dataArea.getX(),
447                 dataArea.getY() + getYOffset(), dataArea.getWidth()
448                 - getXOffset(), dataArea.getHeight() - getYOffset());
449
450         Line2D JavaDoc line1 = null;
451         Line2D JavaDoc line2 = null;
452         PlotOrientation orientation = plot.getOrientation();
453         if (orientation == PlotOrientation.HORIZONTAL) {
454             double x0 = axis.valueToJava2D(value, adjusted,
455                     plot.getRangeAxisEdge());
456             double x1 = x0 + getXOffset();
457             double y0 = dataArea.getMaxY();
458             double y1 = y0 - getYOffset();
459             double y2 = dataArea.getMinY();
460             line1 = new Line2D.Double JavaDoc(x0, y0, x1, y1);
461             line2 = new Line2D.Double JavaDoc(x1, y1, x1, y2);
462         }
463         else if (orientation == PlotOrientation.VERTICAL) {
464             double y0 = axis.valueToJava2D(value, adjusted,
465                     plot.getRangeAxisEdge());
466             double y1 = y0 - getYOffset();
467             double x0 = dataArea.getMinX();
468             double x1 = x0 + getXOffset();
469             double x2 = dataArea.getMaxX();
470             line1 = new Line2D.Double JavaDoc(x0, y0, x1, y1);
471             line2 = new Line2D.Double JavaDoc(x1, y1, x2, y1);
472         }
473         Paint JavaDoc paint = plot.getRangeGridlinePaint();
474         Stroke JavaDoc stroke = plot.getRangeGridlineStroke();
475         g2.setPaint(paint != null ? paint : Plot.DEFAULT_OUTLINE_PAINT);
476         g2.setStroke(stroke != null ? stroke : Plot.DEFAULT_OUTLINE_STROKE);
477         g2.draw(line1);
478         g2.draw(line2);
479
480     }
481
482     /**
483      * Draws a range marker.
484      *
485      * @param g2 the graphics device.
486      * @param plot the plot.
487      * @param axis the value axis.
488      * @param marker the marker.
489      * @param dataArea the area for plotting data (not including 3D effect).
490      */

491     public void drawRangeMarker(Graphics2D JavaDoc g2,
492                                 CategoryPlot plot,
493                                 ValueAxis axis,
494                                 Marker marker,
495                                 Rectangle2D JavaDoc dataArea) {
496
497         if (marker instanceof ValueMarker) {
498             ValueMarker vm = (ValueMarker) marker;
499             double value = vm.getValue();
500             Range range = axis.getRange();
501             if (!range.contains(value)) {
502                 return;
503             }
504
505             Rectangle2D JavaDoc adjusted = new Rectangle2D.Double JavaDoc(dataArea.getX(),
506                     dataArea.getY() + getYOffset(), dataArea.getWidth()
507                     - getXOffset(), dataArea.getHeight() - getYOffset());
508
509             GeneralPath JavaDoc path = null;
510             PlotOrientation orientation = plot.getOrientation();
511             if (orientation == PlotOrientation.HORIZONTAL) {
512                 float x = (float) axis.valueToJava2D(value, adjusted,
513                         plot.getRangeAxisEdge());
514                 float y = (float) adjusted.getMaxY();
515                 path = new GeneralPath JavaDoc();
516                 path.moveTo(x, y);
517                 path.lineTo((float) (x + getXOffset()),
518                         y - (float) getYOffset());
519                 path.lineTo((float) (x + getXOffset()),
520                         (float) (adjusted.getMinY() - getYOffset()));
521                 path.lineTo(x, (float) adjusted.getMinY());
522                 path.closePath();
523             }
524             else if (orientation == PlotOrientation.VERTICAL) {
525                 float y = (float) axis.valueToJava2D(value, adjusted,
526                         plot.getRangeAxisEdge());
527                 float x = (float) dataArea.getX();
528                 path = new GeneralPath JavaDoc();
529                 path.moveTo(x, y);
530                 path.lineTo(x + (float) this.xOffset, y - (float) this.yOffset);
531                 path.lineTo((float) (adjusted.getMaxX() + this.xOffset),
532                         y - (float) this.yOffset);
533                 path.lineTo((float) (adjusted.getMaxX()), y);
534                 path.closePath();
535             }
536             g2.setPaint(marker.getPaint());
537             g2.fill(path);
538             g2.setPaint(marker.getOutlinePaint());
539             g2.draw(path);
540         
541             String JavaDoc label = marker.getLabel();
542             RectangleAnchor anchor = marker.getLabelAnchor();
543             if (label != null) {
544                 Font JavaDoc labelFont = marker.getLabelFont();
545                 g2.setFont(labelFont);
546                 g2.setPaint(marker.getLabelPaint());
547                 Point2D JavaDoc coordinates = calculateRangeMarkerTextAnchorPoint(
548                         g2, orientation, dataArea, path.getBounds2D(),
549                         marker.getLabelOffset(), LengthAdjustmentType.EXPAND,
550                         anchor);
551                 TextUtilities.drawAlignedString(label, g2,
552                         (float) coordinates.getX(), (float) coordinates.getY(),
553                         marker.getLabelTextAnchor());
554             }
555         
556         }
557         else {
558             super.drawRangeMarker(g2, plot, axis, marker, dataArea);
559             // TODO: draw the interval marker with a 3D effect
560
}
561     }
562
563     /**
564      * Draws a 3D bar to represent one data item.
565      *
566      * @param g2 the graphics device.
567      * @param state the renderer state.
568      * @param dataArea the area for plotting the data.
569      * @param plot the plot.
570      * @param domainAxis the domain axis.
571      * @param rangeAxis the range axis.
572      * @param dataset the dataset.
573      * @param row the row index (zero-based).
574      * @param column the column index (zero-based).
575      * @param pass the pass index.
576      */

577     public void drawItem(Graphics2D JavaDoc g2,
578                          CategoryItemRendererState state,
579                          Rectangle2D JavaDoc dataArea,
580                          CategoryPlot plot,
581                          CategoryAxis domainAxis,
582                          ValueAxis rangeAxis,
583                          CategoryDataset dataset,
584                          int row,
585                          int column,
586                          int pass) {
587     
588         // check the value we are plotting...
589
Number JavaDoc dataValue = dataset.getValue(row, column);
590         if (dataValue == null) {
591             return;
592         }
593         
594         double value = dataValue.doubleValue();
595         
596         Rectangle2D JavaDoc adjusted = new Rectangle2D.Double JavaDoc(dataArea.getX(),
597                 dataArea.getY() + getYOffset(),
598                 dataArea.getWidth() - getXOffset(),
599                 dataArea.getHeight() - getYOffset());
600
601         PlotOrientation orientation = plot.getOrientation();
602         
603         double barW0 = calculateBarW0(plot, orientation, adjusted, domainAxis,
604                 state, row, column);
605         double[] barL0L1 = calculateBarL0L1(value);
606         if (barL0L1 == null) {
607             return; // the bar is not visible
608
}
609
610         RectangleEdge edge = plot.getRangeAxisEdge();
611         double transL0 = rangeAxis.valueToJava2D(barL0L1[0], adjusted, edge);
612         double transL1 = rangeAxis.valueToJava2D(barL0L1[1], adjusted, edge);
613         double barL0 = Math.min(transL0, transL1);
614         double barLength = Math.abs(transL1 - transL0);
615         
616         // draw the bar...
617
Rectangle2D JavaDoc bar = null;
618         if (orientation == PlotOrientation.HORIZONTAL) {
619             bar = new Rectangle2D.Double JavaDoc(barL0, barW0, barLength,
620                     state.getBarWidth());
621         }
622         else {
623             bar = new Rectangle2D.Double JavaDoc(barW0, barL0, state.getBarWidth(),
624                     barLength);
625         }
626         Paint JavaDoc itemPaint = getItemPaint(row, column);
627         g2.setPaint(itemPaint);
628         g2.fill(bar);
629
630         double x0 = bar.getMinX();
631         double x1 = x0 + getXOffset();
632         double x2 = bar.getMaxX();
633         double x3 = x2 + getXOffset();
634         
635         double y0 = bar.getMinY() - getYOffset();
636         double y1 = bar.getMinY();
637         double y2 = bar.getMaxY() - getYOffset();
638         double y3 = bar.getMaxY();
639         
640         GeneralPath JavaDoc bar3dRight = null;
641         GeneralPath JavaDoc bar3dTop = null;
642         if (barLength > 0.0) {
643             bar3dRight = new GeneralPath JavaDoc();
644             bar3dRight.moveTo((float) x2, (float) y3);
645             bar3dRight.lineTo((float) x2, (float) y1);
646             bar3dRight.lineTo((float) x3, (float) y0);
647             bar3dRight.lineTo((float) x3, (float) y2);
648             bar3dRight.closePath();
649
650             if (itemPaint instanceof Color JavaDoc) {
651                 g2.setPaint(((Color JavaDoc) itemPaint).darker());
652             }
653             g2.fill(bar3dRight);
654         }
655
656         bar3dTop = new GeneralPath JavaDoc();
657         bar3dTop.moveTo((float) x0, (float) y1);
658         bar3dTop.lineTo((float) x1, (float) y0);
659         bar3dTop.lineTo((float) x3, (float) y0);
660         bar3dTop.lineTo((float) x2, (float) y1);
661         bar3dTop.closePath();
662         g2.fill(bar3dTop);
663
664         if (isDrawBarOutline()
665                 && state.getBarWidth() > BAR_OUTLINE_WIDTH_THRESHOLD) {
666             g2.setStroke(getItemOutlineStroke(row, column));
667             g2.setPaint(getItemOutlinePaint(row, column));
668             g2.draw(bar);
669             if (bar3dRight != null) {
670                 g2.draw(bar3dRight);
671             }
672             if (bar3dTop != null) {
673                 g2.draw(bar3dTop);
674             }
675         }
676
677         CategoryItemLabelGenerator generator
678             = getItemLabelGenerator(row, column);
679         if (generator != null && isItemLabelVisible(row, column)) {
680             drawItemLabel(g2, dataset, row, column, plot, generator, bar,
681                     (value < 0.0));
682         }
683
684         // add an item entity, if this information is being collected
685
EntityCollection entities = state.getEntityCollection();
686         if (entities != null) {
687             GeneralPath JavaDoc barOutline = new GeneralPath JavaDoc();
688             barOutline.moveTo((float) x0, (float) y3);
689             barOutline.lineTo((float) x0, (float) y1);
690             barOutline.lineTo((float) x1, (float) y0);
691             barOutline.lineTo((float) x3, (float) y0);
692             barOutline.lineTo((float) x3, (float) y2);
693             barOutline.lineTo((float) x2, (float) y3);
694             barOutline.closePath();
695             addItemEntity(entities, dataset, row, column, barOutline);
696         }
697
698     }
699
700     /**
701      * Provides serialization support.
702      *
703      * @param stream the output stream.
704      *
705      * @throws IOException if there is an I/O error.
706      */

707     private void writeObject(ObjectOutputStream JavaDoc stream) throws IOException JavaDoc {
708         stream.defaultWriteObject();
709         SerialUtilities.writePaint(this.wallPaint, stream);
710     }
711
712     /**
713      * Provides serialization support.
714      *
715      * @param stream the input stream.
716      *
717      * @throws IOException if there is an I/O error.
718      * @throws ClassNotFoundException if there is a classpath problem.
719      */

720     private void readObject(ObjectInputStream JavaDoc stream)
721         throws IOException JavaDoc, ClassNotFoundException JavaDoc {
722         stream.defaultReadObject();
723         this.wallPaint = SerialUtilities.readPaint(stream);
724     }
725
726 }
727
Popular Tags