Source Code Cross Referenced for PiePlot3D.java in  » Chart » jfreechart » org » jfree » chart » plot » 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.plot 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /* ===========================================================
002:         * JFreeChart : a free chart library for the Java(tm) platform
003:         * ===========================================================
004:         *
005:         * (C) Copyright 2000-2007, by Object Refinery Limited and Contributors.
006:         *
007:         * Project Info:  http://www.jfree.org/jfreechart/index.html
008:         *
009:         * This library is free software; you can redistribute it and/or modify it 
010:         * under the terms of the GNU Lesser General Public License as published by 
011:         * the Free Software Foundation; either version 2.1 of the License, or 
012:         * (at your option) any later version.
013:         *
014:         * This library is distributed in the hope that it will be useful, but 
015:         * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
016:         * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
017:         * License for more details.
018:         *
019:         * You should have received a copy of the GNU Lesser General Public
020:         * License along with this library; if not, write to the Free Software
021:         * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
022:         * USA.  
023:         *
024:         * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 
025:         * in the United States and other countries.]
026:         *
027:         * --------------
028:         * PiePlot3D.java
029:         * --------------
030:         * (C) Copyright 2000-2007, by Object Refinery and Contributors.
031:         *
032:         * Original Author:  Tomer Peretz;
033:         * Contributor(s):   Richard Atkinson;
034:         *                   David Gilbert (for Object Refinery Limited);
035:         *                   Xun Kang;
036:         *                   Christian W. Zuckschwerdt;
037:         *                   Arnaud Lelievre;
038:         *                   Dave Crane;
039:         *
040:         * $Id: PiePlot3D.java,v 1.10.2.6 2007/03/22 14:08:24 mungady Exp $
041:         *
042:         * Changes
043:         * -------
044:         * 21-Jun-2002 : Version 1;
045:         * 31-Jul-2002 : Modified to use startAngle and direction, drawing modified so 
046:         *               that charts render with foreground alpha < 1.0 (DG);
047:         * 05-Aug-2002 : Small modification to draw method to support URLs for HTML 
048:         *               image maps (RA);
049:         * 26-Sep-2002 : Fixed errors reported by Checkstyle (DG);
050:         * 18-Oct-2002 : Added drawing bug fix sent in by Xun Kang, and made a couple 
051:         *               of other related fixes (DG);
052:         * 30-Oct-2002 : Changed the PieDataset interface. Fixed another drawing 
053:         *               bug (DG);
054:         * 12-Nov-2002 : Fixed null pointer exception for zero or negative values (DG);
055:         * 07-Mar-2003 : Modified to pass pieIndex on to PieSectionEntity (DG);
056:         * 21-Mar-2003 : Added workaround for bug id 620031 (DG);
057:         * 26-Mar-2003 : Implemented Serializable (DG);
058:         * 30-Jul-2003 : Modified entity constructor (CZ);
059:         * 29-Aug-2003 : Small changes for API updates in PiePlot class (DG);
060:         * 02-Sep-2003 : Fixed bug where the 'no data' message is not displayed (DG);
061:         * 08-Sep-2003 : Added internationalization via use of properties 
062:         *               resourceBundle (RFE 690236) (AL); 
063:         * 29-Oct-2003 : Added workaround for font alignment in PDF output (DG);
064:         * 20-Nov-2003 : Fixed bug 845289 (sides not showing) (DG);
065:         * 25-Nov-2003 : Added patch (845095) to fix outline paint issues (DG);
066:         * 10-Mar-2004 : Numerous changes to enhance labelling (DG);
067:         * 31-Mar-2004 : Adjusted plot area when label generator is null (DG);
068:         * 08-Apr-2004 : Added flag to PiePlot class to control the treatment of null 
069:         *               values (DG);
070:         *               Added pieIndex to PieSectionEntity (DG);
071:         * 15-Nov-2004 : Removed creation of default tool tip generator (DG);
072:         * 16-Jun-2005 : Added default constructor (DG);
073:         * ------------- JFREECHART 1.0.x ---------------------------------------------
074:         * 27-Sep-2006 : Updated draw() method for new lookup methods (DG);
075:         * 22-Mar-2007 : Added equals() override (DG);
076:         * 
077:         */
078:
079:        package org.jfree.chart.plot;
080:
081:        import java.awt.AlphaComposite;
082:        import java.awt.Color;
083:        import java.awt.Composite;
084:        import java.awt.Font;
085:        import java.awt.FontMetrics;
086:        import java.awt.Graphics2D;
087:        import java.awt.Paint;
088:        import java.awt.Polygon;
089:        import java.awt.Shape;
090:        import java.awt.Stroke;
091:        import java.awt.geom.Arc2D;
092:        import java.awt.geom.Area;
093:        import java.awt.geom.Ellipse2D;
094:        import java.awt.geom.Point2D;
095:        import java.awt.geom.Rectangle2D;
096:        import java.io.Serializable;
097:        import java.util.ArrayList;
098:        import java.util.Iterator;
099:        import java.util.List;
100:
101:        import org.jfree.chart.entity.EntityCollection;
102:        import org.jfree.chart.entity.PieSectionEntity;
103:        import org.jfree.chart.event.PlotChangeEvent;
104:        import org.jfree.chart.labels.PieToolTipGenerator;
105:        import org.jfree.data.general.DatasetUtilities;
106:        import org.jfree.data.general.PieDataset;
107:        import org.jfree.ui.RectangleInsets;
108:
109:        /**
110:         * A plot that displays data in the form of a 3D pie chart, using data from
111:         * any class that implements the {@link PieDataset} interface.
112:         * <P>
113:         * Although this class extends {@link PiePlot}, it does not currently support
114:         * exploded sections.
115:         */
116:        public class PiePlot3D extends PiePlot implements  Serializable {
117:
118:            /** For serialization. */
119:            private static final long serialVersionUID = 3408984188945161432L;
120:
121:            /** The factor of the depth of the pie from the plot height */
122:            private double depthFactor = 0.2;
123:
124:            /**
125:             * Creates a new instance with no dataset.
126:             */
127:            public PiePlot3D() {
128:                this (null);
129:            }
130:
131:            /**
132:             * Creates a pie chart with a three dimensional effect using the specified 
133:             * dataset.
134:             *
135:             * @param dataset  the dataset (<code>null</code> permitted).
136:             */
137:            public PiePlot3D(PieDataset dataset) {
138:                super (dataset);
139:                setCircular(false, false);
140:            }
141:
142:            /**
143:             * Returns the depth factor for the chart.
144:             *
145:             * @return The depth factor.
146:             * 
147:             * @see #setDepthFactor(double)
148:             */
149:            public double getDepthFactor() {
150:                return this .depthFactor;
151:            }
152:
153:            /**
154:             * Sets the pie depth as a percentage of the height of the plot area, and
155:             * sends a {@link PlotChangeEvent} to all registered listeners.
156:             *
157:             * @param factor  the depth factor (for example, 0.20 is twenty percent).
158:             * 
159:             * @see #getDepthFactor()
160:             */
161:            public void setDepthFactor(double factor) {
162:                this .depthFactor = factor;
163:                notifyListeners(new PlotChangeEvent(this ));
164:            }
165:
166:            /**
167:             * Draws the plot on a Java 2D graphics device (such as the screen or a 
168:             * printer).  This method is called by the 
169:             * {@link org.jfree.chart.JFreeChart} class, you don't normally need 
170:             * to call it yourself.
171:             *
172:             * @param g2  the graphics device.
173:             * @param plotArea  the area within which the plot should be drawn.
174:             * @param anchor  the anchor point.
175:             * @param parentState  the state from the parent plot, if there is one.
176:             * @param info  collects info about the drawing 
177:             *              (<code>null</code> permitted).
178:             */
179:            public void draw(Graphics2D g2, Rectangle2D plotArea,
180:                    Point2D anchor, PlotState parentState,
181:                    PlotRenderingInfo info) {
182:
183:                // adjust for insets...
184:                RectangleInsets insets = getInsets();
185:                insets.trim(plotArea);
186:
187:                Rectangle2D originalPlotArea = (Rectangle2D) plotArea.clone();
188:                if (info != null) {
189:                    info.setPlotArea(plotArea);
190:                    info.setDataArea(plotArea);
191:                }
192:
193:                Shape savedClip = g2.getClip();
194:                g2.clip(plotArea);
195:
196:                // adjust the plot area by the interior spacing value
197:                double gapPercent = getInteriorGap();
198:                double labelPercent = 0.0;
199:                if (getLabelGenerator() != null) {
200:                    labelPercent = getLabelGap() + getMaximumLabelWidth()
201:                            + getLabelLinkMargin();
202:                }
203:                double gapHorizontal = plotArea.getWidth()
204:                        * (gapPercent + labelPercent);
205:                double gapVertical = plotArea.getHeight() * gapPercent;
206:
207:                double linkX = plotArea.getX() + gapHorizontal / 2;
208:                double linkY = plotArea.getY() + gapVertical / 2;
209:                double linkW = plotArea.getWidth() - gapHorizontal;
210:                double linkH = plotArea.getHeight() - gapVertical;
211:
212:                // make the link area a square if the pie chart is to be circular...
213:                if (isCircular()) { // is circular?
214:                    double min = Math.min(linkW, linkH) / 2;
215:                    linkX = (linkX + linkX + linkW) / 2 - min;
216:                    linkY = (linkY + linkY + linkH) / 2 - min;
217:                    linkW = 2 * min;
218:                    linkH = 2 * min;
219:                }
220:
221:                PiePlotState state = initialise(g2, plotArea, this , null, info);
222:                // the explode area defines the max circle/ellipse for the exploded pie 
223:                // sections.
224:                // it is defined by shrinking the linkArea by the linkMargin factor.
225:                double hh = linkW * getLabelLinkMargin();
226:                double vv = linkH * getLabelLinkMargin();
227:                Rectangle2D explodeArea = new Rectangle2D.Double(linkX + hh
228:                        / 2.0, linkY + vv / 2.0, linkW - hh, linkH - vv);
229:
230:                state.setExplodedPieArea(explodeArea);
231:
232:                // the pie area defines the circle/ellipse for regular pie sections.
233:                // it is defined by shrinking the explodeArea by the explodeMargin 
234:                // factor. 
235:                double maximumExplodePercent = getMaximumExplodePercent();
236:                double percent = maximumExplodePercent
237:                        / (1.0 + maximumExplodePercent);
238:
239:                double h1 = explodeArea.getWidth() * percent;
240:                double v1 = explodeArea.getHeight() * percent;
241:                Rectangle2D pieArea = new Rectangle2D.Double(explodeArea.getX()
242:                        + h1 / 2.0, explodeArea.getY() + v1 / 2.0, explodeArea
243:                        .getWidth()
244:                        - h1, explodeArea.getHeight() - v1);
245:
246:                int depth = (int) (pieArea.getHeight() * this .depthFactor);
247:                // the link area defines the dog-leg point for the linking lines to 
248:                // the labels
249:                Rectangle2D linkArea = new Rectangle2D.Double(linkX, linkY,
250:                        linkW, linkH - depth);
251:                state.setLinkArea(linkArea);
252:
253:                state.setPieArea(pieArea);
254:                state.setPieCenterX(pieArea.getCenterX());
255:                state.setPieCenterY(pieArea.getCenterY() - depth / 2.0);
256:                state.setPieWRadius(pieArea.getWidth() / 2.0);
257:                state.setPieHRadius((pieArea.getHeight() - depth) / 2.0);
258:
259:                drawBackground(g2, plotArea);
260:                // get the data source - return if null;
261:                PieDataset dataset = getDataset();
262:                if (DatasetUtilities.isEmptyOrNull(getDataset())) {
263:                    drawNoDataMessage(g2, plotArea);
264:                    g2.setClip(savedClip);
265:                    drawOutline(g2, plotArea);
266:                    return;
267:                }
268:
269:                // if too any elements
270:                if (dataset.getKeys().size() > plotArea.getWidth()) {
271:                    String text = "Too many elements";
272:                    Font sfont = new Font("dialog", Font.BOLD, 10);
273:                    g2.setFont(sfont);
274:                    FontMetrics fm = g2.getFontMetrics(sfont);
275:                    int stringWidth = fm.stringWidth(text);
276:
277:                    g2.drawString(text, (int) (plotArea.getX() + (plotArea
278:                            .getWidth() - stringWidth) / 2), (int) (plotArea
279:                            .getY() + (plotArea.getHeight() / 2)));
280:                    return;
281:                }
282:                // if we are drawing a perfect circle, we need to readjust the top left
283:                // coordinates of the drawing area for the arcs to arrive at this
284:                // effect.
285:                if (isCircular()) {
286:                    double min = Math.min(plotArea.getWidth(), plotArea
287:                            .getHeight()) / 2;
288:                    plotArea = new Rectangle2D.Double(plotArea.getCenterX()
289:                            - min, plotArea.getCenterY() - min, 2 * min,
290:                            2 * min);
291:                }
292:                // get a list of keys...
293:                List sectionKeys = dataset.getKeys();
294:
295:                if (sectionKeys.size() == 0) {
296:                    return;
297:                }
298:
299:                // establish the coordinates of the top left corner of the drawing area
300:                double arcX = pieArea.getX();
301:                double arcY = pieArea.getY();
302:
303:                //g2.clip(clipArea);
304:                Composite originalComposite = g2.getComposite();
305:                g2.setComposite(AlphaComposite.getInstance(
306:                        AlphaComposite.SRC_OVER, getForegroundAlpha()));
307:
308:                double totalValue = DatasetUtilities
309:                        .calculatePieDatasetTotal(dataset);
310:                double runningTotal = 0;
311:                if (depth < 0) {
312:                    return; // if depth is negative don't draw anything
313:                }
314:
315:                ArrayList arcList = new ArrayList();
316:                Arc2D.Double arc;
317:                Paint paint;
318:                Paint outlinePaint;
319:                Stroke outlineStroke;
320:
321:                Iterator iterator = sectionKeys.iterator();
322:                while (iterator.hasNext()) {
323:
324:                    Comparable currentKey = (Comparable) iterator.next();
325:                    Number dataValue = dataset.getValue(currentKey);
326:                    if (dataValue == null) {
327:                        arcList.add(null);
328:                        continue;
329:                    }
330:                    double value = dataValue.doubleValue();
331:                    if (value <= 0) {
332:                        arcList.add(null);
333:                        continue;
334:                    }
335:                    double startAngle = getStartAngle();
336:                    double direction = getDirection().getFactor();
337:                    double angle1 = startAngle
338:                            + (direction * (runningTotal * 360)) / totalValue;
339:                    double angle2 = startAngle
340:                            + (direction * (runningTotal + value) * 360)
341:                            / totalValue;
342:                    if (Math.abs(angle2 - angle1) > getMinimumArcAngleToDraw()) {
343:                        arcList.add(new Arc2D.Double(arcX, arcY + depth,
344:                                pieArea.getWidth(),
345:                                pieArea.getHeight() - depth, angle1, angle2
346:                                        - angle1, Arc2D.PIE));
347:                    } else {
348:                        arcList.add(null);
349:                    }
350:                    runningTotal += value;
351:                }
352:
353:                Shape oldClip = g2.getClip();
354:
355:                Ellipse2D top = new Ellipse2D.Double(pieArea.getX(), pieArea
356:                        .getY(), pieArea.getWidth(), pieArea.getHeight()
357:                        - depth);
358:
359:                Ellipse2D bottom = new Ellipse2D.Double(pieArea.getX(), pieArea
360:                        .getY()
361:                        + depth, pieArea.getWidth(), pieArea.getHeight()
362:                        - depth);
363:
364:                Rectangle2D lower = new Rectangle2D.Double(top.getX(), top
365:                        .getCenterY(), pieArea.getWidth(), bottom.getMaxY()
366:                        - top.getCenterY());
367:
368:                Rectangle2D upper = new Rectangle2D.Double(pieArea.getX(), top
369:                        .getY(), pieArea.getWidth(), bottom.getCenterY()
370:                        - top.getY());
371:
372:                Area a = new Area(top);
373:                a.add(new Area(lower));
374:                Area b = new Area(bottom);
375:                b.add(new Area(upper));
376:                Area pie = new Area(a);
377:                pie.intersect(b);
378:
379:                Area front = new Area(pie);
380:                front.subtract(new Area(top));
381:
382:                Area back = new Area(pie);
383:                back.subtract(new Area(bottom));
384:
385:                // draw the bottom circle
386:                int[] xs;
387:                int[] ys;
388:                arc = new Arc2D.Double(arcX, arcY + depth, pieArea.getWidth(),
389:                        pieArea.getHeight() - depth, 0, 360, Arc2D.PIE);
390:
391:                int categoryCount = arcList.size();
392:                for (int categoryIndex = 0; categoryIndex < categoryCount; categoryIndex++) {
393:                    arc = (Arc2D.Double) arcList.get(categoryIndex);
394:                    if (arc == null) {
395:                        continue;
396:                    }
397:                    Comparable key = getSectionKey(categoryIndex);
398:                    paint = lookupSectionPaint(key, true);
399:                    outlinePaint = lookupSectionOutlinePaint(key);
400:                    outlineStroke = lookupSectionOutlineStroke(key);
401:                    g2.setPaint(paint);
402:                    g2.fill(arc);
403:                    g2.setPaint(outlinePaint);
404:                    g2.setStroke(outlineStroke);
405:                    g2.draw(arc);
406:                    g2.setPaint(paint);
407:
408:                    Point2D p1 = arc.getStartPoint();
409:
410:                    // draw the height
411:                    xs = new int[] { (int) arc.getCenterX(),
412:                            (int) arc.getCenterX(), (int) p1.getX(),
413:                            (int) p1.getX() };
414:                    ys = new int[] { (int) arc.getCenterY(),
415:                            (int) arc.getCenterY() - depth,
416:                            (int) p1.getY() - depth, (int) p1.getY() };
417:                    Polygon polygon = new Polygon(xs, ys, 4);
418:                    g2.setPaint(java.awt.Color.lightGray);
419:                    g2.fill(polygon);
420:                    g2.setPaint(outlinePaint);
421:                    g2.setStroke(outlineStroke);
422:                    g2.draw(polygon);
423:                    g2.setPaint(paint);
424:
425:                }
426:
427:                g2.setPaint(Color.gray);
428:                g2.fill(back);
429:                g2.fill(front);
430:
431:                // cycle through once drawing only the sides at the back...
432:                int cat = 0;
433:                iterator = arcList.iterator();
434:                while (iterator.hasNext()) {
435:                    Arc2D segment = (Arc2D) iterator.next();
436:                    if (segment != null) {
437:                        Comparable key = getSectionKey(cat);
438:                        paint = lookupSectionPaint(key, true);
439:                        outlinePaint = lookupSectionOutlinePaint(key);
440:                        outlineStroke = lookupSectionOutlineStroke(key);
441:                        drawSide(g2, pieArea, segment, front, back, paint,
442:                                outlinePaint, outlineStroke, false, true);
443:                    }
444:                    cat++;
445:                }
446:
447:                // cycle through again drawing only the sides at the front...
448:                cat = 0;
449:                iterator = arcList.iterator();
450:                while (iterator.hasNext()) {
451:                    Arc2D segment = (Arc2D) iterator.next();
452:                    if (segment != null) {
453:                        Comparable key = getSectionKey(cat);
454:                        paint = lookupSectionPaint(key);
455:                        outlinePaint = lookupSectionOutlinePaint(key);
456:                        outlineStroke = lookupSectionOutlineStroke(key);
457:                        drawSide(g2, pieArea, segment, front, back, paint,
458:                                outlinePaint, outlineStroke, true, false);
459:                    }
460:                    cat++;
461:                }
462:
463:                g2.setClip(oldClip);
464:
465:                // draw the sections at the top of the pie (and set up tooltips)...
466:                Arc2D upperArc;
467:                for (int sectionIndex = 0; sectionIndex < categoryCount; sectionIndex++) {
468:                    arc = (Arc2D.Double) arcList.get(sectionIndex);
469:                    if (arc == null) {
470:                        continue;
471:                    }
472:                    upperArc = new Arc2D.Double(arcX, arcY, pieArea.getWidth(),
473:                            pieArea.getHeight() - depth, arc.getAngleStart(),
474:                            arc.getAngleExtent(), Arc2D.PIE);
475:
476:                    Comparable currentKey = (Comparable) sectionKeys
477:                            .get(sectionIndex);
478:                    paint = lookupSectionPaint(currentKey, true);
479:                    outlinePaint = lookupSectionOutlinePaint(currentKey);
480:                    outlineStroke = lookupSectionOutlineStroke(currentKey);
481:                    g2.setPaint(paint);
482:                    g2.fill(upperArc);
483:                    g2.setStroke(outlineStroke);
484:                    g2.setPaint(outlinePaint);
485:                    g2.draw(upperArc);
486:
487:                    // add a tooltip for the section...
488:                    if (info != null) {
489:                        EntityCollection entities = info.getOwner()
490:                                .getEntityCollection();
491:                        if (entities != null) {
492:                            String tip = null;
493:                            PieToolTipGenerator tipster = getToolTipGenerator();
494:                            if (tipster != null) {
495:                                // @mgs: using the method's return value was missing 
496:                                tip = tipster.generateToolTip(dataset,
497:                                        currentKey);
498:                            }
499:                            String url = null;
500:                            if (getURLGenerator() != null) {
501:                                url = getURLGenerator().generateURL(dataset,
502:                                        currentKey, getPieIndex());
503:                            }
504:                            PieSectionEntity entity = new PieSectionEntity(
505:                                    upperArc, dataset, getPieIndex(),
506:                                    sectionIndex, currentKey, tip, url);
507:                            entities.add(entity);
508:                        }
509:                    }
510:                    List keys = dataset.getKeys();
511:                    Rectangle2D adjustedPlotArea = new Rectangle2D.Double(
512:                            originalPlotArea.getX(), originalPlotArea.getY(),
513:                            originalPlotArea.getWidth(), originalPlotArea
514:                                    .getHeight()
515:                                    - depth);
516:                    drawLabels(g2, keys, totalValue, adjustedPlotArea,
517:                            linkArea, state);
518:                }
519:
520:                g2.setClip(savedClip);
521:                g2.setComposite(originalComposite);
522:                drawOutline(g2, originalPlotArea);
523:
524:            }
525:
526:            /**
527:             * Draws the side of a pie section.
528:             *
529:             * @param g2  the graphics device.
530:             * @param plotArea  the plot area.
531:             * @param arc  the arc.
532:             * @param front  the front of the pie.
533:             * @param back  the back of the pie.
534:             * @param paint  the color.
535:             * @param outlinePaint  the outline paint.
536:             * @param outlineStroke  the outline stroke.
537:             * @param drawFront  draw the front?
538:             * @param drawBack  draw the back?
539:             */
540:            protected void drawSide(Graphics2D g2, Rectangle2D plotArea,
541:                    Arc2D arc, Area front, Area back, Paint paint,
542:                    Paint outlinePaint, Stroke outlineStroke,
543:                    boolean drawFront, boolean drawBack) {
544:
545:                double start = arc.getAngleStart();
546:                double extent = arc.getAngleExtent();
547:                double end = start + extent;
548:
549:                g2.setStroke(outlineStroke);
550:
551:                // for CLOCKWISE charts, the extent will be negative...
552:                if (extent < 0.0) {
553:
554:                    if (isAngleAtFront(start)) { // start at front
555:
556:                        if (!isAngleAtBack(end)) {
557:
558:                            if (extent > -180.0) { // the segment is entirely at the 
559:                                // front of the chart
560:                                if (drawFront) {
561:                                    Area side = new Area(
562:                                            new Rectangle2D.Double(arc
563:                                                    .getEndPoint().getX(),
564:                                                    plotArea.getY(), arc
565:                                                            .getStartPoint()
566:                                                            .getX()
567:                                                            - arc.getEndPoint()
568:                                                                    .getX(),
569:                                                    plotArea.getHeight()));
570:                                    side.intersect(front);
571:                                    g2.setPaint(paint);
572:                                    g2.fill(side);
573:                                    g2.setPaint(outlinePaint);
574:                                    g2.draw(side);
575:                                }
576:                            } else { // the segment starts at the front, and wraps all 
577:                                // the way around
578:                                // the back and finishes at the front again
579:                                Area side1 = new Area(new Rectangle2D.Double(
580:                                        plotArea.getX(), plotArea.getY(), arc
581:                                                .getStartPoint().getX()
582:                                                - plotArea.getX(), plotArea
583:                                                .getHeight()));
584:                                side1.intersect(front);
585:
586:                                Area side2 = new Area(new Rectangle2D.Double(
587:                                        arc.getEndPoint().getX(), plotArea
588:                                                .getY(), plotArea.getMaxX()
589:                                                - arc.getEndPoint().getX(),
590:                                        plotArea.getHeight()));
591:
592:                                side2.intersect(front);
593:                                g2.setPaint(paint);
594:                                if (drawFront) {
595:                                    g2.fill(side1);
596:                                    g2.fill(side2);
597:                                }
598:
599:                                if (drawBack) {
600:                                    g2.fill(back);
601:                                }
602:
603:                                g2.setPaint(outlinePaint);
604:                                if (drawFront) {
605:                                    g2.draw(side1);
606:                                    g2.draw(side2);
607:                                }
608:
609:                                if (drawBack) {
610:                                    g2.draw(back);
611:                                }
612:
613:                            }
614:                        } else { // starts at the front, finishes at the back (going 
615:                            // around the left side)
616:
617:                            if (drawBack) {
618:                                Area side2 = new Area(new Rectangle2D.Double(
619:                                        plotArea.getX(), plotArea.getY(), arc
620:                                                .getEndPoint().getX()
621:                                                - plotArea.getX(), plotArea
622:                                                .getHeight()));
623:                                side2.intersect(back);
624:                                g2.setPaint(paint);
625:                                g2.fill(side2);
626:                                g2.setPaint(outlinePaint);
627:                                g2.draw(side2);
628:                            }
629:
630:                            if (drawFront) {
631:                                Area side1 = new Area(new Rectangle2D.Double(
632:                                        plotArea.getX(), plotArea.getY(), arc
633:                                                .getStartPoint().getX()
634:                                                - plotArea.getX(), plotArea
635:                                                .getHeight()));
636:                                side1.intersect(front);
637:                                g2.setPaint(paint);
638:                                g2.fill(side1);
639:                                g2.setPaint(outlinePaint);
640:                                g2.draw(side1);
641:                            }
642:                        }
643:                    } else { // the segment starts at the back (still extending 
644:                        // CLOCKWISE)
645:
646:                        if (!isAngleAtFront(end)) {
647:                            if (extent > -180.0) { // whole segment stays at the back
648:                                if (drawBack) {
649:                                    Area side = new Area(
650:                                            new Rectangle2D.Double(
651:                                                    arc.getStartPoint().getX(),
652:                                                    plotArea.getY(),
653:                                                    arc.getEndPoint().getX()
654:                                                            - arc
655:                                                                    .getStartPoint()
656:                                                                    .getX(),
657:                                                    plotArea.getHeight()));
658:                                    side.intersect(back);
659:                                    g2.setPaint(paint);
660:                                    g2.fill(side);
661:                                    g2.setPaint(outlinePaint);
662:                                    g2.draw(side);
663:                                }
664:                            } else { // starts at the back, wraps around front, and 
665:                                // finishes at back again
666:                                Area side1 = new Area(new Rectangle2D.Double(
667:                                        arc.getStartPoint().getX(), plotArea
668:                                                .getY(), plotArea.getMaxX()
669:                                                - arc.getStartPoint().getX(),
670:                                        plotArea.getHeight()));
671:                                side1.intersect(back);
672:
673:                                Area side2 = new Area(new Rectangle2D.Double(
674:                                        plotArea.getX(), plotArea.getY(), arc
675:                                                .getEndPoint().getX()
676:                                                - plotArea.getX(), plotArea
677:                                                .getHeight()));
678:
679:                                side2.intersect(back);
680:
681:                                g2.setPaint(paint);
682:                                if (drawBack) {
683:                                    g2.fill(side1);
684:                                    g2.fill(side2);
685:                                }
686:
687:                                if (drawFront) {
688:                                    g2.fill(front);
689:                                }
690:
691:                                g2.setPaint(outlinePaint);
692:                                if (drawBack) {
693:                                    g2.draw(side1);
694:                                    g2.draw(side2);
695:                                }
696:
697:                                if (drawFront) {
698:                                    g2.draw(front);
699:                                }
700:
701:                            }
702:                        } else { // starts at back, finishes at front (CLOCKWISE)
703:
704:                            if (drawBack) {
705:                                Area side1 = new Area(new Rectangle2D.Double(
706:                                        arc.getStartPoint().getX(), plotArea
707:                                                .getY(), plotArea.getMaxX()
708:                                                - arc.getStartPoint().getX(),
709:                                        plotArea.getHeight()));
710:                                side1.intersect(back);
711:                                g2.setPaint(paint);
712:                                g2.fill(side1);
713:                                g2.setPaint(outlinePaint);
714:                                g2.draw(side1);
715:                            }
716:
717:                            if (drawFront) {
718:                                Area side2 = new Area(new Rectangle2D.Double(
719:                                        arc.getEndPoint().getX(), plotArea
720:                                                .getY(), plotArea.getMaxX()
721:                                                - arc.getEndPoint().getX(),
722:                                        plotArea.getHeight()));
723:                                side2.intersect(front);
724:                                g2.setPaint(paint);
725:                                g2.fill(side2);
726:                                g2.setPaint(outlinePaint);
727:                                g2.draw(side2);
728:                            }
729:
730:                        }
731:                    }
732:                } else if (extent > 0.0) { // the pie sections are arranged ANTICLOCKWISE
733:
734:                    if (isAngleAtFront(start)) { // segment starts at the front
735:
736:                        if (!isAngleAtBack(end)) { // and finishes at the front
737:
738:                            if (extent < 180.0) { // segment only occupies the front
739:                                if (drawFront) {
740:                                    Area side = new Area(
741:                                            new Rectangle2D.Double(
742:                                                    arc.getStartPoint().getX(),
743:                                                    plotArea.getY(),
744:                                                    arc.getEndPoint().getX()
745:                                                            - arc
746:                                                                    .getStartPoint()
747:                                                                    .getX(),
748:                                                    plotArea.getHeight()));
749:                                    side.intersect(front);
750:                                    g2.setPaint(paint);
751:                                    g2.fill(side);
752:                                    g2.setPaint(outlinePaint);
753:                                    g2.draw(side);
754:                                }
755:                            } else { // segments wraps right around the back...
756:                                Area side1 = new Area(new Rectangle2D.Double(
757:                                        arc.getStartPoint().getX(), plotArea
758:                                                .getY(), plotArea.getMaxX()
759:                                                - arc.getStartPoint().getX(),
760:                                        plotArea.getHeight()));
761:                                side1.intersect(front);
762:
763:                                Area side2 = new Area(new Rectangle2D.Double(
764:                                        plotArea.getX(), plotArea.getY(), arc
765:                                                .getEndPoint().getX()
766:                                                - plotArea.getX(), plotArea
767:                                                .getHeight()));
768:                                side2.intersect(front);
769:
770:                                g2.setPaint(paint);
771:                                if (drawFront) {
772:                                    g2.fill(side1);
773:                                    g2.fill(side2);
774:                                }
775:
776:                                if (drawBack) {
777:                                    g2.fill(back);
778:                                }
779:
780:                                g2.setPaint(outlinePaint);
781:                                if (drawFront) {
782:                                    g2.draw(side1);
783:                                    g2.draw(side2);
784:                                }
785:
786:                                if (drawBack) {
787:                                    g2.draw(back);
788:                                }
789:
790:                            }
791:                        } else { // segments starts at front and finishes at back...
792:                            if (drawBack) {
793:                                Area side2 = new Area(new Rectangle2D.Double(
794:                                        arc.getEndPoint().getX(), plotArea
795:                                                .getY(), plotArea.getMaxX()
796:                                                - arc.getEndPoint().getX(),
797:                                        plotArea.getHeight()));
798:                                side2.intersect(back);
799:                                g2.setPaint(paint);
800:                                g2.fill(side2);
801:                                g2.setPaint(outlinePaint);
802:                                g2.draw(side2);
803:                            }
804:
805:                            if (drawFront) {
806:                                Area side1 = new Area(new Rectangle2D.Double(
807:                                        arc.getStartPoint().getX(), plotArea
808:                                                .getY(), plotArea.getMaxX()
809:                                                - arc.getStartPoint().getX(),
810:                                        plotArea.getHeight()));
811:                                side1.intersect(front);
812:                                g2.setPaint(paint);
813:                                g2.fill(side1);
814:                                g2.setPaint(outlinePaint);
815:                                g2.draw(side1);
816:                            }
817:                        }
818:                    } else { // segment starts at back
819:
820:                        if (!isAngleAtFront(end)) {
821:                            if (extent < 180.0) { // and finishes at back
822:                                if (drawBack) {
823:                                    Area side = new Area(
824:                                            new Rectangle2D.Double(arc
825:                                                    .getEndPoint().getX(),
826:                                                    plotArea.getY(), arc
827:                                                            .getStartPoint()
828:                                                            .getX()
829:                                                            - arc.getEndPoint()
830:                                                                    .getX(),
831:                                                    plotArea.getHeight()));
832:                                    side.intersect(back);
833:                                    g2.setPaint(paint);
834:                                    g2.fill(side);
835:                                    g2.setPaint(outlinePaint);
836:                                    g2.draw(side);
837:                                }
838:                            } else { // starts at back and wraps right around to the 
839:                                // back again
840:                                Area side1 = new Area(new Rectangle2D.Double(
841:                                        arc.getStartPoint().getX(), plotArea
842:                                                .getY(), plotArea.getX()
843:                                                - arc.getStartPoint().getX(),
844:                                        plotArea.getHeight()));
845:                                side1.intersect(back);
846:
847:                                Area side2 = new Area(new Rectangle2D.Double(
848:                                        arc.getEndPoint().getX(), plotArea
849:                                                .getY(), plotArea.getMaxX()
850:                                                - arc.getEndPoint().getX(),
851:                                        plotArea.getHeight()));
852:                                side2.intersect(back);
853:
854:                                g2.setPaint(paint);
855:                                if (drawBack) {
856:                                    g2.fill(side1);
857:                                    g2.fill(side2);
858:                                }
859:
860:                                if (drawFront) {
861:                                    g2.fill(front);
862:                                }
863:
864:                                g2.setPaint(outlinePaint);
865:                                if (drawBack) {
866:                                    g2.draw(side1);
867:                                    g2.draw(side2);
868:                                }
869:
870:                                if (drawFront) {
871:                                    g2.draw(front);
872:                                }
873:
874:                            }
875:                        } else { // starts at the back and finishes at the front 
876:                            // (wrapping the left side)
877:                            if (drawBack) {
878:                                Area side1 = new Area(new Rectangle2D.Double(
879:                                        plotArea.getX(), plotArea.getY(), arc
880:                                                .getStartPoint().getX()
881:                                                - plotArea.getX(), plotArea
882:                                                .getHeight()));
883:                                side1.intersect(back);
884:                                g2.setPaint(paint);
885:                                g2.fill(side1);
886:                                g2.setPaint(outlinePaint);
887:                                g2.draw(side1);
888:                            }
889:
890:                            if (drawFront) {
891:                                Area side2 = new Area(new Rectangle2D.Double(
892:                                        plotArea.getX(), plotArea.getY(), arc
893:                                                .getEndPoint().getX()
894:                                                - plotArea.getX(), plotArea
895:                                                .getHeight()));
896:                                side2.intersect(front);
897:                                g2.setPaint(paint);
898:                                g2.fill(side2);
899:                                g2.setPaint(outlinePaint);
900:                                g2.draw(side2);
901:                            }
902:                        }
903:                    }
904:
905:                }
906:
907:            }
908:
909:            /**
910:             * Returns a short string describing the type of plot.
911:             *
912:             * @return <i>Pie 3D Plot</i>.
913:             */
914:            public String getPlotType() {
915:                return localizationResources.getString("Pie_3D_Plot");
916:            }
917:
918:            /**
919:             * A utility method that returns true if the angle represents a point at 
920:             * the front of the 3D pie chart.  0 - 180 degrees is the back, 180 - 360 
921:             * is the front.
922:             *
923:             * @param angle  the angle.
924:             *
925:             * @return A boolean.
926:             */
927:            private boolean isAngleAtFront(double angle) {
928:                return (Math.sin(Math.toRadians(angle)) < 0.0);
929:            }
930:
931:            /**
932:             * A utility method that returns true if the angle represents a point at 
933:             * the back of the 3D pie chart.  0 - 180 degrees is the back, 180 - 360 
934:             * is the front.
935:             *
936:             * @param angle  the angle.
937:             *
938:             * @return <code>true</code> if the angle is at the back of the pie.
939:             */
940:            private boolean isAngleAtBack(double angle) {
941:                return (Math.sin(Math.toRadians(angle)) > 0.0);
942:            }
943:
944:            /**
945:             * Tests this plot for equality with an arbitrary object.
946:             * 
947:             * @param obj  the object (<code>null</code> permitted).
948:             * 
949:             * @return A boolean.
950:             */
951:            public boolean equals(Object obj) {
952:                if (obj == this ) {
953:                    return true;
954:                }
955:                if (!(obj instanceof  PiePlot3D)) {
956:                    return false;
957:                }
958:                PiePlot3D that = (PiePlot3D) obj;
959:                if (this .depthFactor != that.depthFactor) {
960:                    return false;
961:                }
962:                return super.equals(obj);
963:            }
964:
965:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.