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