Source Code Cross Referenced for BarRenderer.java in  » Chart » jfreechart » org » jfree » chart » renderer » category » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Chart » jfreechart » org.jfree.chart.renderer.category 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /* ===========================================================
0002:         * JFreeChart : a free chart library for the Java(tm) platform
0003:         * ===========================================================
0004:         *
0005:         * (C) Copyright 2000-2007, by Object Refinery Limited and Contributors.
0006:         *
0007:         * Project Info:  http://www.jfree.org/jfreechart/index.html
0008:         *
0009:         * This library is free software; you can redistribute it and/or modify it 
0010:         * under the terms of the GNU Lesser General Public License as published by 
0011:         * the Free Software Foundation; either version 2.1 of the License, or 
0012:         * (at your option) any later version.
0013:         *
0014:         * This library is distributed in the hope that it will be useful, but 
0015:         * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
0016:         * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
0017:         * License for more details.
0018:         *
0019:         * You should have received a copy of the GNU Lesser General Public
0020:         * License along with this library; if not, write to the Free Software
0021:         * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
0022:         * USA.  
0023:         *
0024:         * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 
0025:         * in the United States and other countries.]
0026:         *
0027:         * ----------------
0028:         * BarRenderer.java
0029:         * ----------------
0030:         * (C) Copyright 2002-2007, by Object Refinery Limited.
0031:         *
0032:         * Original Author:  David Gilbert (for Object Refinery Limited);
0033:         * Contributor(s):   Christian W. Zuckschwerdt;
0034:         *
0035:         * $Id: BarRenderer.java,v 1.13.2.18 2007/05/18 10:28:27 mungady Exp $
0036:         *
0037:         * Changes
0038:         * -------
0039:         * 14-Mar-2002 : Version 1 (DG);
0040:         * 23-May-2002 : Added tooltip generator to renderer (DG);
0041:         * 29-May-2002 : Moved tooltip generator to abstract super-class (DG);
0042:         * 25-Jun-2002 : Changed constructor to protected and removed redundant 
0043:         *               code (DG);
0044:         * 26-Jun-2002 : Added axis to initialise method, and record upper and lower 
0045:         *               clip values (DG);
0046:         * 24-Sep-2002 : Added getLegendItem() method (DG);
0047:         * 09-Oct-2002 : Modified constructor to include URL generator (DG);
0048:         * 05-Nov-2002 : Base dataset is now TableDataset not CategoryDataset (DG);
0049:         * 10-Jan-2003 : Moved get/setItemMargin() method up from subclasses (DG);
0050:         * 17-Jan-2003 : Moved plot classes into a separate package (DG);
0051:         * 25-Mar-2003 : Implemented Serializable (DG);
0052:         * 01-May-2003 : Modified clipping to allow for dual axes and datasets (DG);
0053:         * 12-May-2003 : Merged horizontal and vertical bar renderers (DG);
0054:         * 12-Jun-2003 : Updates for item labels (DG);
0055:         * 30-Jul-2003 : Modified entity constructor (CZ);
0056:         * 02-Sep-2003 : Changed initialise method to fix bug 790407 (DG);
0057:         * 16-Sep-2003 : Changed ChartRenderingInfo --> PlotRenderingInfo (DG);
0058:         * 07-Oct-2003 : Added renderer state (DG);
0059:         * 27-Oct-2003 : Merged drawHorizontalItem() and drawVerticalItem() 
0060:         *               methods (DG);
0061:         * 28-Oct-2003 : Added support for gradient paint on bars (DG);
0062:         * 14-Nov-2003 : Added 'maxBarWidth' attribute (DG);
0063:         * 10-Feb-2004 : Small changes inside drawItem() method to ease cut-and-paste 
0064:         *               overriding (DG);
0065:         * 19-Mar-2004 : Fixed bug introduced with separation of tool tip and item 
0066:         *               label generators.  Fixed equals() method (DG);
0067:         * 11-May-2004 : Fix for null pointer exception (bug id 951127) (DG);
0068:         * 05-Nov-2004 : Modified drawItem() signature (DG);
0069:         * 26-Jan-2005 : Provided override for getLegendItem() method (DG);
0070:         * 20-Apr-2005 : Generate legend labels, tooltips and URLs (DG);
0071:         * 18-May-2005 : Added configurable base value (DG);
0072:         * 09-Jun-2005 : Use addItemEntity() method from superclass (DG);
0073:         * 01-Dec-2005 : Update legend item to use/not use outline (DG);
0074:         * ------------: JFreeChart 1.0.x ---------------------------------------------
0075:         * 06-Dec-2005 : Fixed bug 1374222 (JDK 1.4 specific code) (DG);
0076:         * 11-Jan-2006 : Fixed bug 1401856 (bad rendering for non-zero base) (DG);
0077:         * 04-Aug-2006 : Fixed bug 1467706 (missing item labels for zero value 
0078:         *               bars) (DG);
0079:         * 04-Dec-2006 : Fixed bug in rendering to non-primary axis (DG);
0080:         * 13-Dec-2006 : Add support for GradientPaint display in legend items (DG);
0081:         * 20-Apr-2007 : Updated getLegendItem() for renderer change (DG);
0082:         * 11-May-2007 : Check for visibility in getLegendItem() (DG);
0083:         * 17-May-2007 : Set datasetIndex and seriesIndex in getLegendItem() (DG);
0084:         * 18-May-2007 : Set dataset and seriesKey for LegendItem (DG);
0085:         * 
0086:         */
0087:
0088:        package org.jfree.chart.renderer.category;
0089:
0090:        import java.awt.BasicStroke;
0091:        import java.awt.Color;
0092:        import java.awt.Font;
0093:        import java.awt.GradientPaint;
0094:        import java.awt.Graphics2D;
0095:        import java.awt.Paint;
0096:        import java.awt.Shape;
0097:        import java.awt.Stroke;
0098:        import java.awt.geom.Line2D;
0099:        import java.awt.geom.Point2D;
0100:        import java.awt.geom.Rectangle2D;
0101:        import java.io.Serializable;
0102:
0103:        import org.jfree.chart.LegendItem;
0104:        import org.jfree.chart.axis.CategoryAxis;
0105:        import org.jfree.chart.axis.ValueAxis;
0106:        import org.jfree.chart.entity.EntityCollection;
0107:        import org.jfree.chart.event.RendererChangeEvent;
0108:        import org.jfree.chart.labels.CategoryItemLabelGenerator;
0109:        import org.jfree.chart.labels.ItemLabelAnchor;
0110:        import org.jfree.chart.labels.ItemLabelPosition;
0111:        import org.jfree.chart.plot.CategoryPlot;
0112:        import org.jfree.chart.plot.PlotOrientation;
0113:        import org.jfree.chart.plot.PlotRenderingInfo;
0114:        import org.jfree.data.Range;
0115:        import org.jfree.data.category.CategoryDataset;
0116:        import org.jfree.data.general.DatasetUtilities;
0117:        import org.jfree.text.TextUtilities;
0118:        import org.jfree.ui.GradientPaintTransformer;
0119:        import org.jfree.ui.RectangleEdge;
0120:        import org.jfree.ui.StandardGradientPaintTransformer;
0121:        import org.jfree.util.ObjectUtilities;
0122:        import org.jfree.util.PublicCloneable;
0123:
0124:        /**
0125:         * A {@link CategoryItemRenderer} that draws individual data items as bars.
0126:         */
0127:        public class BarRenderer extends AbstractCategoryItemRenderer implements 
0128:                Cloneable, PublicCloneable, Serializable {
0129:
0130:            /** For serialization. */
0131:            private static final long serialVersionUID = 6000649414965887481L;
0132:
0133:            /** The default item margin percentage. */
0134:            public static final double DEFAULT_ITEM_MARGIN = 0.20;
0135:
0136:            /** 
0137:             * Constant that controls the minimum width before a bar has an outline 
0138:             * drawn. 
0139:             */
0140:            public static final double BAR_OUTLINE_WIDTH_THRESHOLD = 3.0;
0141:
0142:            /** The margin between items (bars) within a category. */
0143:            private double itemMargin;
0144:
0145:            /** A flag that controls whether or not bar outlines are drawn. */
0146:            private boolean drawBarOutline;
0147:
0148:            /** The maximum bar width as a percentage of the available space. */
0149:            private double maximumBarWidth;
0150:
0151:            /** The minimum bar length (in Java2D units). */
0152:            private double minimumBarLength;
0153:
0154:            /** 
0155:             * An optional class used to transform gradient paint objects to fit each 
0156:             * bar. 
0157:             */
0158:            private GradientPaintTransformer gradientPaintTransformer;
0159:
0160:            /** 
0161:             * The fallback position if a positive item label doesn't fit inside the 
0162:             * bar. 
0163:             */
0164:            private ItemLabelPosition positiveItemLabelPositionFallback;
0165:
0166:            /** 
0167:             * The fallback position if a negative item label doesn't fit inside the 
0168:             * bar. 
0169:             */
0170:            private ItemLabelPosition negativeItemLabelPositionFallback;
0171:
0172:            /** The upper clip (axis) value for the axis. */
0173:            private double upperClip;
0174:            // TODO:  this needs to move into the renderer state
0175:
0176:            /** The lower clip (axis) value for the axis. */
0177:            private double lowerClip;
0178:            // TODO:  this needs to move into the renderer state
0179:
0180:            /** The base value for the bars (defaults to 0.0). */
0181:            private double base;
0182:
0183:            /** 
0184:             * A flag that controls whether the base value is included in the range
0185:             * returned by the findRangeBounds() method.
0186:             */
0187:            private boolean includeBaseInRange;
0188:
0189:            /**
0190:             * Creates a new bar renderer with default settings.
0191:             */
0192:            public BarRenderer() {
0193:                super ();
0194:                this .base = 0.0;
0195:                this .includeBaseInRange = true;
0196:                this .itemMargin = DEFAULT_ITEM_MARGIN;
0197:                this .drawBarOutline = true;
0198:                this .maximumBarWidth = 1.0;
0199:                // 100 percent, so it will not apply unless changed
0200:                this .positiveItemLabelPositionFallback = null;
0201:                this .negativeItemLabelPositionFallback = null;
0202:                this .gradientPaintTransformer = new StandardGradientPaintTransformer();
0203:                this .minimumBarLength = 0.0;
0204:            }
0205:
0206:            /**
0207:             * Returns the base value for the bars.  The default value is 
0208:             * <code>0.0</code>.
0209:             * 
0210:             * @return The base value for the bars.
0211:             * 
0212:             * @see #setBase(double)
0213:             */
0214:            public double getBase() {
0215:                return this .base;
0216:            }
0217:
0218:            /**
0219:             * Sets the base value for the bars and sends a {@link RendererChangeEvent}
0220:             * to all registered listeners.
0221:             * 
0222:             * @param base  the new base value.
0223:             * 
0224:             * @see #getBase()
0225:             */
0226:            public void setBase(double base) {
0227:                this .base = base;
0228:                notifyListeners(new RendererChangeEvent(this ));
0229:            }
0230:
0231:            /**
0232:             * Returns the item margin as a percentage of the available space for all 
0233:             * bars.
0234:             *
0235:             * @return The margin percentage (where 0.10 is ten percent).
0236:             * 
0237:             * @see #setItemMargin(double)
0238:             */
0239:            public double getItemMargin() {
0240:                return this .itemMargin;
0241:            }
0242:
0243:            /**
0244:             * Sets the item margin and sends a {@link RendererChangeEvent} to all 
0245:             * registered listeners.  The value is expressed as a percentage of the 
0246:             * available width for plotting all the bars, with the resulting amount to 
0247:             * be distributed between all the bars evenly.
0248:             *
0249:             * @param percent  the margin (where 0.10 is ten percent).
0250:             * 
0251:             * @see #getItemMargin()
0252:             */
0253:            public void setItemMargin(double percent) {
0254:                this .itemMargin = percent;
0255:                notifyListeners(new RendererChangeEvent(this ));
0256:            }
0257:
0258:            /**
0259:             * Returns a flag that controls whether or not bar outlines are drawn.
0260:             * 
0261:             * @return A boolean.
0262:             * 
0263:             * @see #setDrawBarOutline(boolean)
0264:             */
0265:            public boolean isDrawBarOutline() {
0266:                return this .drawBarOutline;
0267:            }
0268:
0269:            /**
0270:             * Sets the flag that controls whether or not bar outlines are drawn and 
0271:             * sends a {@link RendererChangeEvent} to all registered listeners.
0272:             * 
0273:             * @param draw  the flag.
0274:             * 
0275:             * @see #isDrawBarOutline()
0276:             */
0277:            public void setDrawBarOutline(boolean draw) {
0278:                this .drawBarOutline = draw;
0279:                notifyListeners(new RendererChangeEvent(this ));
0280:            }
0281:
0282:            /**
0283:             * Returns the maximum bar width, as a percentage of the available drawing 
0284:             * space.
0285:             * 
0286:             * @return The maximum bar width.
0287:             * 
0288:             * @see #setMaximumBarWidth(double)
0289:             */
0290:            public double getMaximumBarWidth() {
0291:                return this .maximumBarWidth;
0292:            }
0293:
0294:            /**
0295:             * Sets the maximum bar width, which is specified as a percentage of the 
0296:             * available space for all bars, and sends a {@link RendererChangeEvent} to
0297:             * all registered listeners.
0298:             * 
0299:             * @param percent  the percent (where 0.05 is five percent).
0300:             * 
0301:             * @see #getMaximumBarWidth()
0302:             */
0303:            public void setMaximumBarWidth(double percent) {
0304:                this .maximumBarWidth = percent;
0305:                notifyListeners(new RendererChangeEvent(this ));
0306:            }
0307:
0308:            /**
0309:             * Returns the minimum bar length (in Java2D units).
0310:             * 
0311:             * @return The minimum bar length.
0312:             * 
0313:             * @see #setMinimumBarLength(double)
0314:             */
0315:            public double getMinimumBarLength() {
0316:                return this .minimumBarLength;
0317:            }
0318:
0319:            /**
0320:             * Sets the minimum bar length and sends a {@link RendererChangeEvent} to 
0321:             * all registered listeners.  The minimum bar length is specified in Java2D
0322:             * units, and can be used to prevent bars that represent very small data 
0323:             * values from disappearing when drawn on the screen.
0324:             * 
0325:             * @param min  the minimum bar length (in Java2D units).
0326:             * 
0327:             * @see #getMinimumBarLength()
0328:             */
0329:            public void setMinimumBarLength(double min) {
0330:                this .minimumBarLength = min;
0331:                notifyListeners(new RendererChangeEvent(this ));
0332:            }
0333:
0334:            /**
0335:             * Returns the gradient paint transformer (an object used to transform 
0336:             * gradient paint objects to fit each bar).
0337:             * 
0338:             * @return A transformer (<code>null</code> possible).
0339:             * 
0340:             * @see #setGradientPaintTransformer(GradientPaintTransformer)
0341:             */
0342:            public GradientPaintTransformer getGradientPaintTransformer() {
0343:                return this .gradientPaintTransformer;
0344:            }
0345:
0346:            /**
0347:             * Sets the gradient paint transformer and sends a 
0348:             * {@link RendererChangeEvent} to all registered listeners.
0349:             * 
0350:             * @param transformer  the transformer (<code>null</code> permitted).
0351:             * 
0352:             * @see #getGradientPaintTransformer()
0353:             */
0354:            public void setGradientPaintTransformer(
0355:                    GradientPaintTransformer transformer) {
0356:                this .gradientPaintTransformer = transformer;
0357:                notifyListeners(new RendererChangeEvent(this ));
0358:            }
0359:
0360:            /**
0361:             * Returns the fallback position for positive item labels that don't fit 
0362:             * within a bar.
0363:             * 
0364:             * @return The fallback position (<code>null</code> possible).
0365:             * 
0366:             * @see #setPositiveItemLabelPositionFallback(ItemLabelPosition)
0367:             */
0368:            public ItemLabelPosition getPositiveItemLabelPositionFallback() {
0369:                return this .positiveItemLabelPositionFallback;
0370:            }
0371:
0372:            /**
0373:             * Sets the fallback position for positive item labels that don't fit 
0374:             * within a bar, and sends a {@link RendererChangeEvent} to all registered
0375:             * listeners.
0376:             * 
0377:             * @param position  the position (<code>null</code> permitted).
0378:             * 
0379:             * @see #getPositiveItemLabelPositionFallback()
0380:             */
0381:            public void setPositiveItemLabelPositionFallback(
0382:                    ItemLabelPosition position) {
0383:                this .positiveItemLabelPositionFallback = position;
0384:                notifyListeners(new RendererChangeEvent(this ));
0385:            }
0386:
0387:            /**
0388:             * Returns the fallback position for negative item labels that don't fit 
0389:             * within a bar.
0390:             * 
0391:             * @return The fallback position (<code>null</code> possible).
0392:             * 
0393:             * @see #setPositiveItemLabelPositionFallback(ItemLabelPosition)
0394:             */
0395:            public ItemLabelPosition getNegativeItemLabelPositionFallback() {
0396:                return this .negativeItemLabelPositionFallback;
0397:            }
0398:
0399:            /**
0400:             * Sets the fallback position for negative item labels that don't fit 
0401:             * within a bar, and sends a {@link RendererChangeEvent} to all registered
0402:             * listeners.
0403:             * 
0404:             * @param position  the position (<code>null</code> permitted).
0405:             * 
0406:             * @see #getNegativeItemLabelPositionFallback()
0407:             */
0408:            public void setNegativeItemLabelPositionFallback(
0409:                    ItemLabelPosition position) {
0410:                this .negativeItemLabelPositionFallback = position;
0411:                notifyListeners(new RendererChangeEvent(this ));
0412:            }
0413:
0414:            /**
0415:             * Returns the flag that controls whether or not the base value for the 
0416:             * bars is included in the range calculated by 
0417:             * {@link #findRangeBounds(CategoryDataset)}.
0418:             * 
0419:             * @return <code>true</code> if the base is included in the range, and
0420:             *         <code>false</code> otherwise.
0421:             * 
0422:             * @since 1.0.1
0423:             * 
0424:             * @see #setIncludeBaseInRange(boolean)
0425:             */
0426:            public boolean getIncludeBaseInRange() {
0427:                return this .includeBaseInRange;
0428:            }
0429:
0430:            /**
0431:             * Sets the flag that controls whether or not the base value for the bars 
0432:             * is included in the range calculated by 
0433:             * {@link #findRangeBounds(CategoryDataset)}.  If the flag is changed,
0434:             * a {@link RendererChangeEvent} is sent to all registered listeners.
0435:             * 
0436:             * @param include  the new value for the flag.
0437:             * 
0438:             * @since 1.0.1
0439:             * 
0440:             * @see #getIncludeBaseInRange()
0441:             */
0442:            public void setIncludeBaseInRange(boolean include) {
0443:                if (this .includeBaseInRange != include) {
0444:                    this .includeBaseInRange = include;
0445:                    notifyListeners(new RendererChangeEvent(this ));
0446:                }
0447:            }
0448:
0449:            /**
0450:             * Returns the lower clip value.  This value is recalculated in the 
0451:             * initialise() method.
0452:             *
0453:             * @return The value.
0454:             */
0455:            public double getLowerClip() {
0456:                // TODO:  this attribute should be transferred to the renderer state.
0457:                return this .lowerClip;
0458:            }
0459:
0460:            /**
0461:             * Returns the upper clip value.  This value is recalculated in the 
0462:             * initialise() method.
0463:             *
0464:             * @return The value.
0465:             */
0466:            public double getUpperClip() {
0467:                // TODO:  this attribute should be transferred to the renderer state.
0468:                return this .upperClip;
0469:            }
0470:
0471:            /**
0472:             * Initialises the renderer and returns a state object that will be passed 
0473:             * to subsequent calls to the drawItem method.  This method gets called 
0474:             * once at the start of the process of drawing a chart.
0475:             *
0476:             * @param g2  the graphics device.
0477:             * @param dataArea  the area in which the data is to be plotted.
0478:             * @param plot  the plot.
0479:             * @param rendererIndex  the renderer index.
0480:             * @param info  collects chart rendering information for return to caller.
0481:             * 
0482:             * @return The renderer state.
0483:             */
0484:            public CategoryItemRendererState initialise(Graphics2D g2,
0485:                    Rectangle2D dataArea, CategoryPlot plot, int rendererIndex,
0486:                    PlotRenderingInfo info) {
0487:
0488:                CategoryItemRendererState state = super .initialise(g2,
0489:                        dataArea, plot, rendererIndex, info);
0490:
0491:                // get the clipping values...
0492:                ValueAxis rangeAxis = plot
0493:                        .getRangeAxisForDataset(rendererIndex);
0494:                this .lowerClip = rangeAxis.getRange().getLowerBound();
0495:                this .upperClip = rangeAxis.getRange().getUpperBound();
0496:
0497:                // calculate the bar width
0498:                calculateBarWidth(plot, dataArea, rendererIndex, state);
0499:
0500:                return state;
0501:
0502:            }
0503:
0504:            /**
0505:             * Calculates the bar width and stores it in the renderer state.
0506:             * 
0507:             * @param plot  the plot.
0508:             * @param dataArea  the data area.
0509:             * @param rendererIndex  the renderer index.
0510:             * @param state  the renderer state.
0511:             */
0512:            protected void calculateBarWidth(CategoryPlot plot,
0513:                    Rectangle2D dataArea, int rendererIndex,
0514:                    CategoryItemRendererState state) {
0515:
0516:                CategoryAxis domainAxis = getDomainAxis(plot, rendererIndex);
0517:                CategoryDataset dataset = plot.getDataset(rendererIndex);
0518:                if (dataset != null) {
0519:                    int columns = dataset.getColumnCount();
0520:                    int rows = dataset.getRowCount();
0521:                    double space = 0.0;
0522:                    PlotOrientation orientation = plot.getOrientation();
0523:                    if (orientation == PlotOrientation.HORIZONTAL) {
0524:                        space = dataArea.getHeight();
0525:                    } else if (orientation == PlotOrientation.VERTICAL) {
0526:                        space = dataArea.getWidth();
0527:                    }
0528:                    double maxWidth = space * getMaximumBarWidth();
0529:                    double categoryMargin = 0.0;
0530:                    double currentItemMargin = 0.0;
0531:                    if (columns > 1) {
0532:                        categoryMargin = domainAxis.getCategoryMargin();
0533:                    }
0534:                    if (rows > 1) {
0535:                        currentItemMargin = getItemMargin();
0536:                    }
0537:                    double used = space
0538:                            * (1 - domainAxis.getLowerMargin()
0539:                                    - domainAxis.getUpperMargin()
0540:                                    - categoryMargin - currentItemMargin);
0541:                    if ((rows * columns) > 0) {
0542:                        state.setBarWidth(Math.min(used / (rows * columns),
0543:                                maxWidth));
0544:                    } else {
0545:                        state.setBarWidth(Math.min(used, maxWidth));
0546:                    }
0547:                }
0548:            }
0549:
0550:            /**
0551:             * Calculates the coordinate of the first "side" of a bar.  This will be 
0552:             * the minimum x-coordinate for a vertical bar, and the minimum 
0553:             * y-coordinate for a horizontal bar.
0554:             *
0555:             * @param plot  the plot.
0556:             * @param orientation  the plot orientation.
0557:             * @param dataArea  the data area.
0558:             * @param domainAxis  the domain axis.
0559:             * @param state  the renderer state (has the bar width precalculated).
0560:             * @param row  the row index.
0561:             * @param column  the column index.
0562:             * 
0563:             * @return The coordinate.
0564:             */
0565:            protected double calculateBarW0(CategoryPlot plot,
0566:                    PlotOrientation orientation, Rectangle2D dataArea,
0567:                    CategoryAxis domainAxis, CategoryItemRendererState state,
0568:                    int row, int column) {
0569:                // calculate bar width...
0570:                double space = 0.0;
0571:                if (orientation == PlotOrientation.HORIZONTAL) {
0572:                    space = dataArea.getHeight();
0573:                } else {
0574:                    space = dataArea.getWidth();
0575:                }
0576:                double barW0 = domainAxis.getCategoryStart(column,
0577:                        getColumnCount(), dataArea, plot.getDomainAxisEdge());
0578:                int seriesCount = getRowCount();
0579:                int categoryCount = getColumnCount();
0580:                if (seriesCount > 1) {
0581:                    double seriesGap = space * getItemMargin()
0582:                            / (categoryCount * (seriesCount - 1));
0583:                    double seriesW = calculateSeriesWidth(space, domainAxis,
0584:                            categoryCount, seriesCount);
0585:                    barW0 = barW0 + row * (seriesW + seriesGap)
0586:                            + (seriesW / 2.0) - (state.getBarWidth() / 2.0);
0587:                } else {
0588:                    barW0 = domainAxis.getCategoryMiddle(column,
0589:                            getColumnCount(), dataArea, plot
0590:                                    .getDomainAxisEdge())
0591:                            - state.getBarWidth() / 2.0;
0592:                }
0593:                return barW0;
0594:            }
0595:
0596:            /**
0597:             * Calculates the coordinates for the length of a single bar.
0598:             * 
0599:             * @param value  the value represented by the bar.
0600:             * 
0601:             * @return The coordinates for each end of the bar (or <code>null</code> if 
0602:             *         the bar is not visible for the current axis range).
0603:             */
0604:            protected double[] calculateBarL0L1(double value) {
0605:                double lclip = getLowerClip();
0606:                double uclip = getUpperClip();
0607:                double barLow = Math.min(this .base, value);
0608:                double barHigh = Math.max(this .base, value);
0609:                if (barHigh < lclip) { // bar is not visible
0610:                    return null;
0611:                }
0612:                if (barLow > uclip) { // bar is not visible
0613:                    return null;
0614:                }
0615:                barLow = Math.max(barLow, lclip);
0616:                barHigh = Math.min(barHigh, uclip);
0617:                return new double[] { barLow, barHigh };
0618:            }
0619:
0620:            /**
0621:             * Returns the range of values the renderer requires to display all the 
0622:             * items from the specified dataset.  This takes into account the range
0623:             * of values in the dataset, plus the flag that determines whether or not
0624:             * the base value for the bars should be included in the range.
0625:             * 
0626:             * @param dataset  the dataset (<code>null</code> permitted).
0627:             * 
0628:             * @return The range (or <code>null</code> if the dataset is 
0629:             *         <code>null</code> or empty).
0630:             */
0631:            public Range findRangeBounds(CategoryDataset dataset) {
0632:                Range result = DatasetUtilities.findRangeBounds(dataset);
0633:                if (result != null) {
0634:                    if (this .includeBaseInRange) {
0635:                        result = Range.expandToInclude(result, this .base);
0636:                    }
0637:                }
0638:                return result;
0639:            }
0640:
0641:            /**
0642:             * Returns a legend item for a series.
0643:             *
0644:             * @param datasetIndex  the dataset index (zero-based).
0645:             * @param series  the series index (zero-based).
0646:             *
0647:             * @return The legend item (possibly <code>null</code>).
0648:             */
0649:            public LegendItem getLegendItem(int datasetIndex, int series) {
0650:
0651:                CategoryPlot cp = getPlot();
0652:                if (cp == null) {
0653:                    return null;
0654:                }
0655:
0656:                // check that a legend item needs to be displayed...
0657:                if (!isSeriesVisible(series)
0658:                        || !isSeriesVisibleInLegend(series)) {
0659:                    return null;
0660:                }
0661:
0662:                CategoryDataset dataset = cp.getDataset(datasetIndex);
0663:                String label = getLegendItemLabelGenerator().generateLabel(
0664:                        dataset, series);
0665:                String description = label;
0666:                String toolTipText = null;
0667:                if (getLegendItemToolTipGenerator() != null) {
0668:                    toolTipText = getLegendItemToolTipGenerator()
0669:                            .generateLabel(dataset, series);
0670:                }
0671:                String urlText = null;
0672:                if (getLegendItemURLGenerator() != null) {
0673:                    urlText = getLegendItemURLGenerator().generateLabel(
0674:                            dataset, series);
0675:                }
0676:                Shape shape = new Rectangle2D.Double(-4.0, -4.0, 8.0, 8.0);
0677:                Paint paint = lookupSeriesPaint(series);
0678:                Paint outlinePaint = lookupSeriesOutlinePaint(series);
0679:                Stroke outlineStroke = lookupSeriesOutlineStroke(series);
0680:
0681:                LegendItem result = new LegendItem(label, description,
0682:                        toolTipText, urlText, true, shape, true, paint,
0683:                        isDrawBarOutline(), outlinePaint, outlineStroke, false,
0684:                        new Line2D.Float(), new BasicStroke(1.0f), Color.black);
0685:                result.setDataset(dataset);
0686:                result.setDatasetIndex(datasetIndex);
0687:                result.setSeriesKey(dataset.getRowKey(series));
0688:                result.setSeriesIndex(series);
0689:                if (this .gradientPaintTransformer != null) {
0690:                    result
0691:                            .setFillPaintTransformer(this .gradientPaintTransformer);
0692:                }
0693:                return result;
0694:            }
0695:
0696:            /**
0697:             * Draws the bar for a single (series, category) data item.
0698:             *
0699:             * @param g2  the graphics device.
0700:             * @param state  the renderer state.
0701:             * @param dataArea  the data area.
0702:             * @param plot  the plot.
0703:             * @param domainAxis  the domain axis.
0704:             * @param rangeAxis  the range axis.
0705:             * @param dataset  the dataset.
0706:             * @param row  the row index (zero-based).
0707:             * @param column  the column index (zero-based).
0708:             * @param pass  the pass index.
0709:             */
0710:            public void drawItem(Graphics2D g2,
0711:                    CategoryItemRendererState state, Rectangle2D dataArea,
0712:                    CategoryPlot plot, CategoryAxis domainAxis,
0713:                    ValueAxis rangeAxis, CategoryDataset dataset, int row,
0714:                    int column, int pass) {
0715:
0716:                // nothing is drawn for null values...
0717:                Number dataValue = dataset.getValue(row, column);
0718:                if (dataValue == null) {
0719:                    return;
0720:                }
0721:
0722:                double value = dataValue.doubleValue();
0723:
0724:                PlotOrientation orientation = plot.getOrientation();
0725:                double barW0 = calculateBarW0(plot, orientation, dataArea,
0726:                        domainAxis, state, row, column);
0727:                double[] barL0L1 = calculateBarL0L1(value);
0728:                if (barL0L1 == null) {
0729:                    return; // the bar is not visible
0730:                }
0731:
0732:                RectangleEdge edge = plot.getRangeAxisEdge();
0733:                double transL0 = rangeAxis.valueToJava2D(barL0L1[0], dataArea,
0734:                        edge);
0735:                double transL1 = rangeAxis.valueToJava2D(barL0L1[1], dataArea,
0736:                        edge);
0737:                double barL0 = Math.min(transL0, transL1);
0738:                double barLength = Math.max(Math.abs(transL1 - transL0),
0739:                        getMinimumBarLength());
0740:
0741:                // draw the bar...
0742:                Rectangle2D bar = null;
0743:                if (orientation == PlotOrientation.HORIZONTAL) {
0744:                    bar = new Rectangle2D.Double(barL0, barW0, barLength, state
0745:                            .getBarWidth());
0746:                } else {
0747:                    bar = new Rectangle2D.Double(barW0, barL0, state
0748:                            .getBarWidth(), barLength);
0749:                }
0750:                Paint itemPaint = getItemPaint(row, column);
0751:                GradientPaintTransformer t = getGradientPaintTransformer();
0752:                if (t != null && itemPaint instanceof  GradientPaint) {
0753:                    itemPaint = t.transform((GradientPaint) itemPaint, bar);
0754:                }
0755:                g2.setPaint(itemPaint);
0756:                g2.fill(bar);
0757:
0758:                // draw the outline...
0759:                if (isDrawBarOutline()
0760:                        && state.getBarWidth() > BAR_OUTLINE_WIDTH_THRESHOLD) {
0761:                    Stroke stroke = getItemOutlineStroke(row, column);
0762:                    Paint paint = getItemOutlinePaint(row, column);
0763:                    if (stroke != null && paint != null) {
0764:                        g2.setStroke(stroke);
0765:                        g2.setPaint(paint);
0766:                        g2.draw(bar);
0767:                    }
0768:                }
0769:
0770:                CategoryItemLabelGenerator generator = getItemLabelGenerator(
0771:                        row, column);
0772:                if (generator != null && isItemLabelVisible(row, column)) {
0773:                    drawItemLabel(g2, dataset, row, column, plot, generator,
0774:                            bar, (value < 0.0));
0775:                }
0776:
0777:                // add an item entity, if this information is being collected
0778:                EntityCollection entities = state.getEntityCollection();
0779:                if (entities != null) {
0780:                    addItemEntity(entities, dataset, row, column, bar);
0781:                }
0782:
0783:            }
0784:
0785:            /**
0786:             * Calculates the available space for each series.
0787:             * 
0788:             * @param space  the space along the entire axis (in Java2D units).
0789:             * @param axis  the category axis.
0790:             * @param categories  the number of categories.
0791:             * @param series  the number of series.
0792:             * 
0793:             * @return The width of one series.
0794:             */
0795:            protected double calculateSeriesWidth(double space,
0796:                    CategoryAxis axis, int categories, int series) {
0797:                double factor = 1.0 - getItemMargin() - axis.getLowerMargin()
0798:                        - axis.getUpperMargin();
0799:                if (categories > 1) {
0800:                    factor = factor - axis.getCategoryMargin();
0801:                }
0802:                return (space * factor) / (categories * series);
0803:            }
0804:
0805:            /**
0806:             * Draws an item label.  This method is overridden so that the bar can be 
0807:             * used to calculate the label anchor point.
0808:             * 
0809:             * @param g2  the graphics device.
0810:             * @param data  the dataset.
0811:             * @param row  the row.
0812:             * @param column  the column.
0813:             * @param plot  the plot.
0814:             * @param generator  the label generator.
0815:             * @param bar  the bar.
0816:             * @param negative  a flag indicating a negative value.
0817:             */
0818:            protected void drawItemLabel(Graphics2D g2, CategoryDataset data,
0819:                    int row, int column, CategoryPlot plot,
0820:                    CategoryItemLabelGenerator generator, Rectangle2D bar,
0821:                    boolean negative) {
0822:
0823:                String label = generator.generateLabel(data, row, column);
0824:                if (label == null) {
0825:                    return; // nothing to do   
0826:                }
0827:
0828:                Font labelFont = getItemLabelFont(row, column);
0829:                g2.setFont(labelFont);
0830:                Paint paint = getItemLabelPaint(row, column);
0831:                g2.setPaint(paint);
0832:
0833:                // find out where to place the label...
0834:                ItemLabelPosition position = null;
0835:                if (!negative) {
0836:                    position = getPositiveItemLabelPosition(row, column);
0837:                } else {
0838:                    position = getNegativeItemLabelPosition(row, column);
0839:                }
0840:
0841:                // work out the label anchor point...
0842:                Point2D anchorPoint = calculateLabelAnchorPoint(position
0843:                        .getItemLabelAnchor(), bar, plot.getOrientation());
0844:
0845:                if (isInternalAnchor(position.getItemLabelAnchor())) {
0846:                    Shape bounds = TextUtilities.calculateRotatedStringBounds(
0847:                            label, g2, (float) anchorPoint.getX(),
0848:                            (float) anchorPoint.getY(), position
0849:                                    .getTextAnchor(), position.getAngle(),
0850:                            position.getRotationAnchor());
0851:
0852:                    if (bounds != null) {
0853:                        if (!bar.contains(bounds.getBounds2D())) {
0854:                            if (!negative) {
0855:                                position = getPositiveItemLabelPositionFallback();
0856:                            } else {
0857:                                position = getNegativeItemLabelPositionFallback();
0858:                            }
0859:                            if (position != null) {
0860:                                anchorPoint = calculateLabelAnchorPoint(
0861:                                        position.getItemLabelAnchor(), bar,
0862:                                        plot.getOrientation());
0863:                            }
0864:                        }
0865:                    }
0866:
0867:                }
0868:
0869:                if (position != null) {
0870:                    TextUtilities.drawRotatedString(label, g2,
0871:                            (float) anchorPoint.getX(), (float) anchorPoint
0872:                                    .getY(), position.getTextAnchor(), position
0873:                                    .getAngle(), position.getRotationAnchor());
0874:                }
0875:            }
0876:
0877:            /**
0878:             * Calculates the item label anchor point.
0879:             *
0880:             * @param anchor  the anchor.
0881:             * @param bar  the bar.
0882:             * @param orientation  the plot orientation.
0883:             *
0884:             * @return The anchor point.
0885:             */
0886:            private Point2D calculateLabelAnchorPoint(ItemLabelAnchor anchor,
0887:                    Rectangle2D bar, PlotOrientation orientation) {
0888:
0889:                Point2D result = null;
0890:                double offset = getItemLabelAnchorOffset();
0891:                double x0 = bar.getX() - offset;
0892:                double x1 = bar.getX();
0893:                double x2 = bar.getX() + offset;
0894:                double x3 = bar.getCenterX();
0895:                double x4 = bar.getMaxX() - offset;
0896:                double x5 = bar.getMaxX();
0897:                double x6 = bar.getMaxX() + offset;
0898:
0899:                double y0 = bar.getMaxY() + offset;
0900:                double y1 = bar.getMaxY();
0901:                double y2 = bar.getMaxY() - offset;
0902:                double y3 = bar.getCenterY();
0903:                double y4 = bar.getMinY() + offset;
0904:                double y5 = bar.getMinY();
0905:                double y6 = bar.getMinY() - offset;
0906:
0907:                if (anchor == ItemLabelAnchor.CENTER) {
0908:                    result = new Point2D.Double(x3, y3);
0909:                } else if (anchor == ItemLabelAnchor.INSIDE1) {
0910:                    result = new Point2D.Double(x4, y4);
0911:                } else if (anchor == ItemLabelAnchor.INSIDE2) {
0912:                    result = new Point2D.Double(x4, y4);
0913:                } else if (anchor == ItemLabelAnchor.INSIDE3) {
0914:                    result = new Point2D.Double(x4, y3);
0915:                } else if (anchor == ItemLabelAnchor.INSIDE4) {
0916:                    result = new Point2D.Double(x4, y2);
0917:                } else if (anchor == ItemLabelAnchor.INSIDE5) {
0918:                    result = new Point2D.Double(x4, y2);
0919:                } else if (anchor == ItemLabelAnchor.INSIDE6) {
0920:                    result = new Point2D.Double(x3, y2);
0921:                } else if (anchor == ItemLabelAnchor.INSIDE7) {
0922:                    result = new Point2D.Double(x2, y2);
0923:                } else if (anchor == ItemLabelAnchor.INSIDE8) {
0924:                    result = new Point2D.Double(x2, y2);
0925:                } else if (anchor == ItemLabelAnchor.INSIDE9) {
0926:                    result = new Point2D.Double(x2, y3);
0927:                } else if (anchor == ItemLabelAnchor.INSIDE10) {
0928:                    result = new Point2D.Double(x2, y4);
0929:                } else if (anchor == ItemLabelAnchor.INSIDE11) {
0930:                    result = new Point2D.Double(x2, y4);
0931:                } else if (anchor == ItemLabelAnchor.INSIDE12) {
0932:                    result = new Point2D.Double(x3, y4);
0933:                } else if (anchor == ItemLabelAnchor.OUTSIDE1) {
0934:                    result = new Point2D.Double(x5, y6);
0935:                } else if (anchor == ItemLabelAnchor.OUTSIDE2) {
0936:                    result = new Point2D.Double(x6, y5);
0937:                } else if (anchor == ItemLabelAnchor.OUTSIDE3) {
0938:                    result = new Point2D.Double(x6, y3);
0939:                } else if (anchor == ItemLabelAnchor.OUTSIDE4) {
0940:                    result = new Point2D.Double(x6, y1);
0941:                } else if (anchor == ItemLabelAnchor.OUTSIDE5) {
0942:                    result = new Point2D.Double(x5, y0);
0943:                } else if (anchor == ItemLabelAnchor.OUTSIDE6) {
0944:                    result = new Point2D.Double(x3, y0);
0945:                } else if (anchor == ItemLabelAnchor.OUTSIDE7) {
0946:                    result = new Point2D.Double(x1, y0);
0947:                } else if (anchor == ItemLabelAnchor.OUTSIDE8) {
0948:                    result = new Point2D.Double(x0, y1);
0949:                } else if (anchor == ItemLabelAnchor.OUTSIDE9) {
0950:                    result = new Point2D.Double(x0, y3);
0951:                } else if (anchor == ItemLabelAnchor.OUTSIDE10) {
0952:                    result = new Point2D.Double(x0, y5);
0953:                } else if (anchor == ItemLabelAnchor.OUTSIDE11) {
0954:                    result = new Point2D.Double(x1, y6);
0955:                } else if (anchor == ItemLabelAnchor.OUTSIDE12) {
0956:                    result = new Point2D.Double(x3, y6);
0957:                }
0958:
0959:                return result;
0960:
0961:            }
0962:
0963:            /**
0964:             * Returns <code>true</code> if the specified anchor point is inside a bar.
0965:             * 
0966:             * @param anchor  the anchor point.
0967:             * 
0968:             * @return A boolean.
0969:             */
0970:            private boolean isInternalAnchor(ItemLabelAnchor anchor) {
0971:                return anchor == ItemLabelAnchor.CENTER
0972:                        || anchor == ItemLabelAnchor.INSIDE1
0973:                        || anchor == ItemLabelAnchor.INSIDE2
0974:                        || anchor == ItemLabelAnchor.INSIDE3
0975:                        || anchor == ItemLabelAnchor.INSIDE4
0976:                        || anchor == ItemLabelAnchor.INSIDE5
0977:                        || anchor == ItemLabelAnchor.INSIDE6
0978:                        || anchor == ItemLabelAnchor.INSIDE7
0979:                        || anchor == ItemLabelAnchor.INSIDE8
0980:                        || anchor == ItemLabelAnchor.INSIDE9
0981:                        || anchor == ItemLabelAnchor.INSIDE10
0982:                        || anchor == ItemLabelAnchor.INSIDE11
0983:                        || anchor == ItemLabelAnchor.INSIDE12;
0984:            }
0985:
0986:            /**
0987:             * Tests this instance for equality with an arbitrary object.
0988:             * 
0989:             * @param obj  the object (<code>null</code> permitted).
0990:             * 
0991:             * @return A boolean.
0992:             */
0993:            public boolean equals(Object obj) {
0994:
0995:                if (obj == this ) {
0996:                    return true;
0997:                }
0998:                if (!(obj instanceof  BarRenderer)) {
0999:                    return false;
1000:                }
1001:                if (!super .equals(obj)) {
1002:                    return false;
1003:                }
1004:                BarRenderer that = (BarRenderer) obj;
1005:                if (this .base != that.base) {
1006:                    return false;
1007:                }
1008:                if (this .itemMargin != that.itemMargin) {
1009:                    return false;
1010:                }
1011:                if (this .drawBarOutline != that.drawBarOutline) {
1012:                    return false;
1013:                }
1014:                if (this .maximumBarWidth != that.maximumBarWidth) {
1015:                    return false;
1016:                }
1017:                if (this .minimumBarLength != that.minimumBarLength) {
1018:                    return false;
1019:                }
1020:                if (!ObjectUtilities.equal(this .gradientPaintTransformer,
1021:                        that.gradientPaintTransformer)) {
1022:                    return false;
1023:                }
1024:                if (!ObjectUtilities.equal(
1025:                        this .positiveItemLabelPositionFallback,
1026:                        that.positiveItemLabelPositionFallback)) {
1027:                    return false;
1028:                }
1029:                if (!ObjectUtilities.equal(
1030:                        this .negativeItemLabelPositionFallback,
1031:                        that.negativeItemLabelPositionFallback)) {
1032:                    return false;
1033:                }
1034:                return true;
1035:
1036:            }
1037:
1038:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.