1:
91:
92: package ;
93:
94: import ;
95: import ;
96: import ;
97: import ;
98: import ;
99: import ;
100: import ;
101: import ;
102: import ;
103: import ;
104: import ;
105: import ;
106: import ;
107:
108: import ;
109: import ;
110: import ;
111: import ;
112: import ;
113: import ;
114: import ;
115: import ;
116: import ;
117: import ;
118: import ;
119: import ;
120: import ;
121: import ;
122: import ;
123: import ;
124: import ;
125: import ;
126: import ;
127: import ;
128: import ;
129: import ;
130: import ;
131: import ;
132: import ;
133: import ;
134: import ;
135: import ;
136: import ;
137: import ;
138: import ;
139: import ;
140: import ;
141: import ;
142: import ;
143:
144:
148: public abstract class AbstractXYItemRenderer extends AbstractRenderer
149: implements XYItemRenderer,
150: Cloneable,
151: Serializable {
152:
153:
154: private static final long serialVersionUID = 8019124836026607990L;
155:
156:
157: private XYPlot plot;
158:
159:
160: private XYItemLabelGenerator itemLabelGenerator;
161:
162:
163: private ObjectList itemLabelGeneratorList;
164:
165:
166: private XYItemLabelGenerator baseItemLabelGenerator;
167:
168:
169: private XYToolTipGenerator toolTipGenerator;
170:
171:
172: private ObjectList toolTipGeneratorList;
173:
174:
175: private XYToolTipGenerator baseToolTipGenerator;
176:
177:
178: private XYURLGenerator urlGenerator;
179:
180:
184: private List backgroundAnnotations;
185:
186:
190: private List foregroundAnnotations;
191:
192: private int defaultEntityRadius;
193:
194: private XYSeriesLabelGenerator legendItemLabelGenerator;
195:
196: private XYSeriesLabelGenerator legendItemToolTipGenerator;
197:
198: private XYSeriesLabelGenerator legendItemURLGenerator;
199:
200:
204: protected AbstractXYItemRenderer() {
205: this.itemLabelGenerator = null;
206: this.itemLabelGeneratorList = new ObjectList();
207: this.toolTipGenerator = null;
208: this.toolTipGeneratorList = new ObjectList();
209: this.urlGenerator = null;
210: this.backgroundAnnotations = new java.util.ArrayList();
211: this.foregroundAnnotations = new java.util.ArrayList();
212: this.defaultEntityRadius = 3;
213: this.legendItemLabelGenerator
214: = new StandardXYSeriesLabelGenerator("{0}");
215: }
216:
217:
224: public int getPassCount() {
225: return 1;
226: }
227:
228:
233: public XYPlot getPlot() {
234: return this.plot;
235: }
236:
237:
242: public void setPlot(XYPlot plot) {
243: this.plot = plot;
244: }
245:
246:
263: public XYItemRendererState initialise(Graphics2D g2,
264: Rectangle2D dataArea,
265: XYPlot plot,
266: XYDataset data,
267: PlotRenderingInfo info) {
268:
269: XYItemRendererState state = new XYItemRendererState(info);
270: return state;
271:
272: }
273:
274:
275:
276:
287: public XYItemLabelGenerator getItemLabelGenerator(int row, int column) {
288: return getSeriesItemLabelGenerator(row);
289: }
290:
291:
298: public XYItemLabelGenerator getSeriesItemLabelGenerator(int series) {
299:
300:
301: if (this.itemLabelGenerator != null) {
302: return this.itemLabelGenerator;
303: }
304:
305:
306: XYItemLabelGenerator generator
307: = (XYItemLabelGenerator) this.itemLabelGeneratorList.get(series);
308: if (generator == null) {
309: generator = this.baseItemLabelGenerator;
310: }
311: return generator;
312:
313: }
314:
315:
321: public void setItemLabelGenerator(XYItemLabelGenerator generator) {
322: this.itemLabelGenerator = generator;
323: notifyListeners(new RendererChangeEvent(this));
324: }
325:
326:
333: public void setSeriesItemLabelGenerator(int series,
334: XYItemLabelGenerator generator) {
335: this.itemLabelGeneratorList.set(series, generator);
336: notifyListeners(new RendererChangeEvent(this));
337: }
338:
339:
344: public XYItemLabelGenerator getBaseItemLabelGenerator() {
345: return this.baseItemLabelGenerator;
346: }
347:
348:
354: public void setBaseItemLabelGenerator(XYItemLabelGenerator generator) {
355: this.baseItemLabelGenerator = generator;
356: notifyListeners(new RendererChangeEvent(this));
357: }
358:
359:
360:
361:
372: public XYToolTipGenerator getToolTipGenerator(int row, int column) {
373: return getSeriesToolTipGenerator(row);
374: }
375:
376:
383: public XYToolTipGenerator getSeriesToolTipGenerator(int series) {
384:
385:
386: if (this.toolTipGenerator != null) {
387: return this.toolTipGenerator;
388: }
389:
390:
391: XYToolTipGenerator generator
392: = (XYToolTipGenerator) this.toolTipGeneratorList.get(series);
393: if (generator == null) {
394: generator = this.baseToolTipGenerator;
395: }
396: return generator;
397:
398: }
399:
400:
406: public void setToolTipGenerator(XYToolTipGenerator generator) {
407: this.toolTipGenerator = generator;
408: notifyListeners(new RendererChangeEvent(this));
409: }
410:
411:
418: public void setSeriesToolTipGenerator(int series,
419: XYToolTipGenerator generator) {
420: this.toolTipGeneratorList.set(series, generator);
421: notifyListeners(new RendererChangeEvent(this));
422: }
423:
424:
429: public XYToolTipGenerator getBaseToolTipGenerator() {
430: return this.baseToolTipGenerator;
431: }
432:
433:
439: public void setBaseToolTipGenerator(XYToolTipGenerator generator) {
440: this.baseToolTipGenerator = generator;
441: notifyListeners(new RendererChangeEvent(this));
442: }
443:
444:
445:
446:
451: public XYURLGenerator getURLGenerator() {
452: return this.urlGenerator;
453: }
454:
455:
460: public void setURLGenerator(XYURLGenerator urlGenerator) {
461: this.urlGenerator = urlGenerator;
462: notifyListeners(new RendererChangeEvent(this));
463: }
464:
465:
472: public void addAnnotation(XYAnnotation annotation) {
473:
474: addAnnotation(annotation, Layer.FOREGROUND);
475: }
476:
477:
483: public void addAnnotation(XYAnnotation annotation, Layer layer) {
484: if (annotation == null) {
485: throw new IllegalArgumentException("Null 'annotation' argument.");
486: }
487: if (layer.equals(Layer.FOREGROUND)) {
488: this.foregroundAnnotations.add(annotation);
489: notifyListeners(new RendererChangeEvent(this));
490: }
491: else if (layer.equals(Layer.BACKGROUND)) {
492: this.backgroundAnnotations.add(annotation);
493: notifyListeners(new RendererChangeEvent(this));
494: }
495: else {
496:
497: throw new RuntimeException("Unknown layer.");
498: }
499: }
500:
510: public boolean removeAnnotation(XYAnnotation annotation) {
511: boolean removed = this.foregroundAnnotations.remove(annotation);
512: removed = removed & this.backgroundAnnotations.remove(annotation);
513: notifyListeners(new RendererChangeEvent(this));
514: return removed;
515: }
516:
517:
521: public void removeAnnotations() {
522: this.foregroundAnnotations.clear();
523: this.backgroundAnnotations.clear();
524: notifyListeners(new RendererChangeEvent(this));
525: }
526:
527:
533: public int getDefaultEntityRadius() {
534: return this.defaultEntityRadius;
535: }
536:
537:
543: public void setDefaultEntityRadius(int radius) {
544: this.defaultEntityRadius = radius;
545: }
546:
547:
552: public XYSeriesLabelGenerator getLegendItemLabelGenerator() {
553: return this.legendItemLabelGenerator;
554: }
555:
556:
561: public void setLegendItemLabelGenerator(XYSeriesLabelGenerator generator) {
562: if (generator == null) {
563: throw new IllegalArgumentException("Null 'generator' argument.");
564: }
565: this.legendItemLabelGenerator = generator;
566: }
567:
568:
573: public XYSeriesLabelGenerator getLegendItemToolTipGenerator() {
574: return this.legendItemToolTipGenerator;
575: }
576:
577:
582: public void setLegendItemToolTipGenerator(XYSeriesLabelGenerator generator)
583: {
584: this.legendItemToolTipGenerator = generator;
585: }
586:
587:
592: public XYSeriesLabelGenerator getLegendItemURLGenerator() {
593: return this.legendItemURLGenerator;
594: }
595:
596:
601: public void setLegendItemURLGenerator(XYSeriesLabelGenerator generator)
602: {
603: this.legendItemURLGenerator = generator;
604: }
605:
606:
615: public Range findDomainBounds(XYDataset dataset) {
616: if (dataset != null) {
617: return DatasetUtilities.findDomainBounds(dataset, false);
618: }
619: else {
620: return null;
621: }
622: }
623:
624:
633: public Range findRangeBounds(XYDataset dataset) {
634: if (dataset != null) {
635: return DatasetUtilities.findRangeBounds(dataset, false);
636: }
637: else {
638: return null;
639: }
640: }
641:
642:
648: public LegendItemCollection getLegendItems() {
649: if (this.plot == null) {
650: return new LegendItemCollection();
651: }
652: LegendItemCollection result = new LegendItemCollection();
653: int index = this.plot.getIndexOf(this);
654: XYDataset dataset = this.plot.getDataset(index);
655: if (dataset != null) {
656: int seriesCount = dataset.getSeriesCount();
657: for (int i = 0; i < seriesCount; i++) {
658: if (isSeriesVisibleInLegend(i)) {
659: LegendItem item = getLegendItem(index, i);
660: if (item != null) {
661: result.add(item);
662: }
663: }
664: }
665:
666: }
667: return result;
668: }
669:
670:
679: public LegendItem getLegendItem(int datasetIndex, int series) {
680: LegendItem result = null;
681: XYPlot xyplot = getPlot();
682: if (xyplot != null) {
683: XYDataset dataset = xyplot.getDataset(datasetIndex);
684: if (dataset != null) {
685: String label = this.legendItemLabelGenerator.generateLabel(
686: dataset, series);
687: String description = label;
688: String toolTipText = null;
689: if (getLegendItemToolTipGenerator() != null) {
690: toolTipText = getLegendItemToolTipGenerator().generateLabel(
691: dataset, series);
692: }
693: String urlText = null;
694: if (getLegendItemURLGenerator() != null) {
695: urlText = getLegendItemURLGenerator().generateLabel(
696: dataset, series);
697: }
698: Shape shape = getSeriesShape(series);
699: Paint paint = getSeriesPaint(series);
700: Paint outlinePaint = getSeriesOutlinePaint(series);
701: Stroke outlineStroke = getSeriesOutlineStroke(series);
702: result = new LegendItem(label, description, toolTipText,
703: urlText, shape, paint, outlineStroke, outlinePaint);
704: result.setSeriesIndex(series);
705: result.setDatasetIndex(datasetIndex);
706: }
707: }
708: return result;
709: }
710:
711:
722: public void fillDomainGridBand(Graphics2D g2,
723: XYPlot plot,
724: ValueAxis axis,
725: Rectangle2D dataArea,
726: double start, double end) {
727:
728: double x1 = axis.valueToJava2D(start, dataArea,
729: plot.getDomainAxisEdge());
730: double x2 = axis.valueToJava2D(end, dataArea,
731: plot.getDomainAxisEdge());
732:
733:
734: Rectangle2D band = new Rectangle2D.Double(x1, dataArea.getMinY(),
735: x2 - x1, dataArea.getMaxY() - dataArea.getMinY());
736: Paint paint = plot.getDomainTickBandPaint();
737:
738: if (paint != null) {
739: g2.setPaint(paint);
740: g2.fill(band);
741: }
742:
743: }
744:
745:
756: public void fillRangeGridBand(Graphics2D g2,
757: XYPlot plot,
758: ValueAxis axis,
759: Rectangle2D dataArea,
760: double start, double end) {
761:
762: double y1 = axis.valueToJava2D(start, dataArea,
763: plot.getRangeAxisEdge());
764: double y2 = axis.valueToJava2D(end, dataArea, plot.getRangeAxisEdge());
765:
766:
767: Rectangle2D band = new Rectangle2D.Double(dataArea.getMinX(), y2,
768: dataArea.getWidth(), y1 - y2);
769: Paint paint = plot.getRangeTickBandPaint();
770:
771: if (paint != null) {
772: g2.setPaint(paint);
773: g2.fill(band);
774: }
775:
776: }
777:
778:
788: public void drawDomainGridLine(Graphics2D g2,
789: XYPlot plot,
790: ValueAxis axis,
791: Rectangle2D dataArea,
792: double value) {
793:
794: Range range = axis.getRange();
795: if (!range.contains(value)) {
796: return;
797: }
798:
799: PlotOrientation orientation = plot.getOrientation();
800: double v = axis.valueToJava2D(value, dataArea,
801: plot.getDomainAxisEdge());
802: Line2D line = null;
803: if (orientation == PlotOrientation.HORIZONTAL) {
804: line = new Line2D.Double(dataArea.getMinX(), v,
805: dataArea.getMaxX(), v);
806: }
807: else if (orientation == PlotOrientation.VERTICAL) {
808: line = new Line2D.Double(v, dataArea.getMinY(), v,
809: dataArea.getMaxY());
810: }
811:
812: Paint paint = plot.getDomainGridlinePaint();
813: Stroke stroke = plot.getDomainGridlineStroke();
814: g2.setPaint(paint != null ? paint : Plot.DEFAULT_OUTLINE_PAINT);
815: g2.setStroke(stroke != null ? stroke : Plot.DEFAULT_OUTLINE_STROKE);
816: g2.draw(line);
817:
818: }
819:
820:
832: public void drawRangeLine(Graphics2D g2,
833: XYPlot plot,
834: ValueAxis axis,
835: Rectangle2D dataArea,
836: double value,
837: Paint paint,
838: Stroke stroke) {
839:
840: Range range = axis.getRange();
841: if (!range.contains(value)) {
842: return;
843: }
844:
845: PlotOrientation orientation = plot.getOrientation();
846: Line2D line = null;
847: double v = axis.valueToJava2D(value, dataArea, plot.getRangeAxisEdge());
848: if (orientation == PlotOrientation.HORIZONTAL) {
849: line = new Line2D.Double(v, dataArea.getMinY(), v,
850: dataArea.getMaxY());
851: }
852: else if (orientation == PlotOrientation.VERTICAL) {
853: line = new Line2D.Double(dataArea.getMinX(), v,
854: dataArea.getMaxX(), v);
855: }
856:
857: g2.setPaint(paint);
858: g2.setStroke(stroke);
859: g2.draw(line);
860:
861: }
862:
863:
872: public void drawDomainMarker(Graphics2D g2,
873: XYPlot plot,
874: ValueAxis domainAxis,
875: Marker marker,
876: Rectangle2D dataArea) {
877:
878: if (marker instanceof ValueMarker) {
879: ValueMarker vm = (ValueMarker) marker;
880: double value = vm.getValue();
881: Range range = domainAxis.getRange();
882: if (!range.contains(value)) {
883: return;
884: }
885:
886: double v = domainAxis.valueToJava2D(value, dataArea,
887: plot.getDomainAxisEdge());
888:
889: PlotOrientation orientation = plot.getOrientation();
890: Line2D line = null;
891: if (orientation == PlotOrientation.HORIZONTAL) {
892: line = new Line2D.Double(dataArea.getMinX(), v,
893: dataArea.getMaxX(), v);
894: }
895: else if (orientation == PlotOrientation.VERTICAL) {
896: line = new Line2D.Double(v, dataArea.getMinY(), v,
897: dataArea.getMaxY());
898: }
899:
900: g2.setPaint(marker.getPaint());
901: g2.setStroke(marker.getStroke());
902: g2.draw(line);
903:
904: String label = marker.getLabel();
905: RectangleAnchor anchor = marker.getLabelAnchor();
906: if (label != null) {
907: Font labelFont = marker.getLabelFont();
908: g2.setFont(labelFont);
909: g2.setPaint(marker.getLabelPaint());
910: Point2D coordinates = calculateDomainMarkerTextAnchorPoint(
911: g2, orientation, dataArea, line.getBounds2D(),
912: marker.getLabelOffset(),
913: LengthAdjustmentType.EXPAND, anchor);
914: TextUtilities.drawAlignedString(label, g2,
915: (float) coordinates.getX(), (float) coordinates.getY(),
916: marker.getLabelTextAnchor());
917: }
918: }
919: else if (marker instanceof IntervalMarker) {
920: IntervalMarker im = (IntervalMarker) marker;
921: double start = im.getStartValue();
922: double end = im.getEndValue();
923: Range range = domainAxis.getRange();
924: if (!(range.intersects(start, end))) {
925: return;
926: }
927:
928:
929: start = range.constrain(start);
930: end = range.constrain(end);
931:
932: double v0 = domainAxis.valueToJava2D(start, dataArea,
933: plot.getDomainAxisEdge());
934: double v1 = domainAxis.valueToJava2D(end, dataArea,
935: plot.getDomainAxisEdge());
936:
937: PlotOrientation orientation = plot.getOrientation();
938: Rectangle2D rect = null;
939: if (orientation == PlotOrientation.HORIZONTAL) {
940: rect = new Rectangle2D.Double(dataArea.getMinX(),
941: Math.min(v0, v1), dataArea.getWidth(),
942: Math.abs(v1 - v0));
943: }
944: else if (orientation == PlotOrientation.VERTICAL) {
945: rect = new Rectangle2D.Double(Math.min(v0, v1),
946: dataArea.getMinY(), Math.abs(v1 - v0),
947: dataArea.getHeight());
948: }
949:
950: Paint p = marker.getPaint();
951: if (p instanceof GradientPaint) {
952: GradientPaint gp = (GradientPaint) p;
953: GradientPaintTransformer t = im.getGradientPaintTransformer();
954: if (t != null) {
955: gp = t.transform(gp, rect);
956: }
957: g2.setPaint(gp);
958: }
959: else {
960: g2.setPaint(p);
961: }
962: g2.fill(rect);
963:
964: String label = marker.getLabel();
965: RectangleAnchor anchor = marker.getLabelAnchor();
966: if (label != null) {
967: Font labelFont = marker.getLabelFont();
968: g2.setFont(labelFont);
969: g2.setPaint(marker.getLabelPaint());
970: Point2D coordinates = calculateDomainMarkerTextAnchorPoint(
971: g2, orientation, dataArea, rect,
972: marker.getLabelOffset(), marker.getLabelOffsetType(),
973: anchor);
974: TextUtilities.drawAlignedString(label, g2,
975: (float) coordinates.getX(), (float) coordinates.getY(),
976: marker.getLabelTextAnchor());
977: }
978:
979: }
980:
981: }
982:
983:
996: protected Point2D calculateDomainMarkerTextAnchorPoint(Graphics2D g2,
997: PlotOrientation orientation,
998: Rectangle2D dataArea,
999: Rectangle2D markerArea,
1000: RectangleInsets markerOffset,
1001: LengthAdjustmentType labelOffsetType,
1002: RectangleAnchor anchor) {
1003:
1004: Rectangle2D anchorRect = null;
1005: if (orientation == PlotOrientation.HORIZONTAL) {
1006: anchorRect = markerOffset.createAdjustedRectangle(markerArea,
1007: LengthAdjustmentType.CONTRACT, labelOffsetType);
1008: }
1009: else if (orientation == PlotOrientation.VERTICAL) {
1010: anchorRect = markerOffset.createAdjustedRectangle(markerArea,
1011: labelOffsetType, LengthAdjustmentType.CONTRACT);
1012: }
1013: return RectangleAnchor.coordinates(anchorRect, anchor);
1014:
1015: }
1016:
1017:
1026: public void drawRangeMarker(Graphics2D g2,
1027: XYPlot plot,
1028: ValueAxis rangeAxis,
1029: Marker marker,
1030: Rectangle2D dataArea) {
1031:
1032: if (marker instanceof ValueMarker) {
1033: ValueMarker vm = (ValueMarker) marker;
1034: double value = vm.getValue();
1035: Range range = rangeAxis.getRange();
1036: if (!range.contains(value)) {
1037: return;
1038: }
1039:
1040: double v = rangeAxis.valueToJava2D(value, dataArea,
1041: plot.getRangeAxisEdge());
1042: PlotOrientation orientation = plot.getOrientation();
1043: Line2D line = null;
1044: if (orientation == PlotOrientation.HORIZONTAL) {
1045: line = new Line2D.Double(v, dataArea.getMinY(), v,
1046: dataArea.getMaxY());
1047: }
1048: else if (orientation == PlotOrientation.VERTICAL) {
1049: line = new Line2D.Double(dataArea.getMinX(), v,
1050: dataArea.getMaxX(), v);
1051: }
1052: g2.setPaint(marker.getPaint());
1053: g2.setStroke(marker.getStroke());
1054: g2.draw(line);
1055:
1056: String label = marker.getLabel();
1057: RectangleAnchor anchor = marker.getLabelAnchor();
1058: if (label != null) {
1059: Font labelFont = marker.getLabelFont();
1060: g2.setFont(labelFont);
1061: g2.setPaint(marker.getLabelPaint());
1062: Point2D coordinates = calculateRangeMarkerTextAnchorPoint(
1063: g2, orientation, dataArea, line.getBounds2D(),
1064: marker.getLabelOffset(),
1065: LengthAdjustmentType.EXPAND, anchor);
1066: TextUtilities.drawAlignedString(label, g2,
1067: (float) coordinates.getX(), (float) coordinates.getY(),
1068: marker.getLabelTextAnchor());
1069: }
1070: }
1071: else if (marker instanceof IntervalMarker) {
1072:
1073: IntervalMarker im = (IntervalMarker) marker;
1074: double start = im.getStartValue();
1075: double end = im.getEndValue();
1076: Range range = rangeAxis.getRange();
1077: if (!(range.intersects(start, end))) {
1078: return;
1079: }
1080:
1081:
1082: start = range.constrain(start);
1083: end = range.constrain(end);
1084:
1085: double v0 = rangeAxis.valueToJava2D(start, dataArea,
1086: plot.getRangeAxisEdge());
1087: double v1 = rangeAxis.valueToJava2D(end, dataArea,
1088: plot.getRangeAxisEdge());
1089:
1090: PlotOrientation orientation = plot.getOrientation();
1091: Rectangle2D rect = null;
1092: if (orientation == PlotOrientation.HORIZONTAL) {
1093: rect = new Rectangle2D.Double(Math.min(v0, v1),
1094: dataArea.getMinY(), Math.abs(v1 - v0),
1095: dataArea.getHeight());
1096: }
1097: else if (orientation == PlotOrientation.VERTICAL) {
1098: rect = new Rectangle2D.Double(dataArea.getMinX(),
1099: Math.min(v0, v1), dataArea.getWidth(),
1100: Math.abs(v0 - v1));
1101: }
1102:
1103: Paint p = marker.getPaint();
1104: if (p instanceof GradientPaint) {
1105: GradientPaint gp = (GradientPaint) p;
1106: GradientPaintTransformer t = im.getGradientPaintTransformer();
1107: if (t != null) {
1108: gp = t.transform(gp, rect);
1109: }
1110: g2.setPaint(gp);
1111: }
1112: else {
1113: g2.setPaint(p);
1114: }
1115: g2.fill(rect);
1116: String label = marker.getLabel();
1117: RectangleAnchor anchor = marker.getLabelAnchor();
1118: if (label != null) {
1119: Font labelFont = marker.getLabelFont();
1120: g2.setFont(labelFont);
1121: g2.setPaint(marker.getLabelPaint());
1122: Point2D coordinates = calculateRangeMarkerTextAnchorPoint(
1123: g2, orientation, dataArea, rect,
1124: marker.getLabelOffset(), marker.getLabelOffsetType(),
1125: anchor);
1126: TextUtilities.drawAlignedString(label, g2,
1127: (float) coordinates.getX(), (float) coordinates.getY(),
1128: marker.getLabelTextAnchor());
1129: }
1130: }
1131: }
1132:
1133:
1145: private Point2D calculateRangeMarkerTextAnchorPoint(Graphics2D g2,
1146: PlotOrientation orientation,
1147: Rectangle2D dataArea,
1148: Rectangle2D markerArea,
1149: RectangleInsets markerOffset,
1150: LengthAdjustmentType labelOffsetForRange,
1151: RectangleAnchor anchor) {
1152:
1153: Rectangle2D anchorRect = null;
1154: if (orientation == PlotOrientation.HORIZONTAL) {
1155: anchorRect = markerOffset.createAdjustedRectangle(markerArea,
1156: labelOffsetForRange, LengthAdjustmentType.CONTRACT);
1157: }
1158: else if (orientation == PlotOrientation.VERTICAL) {
1159: anchorRect = markerOffset.createAdjustedRectangle(markerArea,
1160: LengthAdjustmentType.CONTRACT, labelOffsetForRange);
1161: }
1162: return RectangleAnchor.coordinates(anchorRect, anchor);
1163:
1164: }
1165:
1166:
1174: protected Object clone() throws CloneNotSupportedException {
1175: AbstractXYItemRenderer clone = (AbstractXYItemRenderer) super.clone();
1176:
1177: if (this.itemLabelGenerator != null
1178: && this.itemLabelGenerator instanceof PublicCloneable) {
1179: PublicCloneable pc = (PublicCloneable) this.itemLabelGenerator;
1180: clone.itemLabelGenerator = (XYItemLabelGenerator) pc.clone();
1181: }
1182: return clone;
1183: }
1184:
1185:
1192: public boolean equals(Object obj) {
1193:
1194: if (obj == null) {
1195: return false;
1196: }
1197: if (obj == this) {
1198: return true;
1199: }
1200: if (!(obj instanceof AbstractXYItemRenderer)) {
1201: return false;
1202: }
1203: AbstractXYItemRenderer renderer = (AbstractXYItemRenderer) obj;
1204: if (!super.equals(obj)) {
1205: return false;
1206: }
1207: if (!ObjectUtilities.equal(this.itemLabelGenerator,
1208: renderer.itemLabelGenerator)) {
1209: return false;
1210: }
1211: if (!ObjectUtilities.equal(this.urlGenerator, renderer.urlGenerator)) {
1212: return false;
1213: }
1214: return true;
1215: }
1216:
1217:
1222: public DrawingSupplier getDrawingSupplier() {
1223: DrawingSupplier result = null;
1224: XYPlot p = getPlot();
1225: if (p != null) {
1226: result = p.getDrawingSupplier();
1227: }
1228: return result;
1229: }
1230:
1231:
1245: protected void updateCrosshairValues(CrosshairState crosshairState,
1246: double x, double y, double transX,
1247: double transY,
1248: PlotOrientation orientation) {
1249:
1250: if (orientation == null) {
1251: throw new IllegalArgumentException("Null 'orientation' argument.");
1252: }
1253:
1254: if (crosshairState != null) {
1255:
1256: if (this.plot.isDomainCrosshairLockedOnData()) {
1257: if (this.plot.isRangeCrosshairLockedOnData()) {
1258:
1259: crosshairState.updateCrosshairPoint(x, y, transX, transY,
1260: orientation);
1261: }
1262: else {
1263:
1264: crosshairState.updateCrosshairX(x);
1265: }
1266: }
1267: else {
1268: if (this.plot.isRangeCrosshairLockedOnData()) {
1269:
1270: crosshairState.updateCrosshairY(y);
1271: }
1272: }
1273: }
1274:
1275: }
1276:
1277:
1290: protected void drawItemLabel(Graphics2D g2, PlotOrientation orientation,
1291: XYDataset dataset, int series, int item, double x, double y,
1292: boolean negative) {
1293:
1294: XYItemLabelGenerator generator = getItemLabelGenerator(series, item);
1295: if (generator != null) {
1296: Font labelFont = getItemLabelFont(series, item);
1297: Paint paint = getItemLabelPaint(series, item);
1298: g2.setFont(labelFont);
1299: g2.setPaint(paint);
1300: String label = generator.generateLabel(dataset, series, item);
1301:
1302:
1303: ItemLabelPosition position = null;
1304: if (!negative) {
1305: position = getPositiveItemLabelPosition(series, item);
1306: }
1307: else {
1308: position = getNegativeItemLabelPosition(series, item);
1309: }
1310:
1311:
1312: Point2D anchorPoint = calculateLabelAnchorPoint(
1313: position.getItemLabelAnchor(), x, y, orientation);
1314: TextUtilities.drawRotatedString(label, g2,
1315: (float) anchorPoint.getX(), (float) anchorPoint.getY(),
1316: position.getTextAnchor(), position.getAngle(),
1317: position.getRotationAnchor());
1318: }
1319:
1320: }
1321:
1322:
1332: public void drawAnnotations(Graphics2D g2,
1333: Rectangle2D dataArea,
1334: ValueAxis domainAxis,
1335: ValueAxis rangeAxis,
1336: Layer layer,
1337: PlotRenderingInfo info) {
1338:
1339: Iterator iterator = null;
1340: if (layer.equals(Layer.FOREGROUND)) {
1341: iterator = this.foregroundAnnotations.iterator();
1342: }
1343: else if (layer.equals(Layer.BACKGROUND)) {
1344: iterator = this.backgroundAnnotations.iterator();
1345: }
1346: else {
1347:
1348: throw new RuntimeException("Unknown layer.");
1349: }
1350: while (iterator.hasNext()) {
1351: XYAnnotation annotation = (XYAnnotation) iterator.next();
1352: annotation.draw(g2, this.plot, dataArea, domainAxis, rangeAxis,
1353: 0, info);
1354: }
1355:
1356: }
1357:
1358:
1370: protected void addEntity(EntityCollection entities, Shape area,
1371: XYDataset dataset, int series, int item,
1372: double entityX, double entityY) {
1373: if (!getItemCreateEntity(series, item)) {
1374: return;
1375: }
1376: if (area == null) {
1377: area = new Ellipse2D.Double(entityX - this.defaultEntityRadius,
1378: entityY - this.defaultEntityRadius,
1379: this.defaultEntityRadius * 2, this.defaultEntityRadius * 2);
1380: }
1381: String tip = null;
1382: XYToolTipGenerator generator = getToolTipGenerator(series, item);
1383: if (generator != null) {
1384: tip = generator.generateToolTip(dataset, series, item);
1385: }
1386: String url = null;
1387: if (getURLGenerator() != null) {
1388: url = getURLGenerator().generateURL(dataset, series, item);
1389: }
1390: XYItemEntity entity = new XYItemEntity(area, dataset, series, item,
1391: tip, url);
1392: entities.add(entity);
1393: }
1394:
1395: }