1:
81:
82: package ;
83:
84: import ;
85: import ;
86: import ;
87: import ;
88: import ;
89: import ;
90: import ;
91: import ;
92: import ;
93: import ;
94: import ;
95: import ;
96: import ;
97: import ;
98: import ;
99: import ;
100: import ;
101: import ;
102: import ;
103:
104: import ;
105: import ;
106: import ;
107: import ;
108: import ;
109: import ;
110: import ;
111:
112:
119: public class PiePlot3D extends PiePlot implements Serializable {
120:
121:
122: private static final long serialVersionUID = 3408984188945161432L;
123:
124:
125: private double depthFactor = 0.12;
126:
127:
133: private boolean darkerSides = false;
134:
135:
136:
139: public PiePlot3D() {
140: this(null);
141: }
142:
143:
149: public PiePlot3D(PieDataset dataset) {
150: super(dataset);
151: setCircular(false, false);
152: }
153:
154:
161: public double getDepthFactor() {
162: return this.depthFactor;
163: }
164:
165:
173: public void setDepthFactor(double factor) {
174: this.depthFactor = factor;
175: notifyListeners(new PlotChangeEvent(this));
176: }
177:
178:
189: public boolean getDarkerSides() {
190: return this.darkerSides;
191: }
192:
193:
206: public void setDarkerSides(boolean darker) {
207: this.darkerSides = darker;
208: notifyListeners(new PlotChangeEvent(this));
209: }
210:
211:
224: public void draw(Graphics2D g2, Rectangle2D plotArea, Point2D anchor,
225: PlotState parentState,
226: PlotRenderingInfo info) {
227:
228:
229: RectangleInsets insets = getInsets();
230: insets.trim(plotArea);
231:
232: Rectangle2D originalPlotArea = (Rectangle2D) plotArea.clone();
233: if (info != null) {
234: info.setPlotArea(plotArea);
235: info.setDataArea(plotArea);
236: }
237:
238: drawBackground(g2, plotArea);
239:
240: Shape savedClip = g2.getClip();
241: g2.clip(plotArea);
242:
243:
244: double gapPercent = getInteriorGap();
245: double labelPercent = 0.0;
246: if (getLabelGenerator() != null) {
247: labelPercent = getLabelGap() + getMaximumLabelWidth();
248: }
249: double gapHorizontal = plotArea.getWidth() * (gapPercent
250: + labelPercent) * 2.0;
251: double gapVertical = plotArea.getHeight() * gapPercent * 2.0;
252:
253: if (DEBUG_DRAW_INTERIOR) {
254: double hGap = plotArea.getWidth() * getInteriorGap();
255: double vGap = plotArea.getHeight() * getInteriorGap();
256: double igx1 = plotArea.getX() + hGap;
257: double igx2 = plotArea.getMaxX() - hGap;
258: double igy1 = plotArea.getY() + vGap;
259: double igy2 = plotArea.getMaxY() - vGap;
260: g2.setPaint(Color.lightGray);
261: g2.draw(new Rectangle2D.Double(igx1, igy1, igx2 - igx1,
262: igy2 - igy1));
263: }
264:
265: double linkX = plotArea.getX() + gapHorizontal / 2;
266: double linkY = plotArea.getY() + gapVertical / 2;
267: double linkW = plotArea.getWidth() - gapHorizontal;
268: double linkH = plotArea.getHeight() - gapVertical;
269:
270:
271: if (isCircular()) {
272: double min = Math.min(linkW, linkH) / 2;
273: linkX = (linkX + linkX + linkW) / 2 - min;
274: linkY = (linkY + linkY + linkH) / 2 - min;
275: linkW = 2 * min;
276: linkH = 2 * min;
277: }
278:
279: PiePlotState state = initialise(g2, plotArea, this, null, info);
280:
281:
282:
283: Rectangle2D linkAreaXX = new Rectangle2D.Double(linkX, linkY, linkW,
284: linkH * (1 - this.depthFactor));
285: state.setLinkArea(linkAreaXX);
286:
287: if (DEBUG_DRAW_LINK_AREA) {
288: g2.setPaint(Color.blue);
289: g2.draw(linkAreaXX);
290: g2.setPaint(Color.yellow);
291: g2.draw(new Ellipse2D.Double(linkAreaXX.getX(), linkAreaXX.getY(),
292: linkAreaXX.getWidth(), linkAreaXX.getHeight()));
293: }
294:
295:
296:
297:
298: double hh = linkW * getLabelLinkMargin();
299: double vv = linkH * getLabelLinkMargin();
300: Rectangle2D explodeArea = new Rectangle2D.Double(linkX + hh / 2.0,
301: linkY + vv / 2.0, linkW - hh, linkH - vv);
302:
303: state.setExplodedPieArea(explodeArea);
304:
305:
306:
307:
308: double maximumExplodePercent = getMaximumExplodePercent();
309: double percent = maximumExplodePercent / (1.0 + maximumExplodePercent);
310:
311: double h1 = explodeArea.getWidth() * percent;
312: double v1 = explodeArea.getHeight() * percent;
313: Rectangle2D pieArea = new Rectangle2D.Double(explodeArea.getX()
314: + h1 / 2.0, explodeArea.getY() + v1 / 2.0,
315: explodeArea.getWidth() - h1, explodeArea.getHeight() - v1);
316:
317:
318:
319: int depth = (int) (pieArea.getHeight() * this.depthFactor);
320: Rectangle2D linkArea = new Rectangle2D.Double(linkX, linkY, linkW,
321: linkH - depth);
322: state.setLinkArea(linkArea);
323:
324: state.setPieArea(pieArea);
325: state.setPieCenterX(pieArea.getCenterX());
326: state.setPieCenterY(pieArea.getCenterY() - depth / 2.0);
327: state.setPieWRadius(pieArea.getWidth() / 2.0);
328: state.setPieHRadius((pieArea.getHeight() - depth) / 2.0);
329:
330:
331: PieDataset dataset = getDataset();
332: if (DatasetUtilities.isEmptyOrNull(getDataset())) {
333: drawNoDataMessage(g2, plotArea);
334: g2.setClip(savedClip);
335: drawOutline(g2, plotArea);
336: return;
337: }
338:
339:
340: if (dataset.getKeys().size() > plotArea.getWidth()) {
341: String text = "Too many elements";
342: Font sfont = new Font("dialog", Font.BOLD, 10);
343: g2.setFont(sfont);
344: FontMetrics fm = g2.getFontMetrics(sfont);
345: int stringWidth = fm.stringWidth(text);
346:
347: g2.drawString(text, (int) (plotArea.getX() + (plotArea.getWidth()
348: - stringWidth) / 2), (int) (plotArea.getY()
349: + (plotArea.getHeight() / 2)));
350: return;
351: }
352:
353:
354:
355: if (isCircular()) {
356: double min = Math.min(plotArea.getWidth(),
357: plotArea.getHeight()) / 2;
358: plotArea = new Rectangle2D.Double(plotArea.getCenterX() - min,
359: plotArea.getCenterY() - min, 2 * min, 2 * min);
360: }
361:
362: List sectionKeys = dataset.getKeys();
363:
364: if (sectionKeys.size() == 0) {
365: return;
366: }
367:
368:
369: double arcX = pieArea.getX();
370: double arcY = pieArea.getY();
371:
372:
373: Composite originalComposite = g2.getComposite();
374: g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
375: getForegroundAlpha()));
376:
377: double totalValue = DatasetUtilities.calculatePieDatasetTotal(dataset);
378: double runningTotal = 0;
379: if (depth < 0) {
380: return;
381: }
382:
383: ArrayList arcList = new ArrayList();
384: Arc2D.Double arc;
385: Paint paint;
386: Paint outlinePaint;
387: Stroke outlineStroke;
388:
389: Iterator iterator = sectionKeys.iterator();
390: while (iterator.hasNext()) {
391:
392: Comparable currentKey = (Comparable) iterator.next();
393: Number dataValue = dataset.getValue(currentKey);
394: if (dataValue == null) {
395: arcList.add(null);
396: continue;
397: }
398: double value = dataValue.doubleValue();
399: if (value <= 0) {
400: arcList.add(null);
401: continue;
402: }
403: double startAngle = getStartAngle();
404: double direction = getDirection().getFactor();
405: double angle1 = startAngle + (direction * (runningTotal * 360))
406: / totalValue;
407: double angle2 = startAngle + (direction * (runningTotal + value)
408: * 360) / totalValue;
409: if (Math.abs(angle2 - angle1) > getMinimumArcAngleToDraw()) {
410: arcList.add(new Arc2D.Double(arcX, arcY + depth,
411: pieArea.getWidth(), pieArea.getHeight() - depth,
412: angle1, angle2 - angle1, Arc2D.PIE));
413: }
414: else {
415: arcList.add(null);
416: }
417: runningTotal += value;
418: }
419:
420: Shape oldClip = g2.getClip();
421:
422: Ellipse2D top = new Ellipse2D.Double(pieArea.getX(), pieArea.getY(),
423: pieArea.getWidth(), pieArea.getHeight() - depth);
424:
425: Ellipse2D bottom = new Ellipse2D.Double(pieArea.getX(), pieArea.getY()
426: + depth, pieArea.getWidth(), pieArea.getHeight() - depth);
427:
428: Rectangle2D lower = new Rectangle2D.Double(top.getX(),
429: top.getCenterY(), pieArea.getWidth(), bottom.getMaxY()
430: - top.getCenterY());
431:
432: Rectangle2D upper = new Rectangle2D.Double(pieArea.getX(), top.getY(),
433: pieArea.getWidth(), bottom.getCenterY() - top.getY());
434:
435: Area a = new Area(top);
436: a.add(new Area(lower));
437: Area b = new Area(bottom);
438: b.add(new Area(upper));
439: Area pie = new Area(a);
440: pie.intersect(b);
441:
442: Area front = new Area(pie);
443: front.subtract(new Area(top));
444:
445: Area back = new Area(pie);
446: back.subtract(new Area(bottom));
447:
448:
449: int[] xs;
450: int[] ys;
451: arc = new Arc2D.Double(arcX, arcY + depth, pieArea.getWidth(),
452: pieArea.getHeight() - depth, 0, 360, Arc2D.PIE);
453:
454: int categoryCount = arcList.size();
455: for (int categoryIndex = 0; categoryIndex < categoryCount;
456: categoryIndex++) {
457: arc = (Arc2D.Double) arcList.get(categoryIndex);
458: if (arc == null) {
459: continue;
460: }
461: Comparable key = getSectionKey(categoryIndex);
462: paint = lookupSectionPaint(key, true);
463: outlinePaint = lookupSectionOutlinePaint(key);
464: outlineStroke = lookupSectionOutlineStroke(key);
465: g2.setPaint(paint);
466: g2.fill(arc);
467: g2.setPaint(outlinePaint);
468: g2.setStroke(outlineStroke);
469: g2.draw(arc);
470: g2.setPaint(paint);
471:
472: Point2D p1 = arc.getStartPoint();
473:
474:
475: xs = new int[] {(int) arc.getCenterX(), (int) arc.getCenterX(),
476: (int) p1.getX(), (int) p1.getX()};
477: ys = new int[] {(int) arc.getCenterY(), (int) arc.getCenterY()
478: - depth, (int) p1.getY() - depth, (int) p1.getY()};
479: Polygon polygon = new Polygon(xs, ys, 4);
480: g2.setPaint(java.awt.Color.lightGray);
481: g2.fill(polygon);
482: g2.setPaint(outlinePaint);
483: g2.setStroke(outlineStroke);
484: g2.draw(polygon);
485: g2.setPaint(paint);
486:
487: }
488:
489: g2.setPaint(Color.gray);
490: g2.fill(back);
491: g2.fill(front);
492:
493:
494: int cat = 0;
495: iterator = arcList.iterator();
496: while (iterator.hasNext()) {
497: Arc2D segment = (Arc2D) iterator.next();
498: if (segment != null) {
499: Comparable key = getSectionKey(cat);
500: paint = lookupSectionPaint(key, true);
501: outlinePaint = lookupSectionOutlinePaint(key);
502: outlineStroke = lookupSectionOutlineStroke(key);
503: drawSide(g2, pieArea, segment, front, back, paint,
504: outlinePaint, outlineStroke, false, true);
505: }
506: cat++;
507: }
508:
509:
510: cat = 0;
511: iterator = arcList.iterator();
512: while (iterator.hasNext()) {
513: Arc2D segment = (Arc2D) iterator.next();
514: if (segment != null) {
515: Comparable key = getSectionKey(cat);
516: paint = lookupSectionPaint(key);
517: outlinePaint = lookupSectionOutlinePaint(key);
518: outlineStroke = lookupSectionOutlineStroke(key);
519: drawSide(g2, pieArea, segment, front, back, paint,
520: outlinePaint, outlineStroke, true, false);
521: }
522: cat++;
523: }
524:
525: g2.setClip(oldClip);
526:
527:
528: Arc2D upperArc;
529: for (int sectionIndex = 0; sectionIndex < categoryCount;
530: sectionIndex++) {
531: arc = (Arc2D.Double) arcList.get(sectionIndex);
532: if (arc == null) {
533: continue;
534: }
535: upperArc = new Arc2D.Double(arcX, arcY, pieArea.getWidth(),
536: pieArea.getHeight() - depth, arc.getAngleStart(),
537: arc.getAngleExtent(), Arc2D.PIE);
538:
539: Comparable currentKey = (Comparable) sectionKeys.get(sectionIndex);
540: paint = lookupSectionPaint(currentKey, true);
541: outlinePaint = lookupSectionOutlinePaint(currentKey);
542: outlineStroke = lookupSectionOutlineStroke(currentKey);
543: g2.setPaint(paint);
544: g2.fill(upperArc);
545: g2.setStroke(outlineStroke);
546: g2.setPaint(outlinePaint);
547: g2.draw(upperArc);
548:
549:
550: if (info != null) {
551: EntityCollection entities
552: = info.getOwner().getEntityCollection();
553: if (entities != null) {
554: String tip = null;
555: PieToolTipGenerator tipster = getToolTipGenerator();
556: if (tipster != null) {
557:
558: tip = tipster.generateToolTip(dataset, currentKey);
559: }
560: String url = null;
561: if (getURLGenerator() != null) {
562: url = getURLGenerator().generateURL(dataset, currentKey,
563: getPieIndex());
564: }
565: PieSectionEntity entity = new PieSectionEntity(
566: upperArc, dataset, getPieIndex(), sectionIndex,
567: currentKey, tip, url);
568: entities.add(entity);
569: }
570: }
571: List keys = dataset.getKeys();
572: Rectangle2D adjustedPlotArea = new Rectangle2D.Double(
573: originalPlotArea.getX(), originalPlotArea.getY(),
574: originalPlotArea.getWidth(), originalPlotArea.getHeight()
575: - depth);
576: if (getSimpleLabels()) {
577: drawSimpleLabels(g2, keys, totalValue, adjustedPlotArea,
578: linkArea, state);
579: }
580: else {
581: drawLabels(g2, keys, totalValue, adjustedPlotArea, linkArea,
582: state);
583: }
584: }
585:
586: g2.setClip(savedClip);
587: g2.setComposite(originalComposite);
588: drawOutline(g2, originalPlotArea);
589:
590: }
591:
592:
606: protected void drawSide(Graphics2D g2,
607: Rectangle2D plotArea,
608: Arc2D arc,
609: Area front,
610: Area back,
611: Paint paint,
612: Paint outlinePaint,
613: Stroke outlineStroke,
614: boolean drawFront,
615: boolean drawBack) {
616:
617: if (getDarkerSides()) {
618: if (paint instanceof Color) {
619: Color c = (Color) paint;
620: c = c.darker();
621: paint = c;
622: }
623: }
624:
625: double start = arc.getAngleStart();
626: double extent = arc.getAngleExtent();
627: double end = start + extent;
628:
629: g2.setStroke(outlineStroke);
630:
631:
632: if (extent < 0.0) {
633:
634: if (isAngleAtFront(start)) {
635:
636: if (!isAngleAtBack(end)) {
637:
638: if (extent > -180.0) {
639:
640: if (drawFront) {
641: Area side = new Area(new Rectangle2D.Double(
642: arc.getEndPoint().getX(), plotArea.getY(),
643: arc.getStartPoint().getX()
644: - arc.getEndPoint().getX(),
645: plotArea.getHeight()));
646: side.intersect(front);
647: g2.setPaint(paint);
648: g2.fill(side);
649: g2.setPaint(outlinePaint);
650: g2.draw(side);
651: }
652: }
653: else {
654:
655:
656: Area side1 = new Area(new Rectangle2D.Double(
657: plotArea.getX(), plotArea.getY(),
658: arc.getStartPoint().getX() - plotArea.getX(),
659: plotArea.getHeight()));
660: side1.intersect(front);
661:
662: Area side2 = new Area(new Rectangle2D.Double(
663: arc.getEndPoint().getX(), plotArea.getY(),
664: plotArea.getMaxX() - arc.getEndPoint().getX(),
665: plotArea.getHeight()));
666:
667: side2.intersect(front);
668: g2.setPaint(paint);
669: if (drawFront) {
670: g2.fill(side1);
671: g2.fill(side2);
672: }
673:
674: if (drawBack) {
675: g2.fill(back);
676: }
677:
678: g2.setPaint(outlinePaint);
679: if (drawFront) {
680: g2.draw(side1);
681: g2.draw(side2);
682: }
683:
684: if (drawBack) {
685: g2.draw(back);
686: }
687:
688: }
689: }
690: else {
691:
692:
693: if (drawBack) {
694: Area side2 = new Area(new Rectangle2D.Double(
695: plotArea.getX(), plotArea.getY(),
696: arc.getEndPoint().getX() - plotArea.getX(),
697: plotArea.getHeight()));
698: side2.intersect(back);
699: g2.setPaint(paint);
700: g2.fill(side2);
701: g2.setPaint(outlinePaint);
702: g2.draw(side2);
703: }
704:
705: if (drawFront) {
706: Area side1 = new Area(new Rectangle2D.Double(
707: plotArea.getX(), plotArea.getY(),
708: arc.getStartPoint().getX() - plotArea.getX(),
709: plotArea.getHeight()));
710: side1.intersect(front);
711: g2.setPaint(paint);
712: g2.fill(side1);
713: g2.setPaint(outlinePaint);
714: g2.draw(side1);
715: }
716: }
717: }
718: else {
719:
720:
721: if (!isAngleAtFront(end)) {
722: if (extent > -180.0) {
723: if (drawBack) {
724: Area side = new Area(new Rectangle2D.Double(
725: arc.getStartPoint().getX(), plotArea.getY(),
726: arc.getEndPoint().getX()
727: - arc.getStartPoint().getX(),
728: plotArea.getHeight()));
729: side.intersect(back);
730: g2.setPaint(paint);
731: g2.fill(side);
732: g2.setPaint(outlinePaint);
733: g2.draw(side);
734: }
735: }
736: else {
737:
738: Area side1 = new Area(new Rectangle2D.Double(
739: arc.getStartPoint().getX(), plotArea.getY(),
740: plotArea.getMaxX() - arc.getStartPoint().getX(),
741: plotArea.getHeight()));
742: side1.intersect(back);
743:
744: Area side2 = new Area(new Rectangle2D.Double(
745: plotArea.getX(), plotArea.getY(),
746: arc.getEndPoint().getX() - plotArea.getX(),
747: plotArea.getHeight()));
748:
749: side2.intersect(back);
750:
751: g2.setPaint(paint);
752: if (drawBack) {
753: g2.fill(side1);
754: g2.fill(side2);
755: }
756:
757: if (drawFront) {
758: g2.fill(front);
759: }
760:
761: g2.setPaint(outlinePaint);
762: if (drawBack) {
763: g2.draw(side1);
764: g2.draw(side2);
765: }
766:
767: if (drawFront) {
768: g2.draw(front);
769: }
770:
771: }
772: }
773: else {
774:
775: if (drawBack) {
776: Area side1 = new Area(new Rectangle2D.Double(
777: arc.getStartPoint().getX(), plotArea.getY(),
778: plotArea.getMaxX() - arc.getStartPoint().getX(),
779: plotArea.getHeight()));
780: side1.intersect(back);
781: g2.setPaint(paint);
782: g2.fill(side1);
783: g2.setPaint(outlinePaint);
784: g2.draw(side1);
785: }
786:
787: if (drawFront) {
788: Area side2 = new Area(new Rectangle2D.Double(
789: arc.getEndPoint().getX(), plotArea.getY(),
790: plotArea.getMaxX() - arc.getEndPoint().getX(),
791: plotArea.getHeight()));
792: side2.intersect(front);
793: g2.setPaint(paint);
794: g2.fill(side2);
795: g2.setPaint(outlinePaint);
796: g2.draw(side2);
797: }
798:
799: }
800: }
801: }
802: else if (extent > 0.0) {
803:
804: if (isAngleAtFront(start)) {
805:
806: if (!isAngleAtBack(end)) {
807:
808: if (extent < 180.0) {
809: if (drawFront) {
810: Area side = new Area(new Rectangle2D.Double(
811: arc.getStartPoint().getX(), plotArea.getY(),
812: arc.getEndPoint().getX()
813: - arc.getStartPoint().getX(),
814: plotArea.getHeight()));
815: side.intersect(front);
816: g2.setPaint(paint);
817: g2.fill(side);
818: g2.setPaint(outlinePaint);
819: g2.draw(side);
820: }
821: }
822: else {
823: Area side1 = new Area(new Rectangle2D.Double(
824: arc.getStartPoint().getX(), plotArea.getY(),
825: plotArea.getMaxX() - arc.getStartPoint().getX(),
826: plotArea.getHeight()));
827: side1.intersect(front);
828:
829: Area side2 = new Area(new Rectangle2D.Double(
830: plotArea.getX(), plotArea.getY(),
831: arc.getEndPoint().getX() - plotArea.getX(),
832: plotArea.getHeight()));
833: side2.intersect(front);
834:
835: g2.setPaint(paint);
836: if (drawFront) {
837: g2.fill(side1);
838: g2.fill(side2);
839: }
840:
841: if (drawBack) {
842: g2.fill(back);
843: }
844:
845: g2.setPaint(outlinePaint);
846: if (drawFront) {
847: g2.draw(side1);
848: g2.draw(side2);
849: }
850:
851: if (drawBack) {
852: g2.draw(back);
853: }
854:
855: }
856: }
857: else {
858: if (drawBack) {
859: Area side2 = new Area(new Rectangle2D.Double(
860: arc.getEndPoint().getX(), plotArea.getY(),
861: plotArea.getMaxX() - arc.getEndPoint().getX(),
862: plotArea.getHeight()));
863: side2.intersect(back);
864: g2.setPaint(paint);
865: g2.fill(side2);
866: g2.setPaint(outlinePaint);
867: g2.draw(side2);
868: }
869:
870: if (drawFront) {
871: Area side1 = new Area(new Rectangle2D.Double(
872: arc.getStartPoint().getX(), plotArea.getY(),
873: plotArea.getMaxX() - arc.getStartPoint().getX(),
874: plotArea.getHeight()));
875: side1.intersect(front);
876: g2.setPaint(paint);
877: g2.fill(side1);
878: g2.setPaint(outlinePaint);
879: g2.draw(side1);
880: }
881: }
882: }
883: else {
884:
885: if (!isAngleAtFront(end)) {
886: if (extent < 180.0) {
887: if (drawBack) {
888: Area side = new Area(new Rectangle2D.Double(
889: arc.getEndPoint().getX(), plotArea.getY(),
890: arc.getStartPoint().getX()
891: - arc.getEndPoint().getX(),
892: plotArea.getHeight()));
893: side.intersect(back);
894: g2.setPaint(paint);
895: g2.fill(side);
896: g2.setPaint(outlinePaint);
897: g2.draw(side);
898: }
899: }
900: else {
901:
902: Area side1 = new Area(new Rectangle2D.Double(
903: arc.getStartPoint().getX(), plotArea.getY(),
904: plotArea.getX() - arc.getStartPoint().getX(),
905: plotArea.getHeight()));
906: side1.intersect(back);
907:
908: Area side2 = new Area(new Rectangle2D.Double(
909: arc.getEndPoint().getX(), plotArea.getY(),
910: plotArea.getMaxX() - arc.getEndPoint().getX(),
911: plotArea.getHeight()));
912: side2.intersect(back);
913:
914: g2.setPaint(paint);
915: if (drawBack) {
916: g2.fill(side1);
917: g2.fill(side2);
918: }
919:
920: if (drawFront) {
921: g2.fill(front);
922: }
923:
924: g2.setPaint(outlinePaint);
925: if (drawBack) {
926: g2.draw(side1);
927: g2.draw(side2);
928: }
929:
930: if (drawFront) {
931: g2.draw(front);
932: }
933:
934: }
935: }
936: else {
937:
938: if (drawBack) {
939: Area side1 = new Area(new Rectangle2D.Double(
940: plotArea.getX(), plotArea.getY(),
941: arc.getStartPoint().getX() - plotArea.getX(),
942: plotArea.getHeight()));
943: side1.intersect(back);
944: g2.setPaint(paint);
945: g2.fill(side1);
946: g2.setPaint(outlinePaint);
947: g2.draw(side1);
948: }
949:
950: if (drawFront) {
951: Area side2 = new Area(new Rectangle2D.Double(
952: plotArea.getX(), plotArea.getY(),
953: arc.getEndPoint().getX() - plotArea.getX(),
954: plotArea.getHeight()));
955: side2.intersect(front);
956: g2.setPaint(paint);
957: g2.fill(side2);
958: g2.setPaint(outlinePaint);
959: g2.draw(side2);
960: }
961: }
962: }
963:
964: }
965:
966: }
967:
968:
973: public String getPlotType() {
974: return localizationResources.getString("Pie_3D_Plot");
975: }
976:
977:
986: private boolean isAngleAtFront(double angle) {
987: return (Math.sin(Math.toRadians(angle)) < 0.0);
988: }
989:
990:
999: private boolean isAngleAtBack(double angle) {
1000: return (Math.sin(Math.toRadians(angle)) > 0.0);
1001: }
1002:
1003:
1010: public boolean equals(Object obj) {
1011: if (obj == this) {
1012: return true;
1013: }
1014: if (!(obj instanceof PiePlot3D)) {
1015: return false;
1016: }
1017: PiePlot3D that = (PiePlot3D) obj;
1018: if (this.depthFactor != that.depthFactor) {
1019: return false;
1020: }
1021: if (this.darkerSides != that.darkerSides) {
1022: return false;
1023: }
1024: return super.equals(obj);
1025: }
1026:
1027: }