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