1:
103:
104: package ;
105:
106: import ;
107: import ;
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:
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: import ;
144: import ;
145: import ;
146: import ;
147: import ;
148: import ;
149: import ;
150: import ;
151: import ;
152: import ;
153: import ;
154: import ;
155: import ;
156: import ;
157:
158:
162: public abstract class AbstractXYItemRenderer extends AbstractRenderer
163: implements XYItemRenderer,
164: Cloneable,
165: Serializable {
166:
167:
168: private static final long serialVersionUID = 8019124836026607990L;
169:
170:
171: private XYPlot plot;
172:
173:
174: private XYItemLabelGenerator itemLabelGenerator;
175:
176:
177: private ObjectList itemLabelGeneratorList;
178:
179:
180: private XYItemLabelGenerator baseItemLabelGenerator;
181:
182:
183: private XYToolTipGenerator toolTipGenerator;
184:
185:
186: private ObjectList toolTipGeneratorList;
187:
188:
189: private XYToolTipGenerator baseToolTipGenerator;
190:
191:
192: private XYURLGenerator urlGenerator;
193:
194:
198: private List backgroundAnnotations;
199:
200:
204: private List foregroundAnnotations;
205:
206:
207: private int defaultEntityRadius;
208:
209:
210: private XYSeriesLabelGenerator legendItemLabelGenerator;
211:
212:
213: private XYSeriesLabelGenerator legendItemToolTipGenerator;
214:
215:
216: private XYSeriesLabelGenerator legendItemURLGenerator;
217:
218:
222: protected AbstractXYItemRenderer() {
223: this.itemLabelGenerator = null;
224: this.itemLabelGeneratorList = new ObjectList();
225: this.toolTipGenerator = null;
226: this.toolTipGeneratorList = new ObjectList();
227: this.urlGenerator = null;
228: this.backgroundAnnotations = new java.util.ArrayList();
229: this.foregroundAnnotations = new java.util.ArrayList();
230: this.defaultEntityRadius = 3;
231: this.legendItemLabelGenerator = new StandardXYSeriesLabelGenerator(
232: "{0}");
233: }
234:
235:
242: public int getPassCount() {
243: return 1;
244: }
245:
246:
251: public XYPlot getPlot() {
252: return this.plot;
253: }
254:
255:
260: public void setPlot(XYPlot plot) {
261: this.plot = plot;
262: }
263:
264:
281: public XYItemRendererState initialise(Graphics2D g2,
282: Rectangle2D dataArea,
283: XYPlot plot,
284: XYDataset data,
285: PlotRenderingInfo info) {
286:
287: XYItemRendererState state = new XYItemRendererState(info);
288: return state;
289:
290: }
291:
292:
293:
294:
305: public XYItemLabelGenerator getItemLabelGenerator(int series, int item) {
306:
307: if (this.itemLabelGenerator != null) {
308: return this.itemLabelGenerator;
309: }
310:
311:
312: XYItemLabelGenerator generator
313: = (XYItemLabelGenerator) this.itemLabelGeneratorList.get(series);
314: if (generator == null) {
315: generator = this.baseItemLabelGenerator;
316: }
317: return generator;
318: }
319:
320:
327: public XYItemLabelGenerator getSeriesItemLabelGenerator(int series) {
328: return (XYItemLabelGenerator) this.itemLabelGeneratorList.get(series);
329: }
330:
331:
340: public XYItemLabelGenerator getItemLabelGenerator() {
341: return this.itemLabelGenerator;
342: }
343:
344:
352: public void setItemLabelGenerator(XYItemLabelGenerator generator) {
353: this.itemLabelGenerator = generator;
354: notifyListeners(new RendererChangeEvent(this));
355: }
356:
357:
364: public void setSeriesItemLabelGenerator(int series,
365: XYItemLabelGenerator generator) {
366: this.itemLabelGeneratorList.set(series, generator);
367: notifyListeners(new RendererChangeEvent(this));
368: }
369:
370:
375: public XYItemLabelGenerator getBaseItemLabelGenerator() {
376: return this.baseItemLabelGenerator;
377: }
378:
379:
385: public void setBaseItemLabelGenerator(XYItemLabelGenerator generator) {
386: this.baseItemLabelGenerator = generator;
387: notifyListeners(new RendererChangeEvent(this));
388: }
389:
390:
391:
392:
402: public XYToolTipGenerator getToolTipGenerator(int series, int item) {
403:
404: if (this.toolTipGenerator != null) {
405: return this.toolTipGenerator;
406: }
407:
408:
409: XYToolTipGenerator generator
410: = (XYToolTipGenerator) this.toolTipGeneratorList.get(series);
411: if (generator == null) {
412: generator = this.baseToolTipGenerator;
413: }
414: return generator;
415: }
416:
417:
426: public XYToolTipGenerator getToolTipGenerator() {
427: return this.toolTipGenerator;
428: }
429:
430:
438: public void setToolTipGenerator(XYToolTipGenerator generator) {
439: this.toolTipGenerator = generator;
440: notifyListeners(new RendererChangeEvent(this));
441: }
442:
443:
450: public XYToolTipGenerator getSeriesToolTipGenerator(int series) {
451: return (XYToolTipGenerator) this.toolTipGeneratorList.get(series);
452: }
453:
454:
461: public void setSeriesToolTipGenerator(int series,
462: XYToolTipGenerator generator) {
463: this.toolTipGeneratorList.set(series, generator);
464: notifyListeners(new RendererChangeEvent(this));
465: }
466:
467:
474: public XYToolTipGenerator getBaseToolTipGenerator() {
475: return this.baseToolTipGenerator;
476: }
477:
478:
486: public void setBaseToolTipGenerator(XYToolTipGenerator generator) {
487: this.baseToolTipGenerator = generator;
488: notifyListeners(new RendererChangeEvent(this));
489: }
490:
491:
492:
493:
498: public XYURLGenerator getURLGenerator() {
499: return this.urlGenerator;
500: }
501:
502:
507: public void setURLGenerator(XYURLGenerator urlGenerator) {
508: this.urlGenerator = urlGenerator;
509: notifyListeners(new RendererChangeEvent(this));
510: }
511:
512:
519: public void addAnnotation(XYAnnotation annotation) {
520:
521: addAnnotation(annotation, Layer.FOREGROUND);
522: }
523:
524:
530: public void addAnnotation(XYAnnotation annotation, Layer layer) {
531: if (annotation == null) {
532: throw new IllegalArgumentException("Null 'annotation' argument.");
533: }
534: if (layer.equals(Layer.FOREGROUND)) {
535: this.foregroundAnnotations.add(annotation);
536: notifyListeners(new RendererChangeEvent(this));
537: }
538: else if (layer.equals(Layer.BACKGROUND)) {
539: this.backgroundAnnotations.add(annotation);
540: notifyListeners(new RendererChangeEvent(this));
541: }
542: else {
543:
544: throw new RuntimeException("Unknown layer.");
545: }
546: }
547:
557: public boolean removeAnnotation(XYAnnotation annotation) {
558: boolean removed = this.foregroundAnnotations.remove(annotation);
559: removed = removed & this.backgroundAnnotations.remove(annotation);
560: notifyListeners(new RendererChangeEvent(this));
561: return removed;
562: }
563:
564:
568: public void removeAnnotations() {
569: this.foregroundAnnotations.clear();
570: this.backgroundAnnotations.clear();
571: notifyListeners(new RendererChangeEvent(this));
572: }
573:
574:
580: public int getDefaultEntityRadius() {
581: return this.defaultEntityRadius;
582: }
583:
584:
590: public void setDefaultEntityRadius(int radius) {
591: this.defaultEntityRadius = radius;
592: }
593:
594:
601: public XYSeriesLabelGenerator getLegendItemLabelGenerator() {
602: return this.legendItemLabelGenerator;
603: }
604:
605:
613: public void setLegendItemLabelGenerator(XYSeriesLabelGenerator generator) {
614: if (generator == null) {
615: throw new IllegalArgumentException("Null 'generator' argument.");
616: }
617: this.legendItemLabelGenerator = generator;
618: notifyListeners(new RendererChangeEvent(this));
619: }
620:
621:
628: public XYSeriesLabelGenerator getLegendItemToolTipGenerator() {
629: return this.legendItemToolTipGenerator;
630: }
631:
632:
640: public void setLegendItemToolTipGenerator(
641: XYSeriesLabelGenerator generator) {
642: this.legendItemToolTipGenerator = generator;
643: notifyListeners(new RendererChangeEvent(this));
644: }
645:
646:
653: public XYSeriesLabelGenerator getLegendItemURLGenerator() {
654: return this.legendItemURLGenerator;
655: }
656:
657:
665: public void setLegendItemURLGenerator(XYSeriesLabelGenerator generator) {
666: this.legendItemURLGenerator = generator;
667: notifyListeners(new RendererChangeEvent(this));
668: }
669:
670:
679: public Range findDomainBounds(XYDataset dataset) {
680: if (dataset != null) {
681: return DatasetUtilities.findDomainBounds(dataset, false);
682: }
683: else {
684: return null;
685: }
686: }
687:
688:
697: public Range findRangeBounds(XYDataset dataset) {
698: if (dataset != null) {
699: return DatasetUtilities.findRangeBounds(dataset, false);
700: }
701: else {
702: return null;
703: }
704: }
705:
706:
712: public LegendItemCollection getLegendItems() {
713: if (this.plot == null) {
714: return new LegendItemCollection();
715: }
716: LegendItemCollection result = new LegendItemCollection();
717: int index = this.plot.getIndexOf(this);
718: XYDataset dataset = this.plot.getDataset(index);
719: if (dataset != null) {
720: int seriesCount = dataset.getSeriesCount();
721: for (int i = 0; i < seriesCount; i++) {
722: if (isSeriesVisibleInLegend(i)) {
723: LegendItem item = getLegendItem(index, i);
724: if (item != null) {
725: result.add(item);
726: }
727: }
728: }
729:
730: }
731: return result;
732: }
733:
734:
743: public LegendItem getLegendItem(int datasetIndex, int series) {
744: LegendItem result = null;
745: XYPlot xyplot = getPlot();
746: if (xyplot != null) {
747: XYDataset dataset = xyplot.getDataset(datasetIndex);
748: if (dataset != null) {
749: String label = this.legendItemLabelGenerator.generateLabel(
750: dataset, series);
751: String description = label;
752: String toolTipText = null;
753: if (getLegendItemToolTipGenerator() != null) {
754: toolTipText = getLegendItemToolTipGenerator().generateLabel(
755: dataset, series);
756: }
757: String urlText = null;
758: if (getLegendItemURLGenerator() != null) {
759: urlText = getLegendItemURLGenerator().generateLabel(
760: dataset, series);
761: }
762: Shape shape = getSeriesShape(series);
763: Paint paint = getSeriesPaint(series);
764: Paint outlinePaint = getSeriesOutlinePaint(series);
765: Stroke outlineStroke = getSeriesOutlineStroke(series);
766: result = new LegendItem(label, description, toolTipText,
767: urlText, shape, paint, outlineStroke, outlinePaint);
768: result.setSeriesIndex(series);
769: result.setDatasetIndex(datasetIndex);
770: }
771: }
772: return result;
773: }
774:
775:
786: public void fillDomainGridBand(Graphics2D g2,
787: XYPlot plot,
788: ValueAxis axis,
789: Rectangle2D dataArea,
790: double start, double end) {
791:
792: double x1 = axis.valueToJava2D(start, dataArea,
793: plot.getDomainAxisEdge());
794: double x2 = axis.valueToJava2D(end, dataArea,
795: plot.getDomainAxisEdge());
796:
797:
798: Rectangle2D band = new Rectangle2D.Double(x1, dataArea.getMinY(),
799: x2 - x1, dataArea.getMaxY() - dataArea.getMinY());
800: Paint paint = plot.getDomainTickBandPaint();
801:
802: if (paint != null) {
803: g2.setPaint(paint);
804: g2.fill(band);
805: }
806:
807: }
808:
809:
820: public void fillRangeGridBand(Graphics2D g2,
821: XYPlot plot,
822: ValueAxis axis,
823: Rectangle2D dataArea,
824: double start, double end) {
825:
826: double y1 = axis.valueToJava2D(start, dataArea,
827: plot.getRangeAxisEdge());
828: double y2 = axis.valueToJava2D(end, dataArea, plot.getRangeAxisEdge());
829:
830:
831: Rectangle2D band = new Rectangle2D.Double(dataArea.getMinX(), y2,
832: dataArea.getWidth(), y1 - y2);
833: Paint paint = plot.getRangeTickBandPaint();
834:
835: if (paint != null) {
836: g2.setPaint(paint);
837: g2.fill(band);
838: }
839:
840: }
841:
842:
852: public void drawDomainGridLine(Graphics2D g2,
853: XYPlot plot,
854: ValueAxis axis,
855: Rectangle2D dataArea,
856: double value) {
857:
858: Range range = axis.getRange();
859: if (!range.contains(value)) {
860: return;
861: }
862:
863: PlotOrientation orientation = plot.getOrientation();
864: double v = axis.valueToJava2D(value, dataArea,
865: plot.getDomainAxisEdge());
866: Line2D line = null;
867: if (orientation == PlotOrientation.HORIZONTAL) {
868: line = new Line2D.Double(dataArea.getMinX(), v,
869: dataArea.getMaxX(), v);
870: }
871: else if (orientation == PlotOrientation.VERTICAL) {
872: line = new Line2D.Double(v, dataArea.getMinY(), v,
873: dataArea.getMaxY());
874: }
875:
876: Paint paint = plot.getDomainGridlinePaint();
877: Stroke stroke = plot.getDomainGridlineStroke();
878: g2.setPaint(paint != null ? paint : Plot.DEFAULT_OUTLINE_PAINT);
879: g2.setStroke(stroke != null ? stroke : Plot.DEFAULT_OUTLINE_STROKE);
880: g2.draw(line);
881:
882: }
883:
884:
898: public void drawDomainLine(Graphics2D g2, XYPlot plot, ValueAxis axis,
899: Rectangle2D dataArea, double value, Paint paint, Stroke stroke) {
900:
901: Range range = axis.getRange();
902: if (!range.contains(value)) {
903: return;
904: }
905:
906: PlotOrientation orientation = plot.getOrientation();
907: Line2D line = null;
908: double v = axis.valueToJava2D(value, dataArea, plot.getDomainAxisEdge());
909: if (orientation == PlotOrientation.HORIZONTAL) {
910: line = new Line2D.Double(dataArea.getMinX(), v, dataArea.getMaxX(),
911: v);
912: }
913: else if (orientation == PlotOrientation.VERTICAL) {
914: line = new Line2D.Double(v, dataArea.getMinY(), v,
915: dataArea.getMaxY());
916: }
917:
918: g2.setPaint(paint);
919: g2.setStroke(stroke);
920: g2.draw(line);
921:
922: }
923:
924:
936: public void drawRangeLine(Graphics2D g2,
937: XYPlot plot,
938: ValueAxis axis,
939: Rectangle2D dataArea,
940: double value,
941: Paint paint,
942: Stroke stroke) {
943:
944: Range range = axis.getRange();
945: if (!range.contains(value)) {
946: return;
947: }
948:
949: PlotOrientation orientation = plot.getOrientation();
950: Line2D line = null;
951: double v = axis.valueToJava2D(value, dataArea, plot.getRangeAxisEdge());
952: if (orientation == PlotOrientation.HORIZONTAL) {
953: line = new Line2D.Double(v, dataArea.getMinY(), v,
954: dataArea.getMaxY());
955: }
956: else if (orientation == PlotOrientation.VERTICAL) {
957: line = new Line2D.Double(dataArea.getMinX(), v,
958: dataArea.getMaxX(), v);
959: }
960:
961: g2.setPaint(paint);
962: g2.setStroke(stroke);
963: g2.draw(line);
964:
965: }
966:
967:
976: public void drawDomainMarker(Graphics2D g2,
977: XYPlot plot,
978: ValueAxis domainAxis,
979: Marker marker,
980: Rectangle2D dataArea) {
981:
982: if (marker instanceof ValueMarker) {
983: ValueMarker vm = (ValueMarker) marker;
984: double value = vm.getValue();
985: Range range = domainAxis.getRange();
986: if (!range.contains(value)) {
987: return;
988: }
989:
990: double v = domainAxis.valueToJava2D(value, dataArea,
991: plot.getDomainAxisEdge());
992:
993: PlotOrientation orientation = plot.getOrientation();
994: Line2D line = null;
995: if (orientation == PlotOrientation.HORIZONTAL) {
996: line = new Line2D.Double(dataArea.getMinX(), v,
997: dataArea.getMaxX(), v);
998: }
999: else if (orientation == PlotOrientation.VERTICAL) {
1000: line = new Line2D.Double(v, dataArea.getMinY(), v,
1001: dataArea.getMaxY());
1002: }
1003:
1004: final Composite originalComposite = g2.getComposite();
1005: g2.setComposite(AlphaComposite.getInstance(
1006: AlphaComposite.SRC_OVER, marker.getAlpha()));
1007: g2.setPaint(marker.getPaint());
1008: g2.setStroke(marker.getStroke());
1009: g2.draw(line);
1010:
1011: String label = marker.getLabel();
1012: RectangleAnchor anchor = marker.getLabelAnchor();
1013: if (label != null) {
1014: Font labelFont = marker.getLabelFont();
1015: g2.setFont(labelFont);
1016: g2.setPaint(marker.getLabelPaint());
1017: Point2D coordinates = calculateDomainMarkerTextAnchorPoint(
1018: g2, orientation, dataArea, line.getBounds2D(),
1019: marker.getLabelOffset(),
1020: LengthAdjustmentType.EXPAND, anchor);
1021: TextUtilities.drawAlignedString(label, g2,
1022: (float) coordinates.getX(), (float) coordinates.getY(),
1023: marker.getLabelTextAnchor());
1024: }
1025: g2.setComposite(originalComposite);
1026: }
1027: else if (marker instanceof IntervalMarker) {
1028: IntervalMarker im = (IntervalMarker) marker;
1029: double start = im.getStartValue();
1030: double end = im.getEndValue();
1031: Range range = domainAxis.getRange();
1032: if (!(range.intersects(start, end))) {
1033: return;
1034: }
1035:
1036: double start2d = domainAxis.valueToJava2D(start, dataArea,
1037: plot.getDomainAxisEdge());
1038: double end2d = domainAxis.valueToJava2D(end, dataArea,
1039: plot.getDomainAxisEdge());
1040: double low = Math.min(start2d, end2d);
1041: double high = Math.max(start2d, end2d);
1042:
1043: PlotOrientation orientation = plot.getOrientation();
1044: Rectangle2D rect = null;
1045: if (orientation == PlotOrientation.HORIZONTAL) {
1046:
1047: low = Math.max(low, dataArea.getMinY());
1048: high = Math.min(high, dataArea.getMaxY());
1049: rect = new Rectangle2D.Double(dataArea.getMinX(),
1050: low, dataArea.getWidth(),
1051: high - low);
1052: }
1053: else if (orientation == PlotOrientation.VERTICAL) {
1054:
1055: low = Math.max(low, dataArea.getMinX());
1056: high = Math.min(high, dataArea.getMaxX());
1057: rect = new Rectangle2D.Double(low,
1058: dataArea.getMinY(), high - low,
1059: dataArea.getHeight());
1060: }
1061:
1062: final Composite originalComposite = g2.getComposite();
1063: g2.setComposite(AlphaComposite.getInstance(
1064: AlphaComposite.SRC_OVER, marker.getAlpha()));
1065: Paint p = marker.getPaint();
1066: if (p instanceof GradientPaint) {
1067: GradientPaint gp = (GradientPaint) p;
1068: GradientPaintTransformer t = im.getGradientPaintTransformer();
1069: if (t != null) {
1070: gp = t.transform(gp, rect);
1071: }
1072: g2.setPaint(gp);
1073: }
1074: else {
1075: g2.setPaint(p);
1076: }
1077: g2.fill(rect);
1078:
1079:
1080: if (im.getOutlinePaint() != null && im.getOutlineStroke() != null) {
1081: if (orientation == PlotOrientation.VERTICAL) {
1082: Line2D line = new Line2D.Double();
1083: double y0 = dataArea.getMinY();
1084: double y1 = dataArea.getMaxY();
1085: g2.setPaint(im.getOutlinePaint());
1086: g2.setStroke(im.getOutlineStroke());
1087: if (range.contains(start)) {
1088: line.setLine(start2d, y0, start2d, y1);
1089: g2.draw(line);
1090: }
1091: if (range.contains(end)) {
1092: line.setLine(end2d, y0, end2d, y1);
1093: g2.draw(line);
1094: }
1095: }
1096: else {
1097: Line2D line = new Line2D.Double();
1098: double x0 = dataArea.getMinX();
1099: double x1 = dataArea.getMaxX();
1100: g2.setPaint(im.getOutlinePaint());
1101: g2.setStroke(im.getOutlineStroke());
1102: if (range.contains(start)) {
1103: line.setLine(x0, start2d, x1, start2d);
1104: g2.draw(line);
1105: }
1106: if (range.contains(end)) {
1107: line.setLine(x0, end2d, x1, end2d);
1108: g2.draw(line);
1109: }
1110: }
1111: }
1112:
1113: String label = marker.getLabel();
1114: RectangleAnchor anchor = marker.getLabelAnchor();
1115: if (label != null) {
1116: Font labelFont = marker.getLabelFont();
1117: g2.setFont(labelFont);
1118: g2.setPaint(marker.getLabelPaint());
1119: Point2D coordinates = calculateDomainMarkerTextAnchorPoint(
1120: g2, orientation, dataArea, rect,
1121: marker.getLabelOffset(), marker.getLabelOffsetType(),
1122: anchor);
1123: TextUtilities.drawAlignedString(label, g2,
1124: (float) coordinates.getX(), (float) coordinates.getY(),
1125: marker.getLabelTextAnchor());
1126: }
1127: g2.setComposite(originalComposite);
1128:
1129: }
1130:
1131: }
1132:
1133:
1146: protected Point2D calculateDomainMarkerTextAnchorPoint(Graphics2D g2,
1147: PlotOrientation orientation,
1148: Rectangle2D dataArea,
1149: Rectangle2D markerArea,
1150: RectangleInsets markerOffset,
1151: LengthAdjustmentType labelOffsetType,
1152: RectangleAnchor anchor) {
1153:
1154: Rectangle2D anchorRect = null;
1155: if (orientation == PlotOrientation.HORIZONTAL) {
1156: anchorRect = markerOffset.createAdjustedRectangle(markerArea,
1157: LengthAdjustmentType.CONTRACT, labelOffsetType);
1158: }
1159: else if (orientation == PlotOrientation.VERTICAL) {
1160: anchorRect = markerOffset.createAdjustedRectangle(markerArea,
1161: labelOffsetType, LengthAdjustmentType.CONTRACT);
1162: }
1163: return RectangleAnchor.coordinates(anchorRect, anchor);
1164:
1165: }
1166:
1167:
1176: public void drawRangeMarker(Graphics2D g2,
1177: XYPlot plot,
1178: ValueAxis rangeAxis,
1179: Marker marker,
1180: Rectangle2D dataArea) {
1181:
1182: if (marker instanceof ValueMarker) {
1183: ValueMarker vm = (ValueMarker) marker;
1184: double value = vm.getValue();
1185: Range range = rangeAxis.getRange();
1186: if (!range.contains(value)) {
1187: return;
1188: }
1189:
1190: double v = rangeAxis.valueToJava2D(value, dataArea,
1191: plot.getRangeAxisEdge());
1192: PlotOrientation orientation = plot.getOrientation();
1193: Line2D line = null;
1194: if (orientation == PlotOrientation.HORIZONTAL) {
1195: line = new Line2D.Double(v, dataArea.getMinY(), v,
1196: dataArea.getMaxY());
1197: }
1198: else if (orientation == PlotOrientation.VERTICAL) {
1199: line = new Line2D.Double(dataArea.getMinX(), v,
1200: dataArea.getMaxX(), v);
1201: }
1202:
1203: final Composite originalComposite = g2.getComposite();
1204: g2.setComposite(AlphaComposite.getInstance(
1205: AlphaComposite.SRC_OVER, marker.getAlpha()));
1206: g2.setPaint(marker.getPaint());
1207: g2.setStroke(marker.getStroke());
1208: g2.draw(line);
1209:
1210: String label = marker.getLabel();
1211: RectangleAnchor anchor = marker.getLabelAnchor();
1212: if (label != null) {
1213: Font labelFont = marker.getLabelFont();
1214: g2.setFont(labelFont);
1215: g2.setPaint(marker.getLabelPaint());
1216: Point2D coordinates = calculateRangeMarkerTextAnchorPoint(
1217: g2, orientation, dataArea, line.getBounds2D(),
1218: marker.getLabelOffset(),
1219: LengthAdjustmentType.EXPAND, anchor);
1220: TextUtilities.drawAlignedString(label, g2,
1221: (float) coordinates.getX(), (float) coordinates.getY(),
1222: marker.getLabelTextAnchor());
1223: }
1224: g2.setComposite(originalComposite);
1225: }
1226: else if (marker instanceof IntervalMarker) {
1227: IntervalMarker im = (IntervalMarker) marker;
1228: double start = im.getStartValue();
1229: double end = im.getEndValue();
1230: Range range = rangeAxis.getRange();
1231: if (!(range.intersects(start, end))) {
1232: return;
1233: }
1234:
1235: double start2d = rangeAxis.valueToJava2D(start, dataArea,
1236: plot.getRangeAxisEdge());
1237: double end2d = rangeAxis.valueToJava2D(end, dataArea,
1238: plot.getRangeAxisEdge());
1239: double low = Math.min(start2d, end2d);
1240: double high = Math.max(start2d, end2d);
1241:
1242: PlotOrientation orientation = plot.getOrientation();
1243: Rectangle2D rect = null;
1244: if (orientation == PlotOrientation.HORIZONTAL) {
1245:
1246: low = Math.max(low, dataArea.getMinX());
1247: high = Math.min(high, dataArea.getMaxX());
1248: rect = new Rectangle2D.Double(low,
1249: dataArea.getMinY(), high - low,
1250: dataArea.getHeight());
1251: }
1252: else if (orientation == PlotOrientation.VERTICAL) {
1253:
1254: low = Math.max(low, dataArea.getMinY());
1255: high = Math.min(high, dataArea.getMaxY());
1256: rect = new Rectangle2D.Double(dataArea.getMinX(),
1257: low, dataArea.getWidth(),
1258: high - low);
1259: }
1260:
1261: final Composite originalComposite = g2.getComposite();
1262: g2.setComposite(AlphaComposite.getInstance(
1263: AlphaComposite.SRC_OVER, marker.getAlpha()));
1264: Paint p = marker.getPaint();
1265: if (p instanceof GradientPaint) {
1266: GradientPaint gp = (GradientPaint) p;
1267: GradientPaintTransformer t = im.getGradientPaintTransformer();
1268: if (t != null) {
1269: gp = t.transform(gp, rect);
1270: }
1271: g2.setPaint(gp);
1272: }
1273: else {
1274: g2.setPaint(p);
1275: }
1276: g2.fill(rect);
1277:
1278:
1279: if (im.getOutlinePaint() != null && im.getOutlineStroke() != null) {
1280: if (orientation == PlotOrientation.VERTICAL) {
1281: Line2D line = new Line2D.Double();
1282: double x0 = dataArea.getMinX();
1283: double x1 = dataArea.getMaxX();
1284: g2.setPaint(im.getOutlinePaint());
1285: g2.setStroke(im.getOutlineStroke());
1286: if (range.contains(start)) {
1287: line.setLine(x0, start2d, x1, start2d);
1288: g2.draw(line);
1289: }
1290: if (range.contains(end)) {
1291: line.setLine(x0, end2d, x1, end2d);
1292: g2.draw(line);
1293: }
1294: }
1295: else {
1296: Line2D line = new Line2D.Double();
1297: double y0 = dataArea.getMinY();
1298: double y1 = dataArea.getMaxY();
1299: g2.setPaint(im.getOutlinePaint());
1300: g2.setStroke(im.getOutlineStroke());
1301: if (range.contains(start)) {
1302: line.setLine(start2d, y0, start2d, y1);
1303: g2.draw(line);
1304: }
1305: if (range.contains(end)) {
1306: line.setLine(end2d, y0, end2d, y1);
1307: g2.draw(line);
1308: }
1309: }
1310: }
1311:
1312: String label = marker.getLabel();
1313: RectangleAnchor anchor = marker.getLabelAnchor();
1314: if (label != null) {
1315: Font labelFont = marker.getLabelFont();
1316: g2.setFont(labelFont);
1317: g2.setPaint(marker.getLabelPaint());
1318: Point2D coordinates = calculateRangeMarkerTextAnchorPoint(
1319: g2, orientation, dataArea, rect,
1320: marker.getLabelOffset(), marker.getLabelOffsetType(),
1321: anchor);
1322: TextUtilities.drawAlignedString(label, g2,
1323: (float) coordinates.getX(), (float) coordinates.getY(),
1324: marker.getLabelTextAnchor());
1325: }
1326: g2.setComposite(originalComposite);
1327: }
1328: }
1329:
1330:
1342: private Point2D calculateRangeMarkerTextAnchorPoint(Graphics2D g2,
1343: PlotOrientation orientation,
1344: Rectangle2D dataArea,
1345: Rectangle2D markerArea,
1346: RectangleInsets markerOffset,
1347: LengthAdjustmentType labelOffsetForRange,
1348: RectangleAnchor anchor) {
1349:
1350: Rectangle2D anchorRect = null;
1351: if (orientation == PlotOrientation.HORIZONTAL) {
1352: anchorRect = markerOffset.createAdjustedRectangle(markerArea,
1353: labelOffsetForRange, LengthAdjustmentType.CONTRACT);
1354: }
1355: else if (orientation == PlotOrientation.VERTICAL) {
1356: anchorRect = markerOffset.createAdjustedRectangle(markerArea,
1357: LengthAdjustmentType.CONTRACT, labelOffsetForRange);
1358: }
1359: return RectangleAnchor.coordinates(anchorRect, anchor);
1360:
1361: }
1362:
1363:
1371: protected Object clone() throws CloneNotSupportedException {
1372: AbstractXYItemRenderer clone = (AbstractXYItemRenderer) super.clone();
1373:
1374:
1375: if (this.itemLabelGenerator != null
1376: && this.itemLabelGenerator instanceof PublicCloneable) {
1377: PublicCloneable pc = (PublicCloneable) this.itemLabelGenerator;
1378: clone.itemLabelGenerator = (XYItemLabelGenerator) pc.clone();
1379: }
1380: clone.itemLabelGeneratorList
1381: = (ObjectList) this.itemLabelGeneratorList.clone();
1382: if (this.baseItemLabelGenerator != null
1383: && this.baseItemLabelGenerator instanceof PublicCloneable) {
1384: PublicCloneable pc = (PublicCloneable) this.baseItemLabelGenerator;
1385: clone.baseItemLabelGenerator = (XYItemLabelGenerator) pc.clone();
1386: }
1387:
1388: if (this.toolTipGenerator != null
1389: && this.toolTipGenerator instanceof PublicCloneable) {
1390: PublicCloneable pc = (PublicCloneable) this.toolTipGenerator;
1391: clone.toolTipGenerator = (XYToolTipGenerator) pc.clone();
1392: }
1393: clone.toolTipGeneratorList
1394: = (ObjectList) this.toolTipGeneratorList.clone();
1395: if (this.baseToolTipGenerator != null
1396: && this.baseToolTipGenerator instanceof PublicCloneable) {
1397: PublicCloneable pc = (PublicCloneable) this.baseToolTipGenerator;
1398: clone.baseToolTipGenerator = (XYToolTipGenerator) pc.clone();
1399: }
1400:
1401: if (clone.legendItemLabelGenerator instanceof PublicCloneable) {
1402: clone.legendItemLabelGenerator = (XYSeriesLabelGenerator)
1403: ObjectUtilities.clone(this.legendItemLabelGenerator);
1404: }
1405: if (clone.legendItemToolTipGenerator instanceof PublicCloneable) {
1406: clone.legendItemToolTipGenerator = (XYSeriesLabelGenerator)
1407: ObjectUtilities.clone(this.legendItemToolTipGenerator);
1408: }
1409: if (clone.legendItemURLGenerator instanceof PublicCloneable) {
1410: clone.legendItemURLGenerator = (XYSeriesLabelGenerator)
1411: ObjectUtilities.clone(this.legendItemURLGenerator);
1412: }
1413:
1414: clone.foregroundAnnotations = (List) ObjectUtilities.deepClone(
1415: this.foregroundAnnotations);
1416: clone.backgroundAnnotations = (List) ObjectUtilities.deepClone(
1417: this.backgroundAnnotations);
1418:
1419: if (clone.legendItemLabelGenerator instanceof PublicCloneable) {
1420: clone.legendItemLabelGenerator = (XYSeriesLabelGenerator)
1421: ObjectUtilities.clone(this.legendItemLabelGenerator);
1422: }
1423: if (clone.legendItemToolTipGenerator instanceof PublicCloneable) {
1424: clone.legendItemToolTipGenerator = (XYSeriesLabelGenerator)
1425: ObjectUtilities.clone(this.legendItemToolTipGenerator);
1426: }
1427: if (clone.legendItemURLGenerator instanceof PublicCloneable) {
1428: clone.legendItemURLGenerator = (XYSeriesLabelGenerator)
1429: ObjectUtilities.clone(this.legendItemURLGenerator);
1430: }
1431:
1432: return clone;
1433: }
1434:
1435:
1442: public boolean equals(Object obj) {
1443: if (obj == this) {
1444: return true;
1445: }
1446: if (!(obj instanceof AbstractXYItemRenderer)) {
1447: return false;
1448: }
1449: AbstractXYItemRenderer that = (AbstractXYItemRenderer) obj;
1450: if (!ObjectUtilities.equal(this.itemLabelGenerator,
1451: that.itemLabelGenerator)) {
1452: return false;
1453: }
1454: if (!this.itemLabelGeneratorList.equals(that.itemLabelGeneratorList)) {
1455: return false;
1456: }
1457: if (!ObjectUtilities.equal(this.baseItemLabelGenerator,
1458: that.baseItemLabelGenerator)) {
1459: return false;
1460: }
1461: if (!ObjectUtilities.equal(this.toolTipGenerator,
1462: that.toolTipGenerator)) {
1463: return false;
1464: }
1465: if (!this.toolTipGeneratorList.equals(that.toolTipGeneratorList)) {
1466: return false;
1467: }
1468: if (!ObjectUtilities.equal(this.baseToolTipGenerator,
1469: that.baseToolTipGenerator)) {
1470: return false;
1471: }
1472: if (!ObjectUtilities.equal(this.urlGenerator, that.urlGenerator)) {
1473: return false;
1474: }
1475: if (!this.foregroundAnnotations.equals(that.foregroundAnnotations)) {
1476: return false;
1477: }
1478: if (!this.backgroundAnnotations.equals(that.backgroundAnnotations)) {
1479: return false;
1480: }
1481: if (this.defaultEntityRadius != that.defaultEntityRadius) {
1482: return false;
1483: }
1484: if (!ObjectUtilities.equal(this.legendItemLabelGenerator,
1485: that.legendItemLabelGenerator)) {
1486: return false;
1487: }
1488: if (!ObjectUtilities.equal(this.legendItemToolTipGenerator,
1489: that.legendItemToolTipGenerator)) {
1490: return false;
1491: }
1492: if (!ObjectUtilities.equal(this.legendItemURLGenerator,
1493: that.legendItemURLGenerator)) {
1494: return false;
1495: }
1496: return super.equals(obj);
1497: }
1498:
1499:
1504: public DrawingSupplier getDrawingSupplier() {
1505: DrawingSupplier result = null;
1506: XYPlot p = getPlot();
1507: if (p != null) {
1508: result = p.getDrawingSupplier();
1509: }
1510: return result;
1511: }
1512:
1513:
1531: protected void updateCrosshairValues(CrosshairState crosshairState,
1532: double x, double y, double transX, double transY,
1533: PlotOrientation orientation) {
1534: updateCrosshairValues(crosshairState, x, y, 0, 0, transX, transY,
1535: orientation);
1536: }
1537:
1538:
1556: protected void updateCrosshairValues(CrosshairState crosshairState,
1557: double x, double y, int domainAxisIndex, int rangeAxisIndex,
1558: double transX, double transY, PlotOrientation orientation) {
1559:
1560: if (orientation == null) {
1561: throw new IllegalArgumentException("Null 'orientation' argument.");
1562: }
1563:
1564: if (crosshairState != null) {
1565:
1566: if (this.plot.isDomainCrosshairLockedOnData()) {
1567: if (this.plot.isRangeCrosshairLockedOnData()) {
1568:
1569: crosshairState.updateCrosshairPoint(x, y, domainAxisIndex,
1570: rangeAxisIndex, transX, transY, orientation);
1571: }
1572: else {
1573:
1574: crosshairState.updateCrosshairX(x, domainAxisIndex);
1575: }
1576: }
1577: else {
1578: if (this.plot.isRangeCrosshairLockedOnData()) {
1579:
1580: crosshairState.updateCrosshairY(y, rangeAxisIndex);
1581: }
1582: }
1583: }
1584:
1585: }
1586:
1587:
1600: protected void drawItemLabel(Graphics2D g2, PlotOrientation orientation,
1601: XYDataset dataset, int series, int item, double x, double y,
1602: boolean negative) {
1603:
1604: XYItemLabelGenerator generator = getItemLabelGenerator(series, item);
1605: if (generator != null) {
1606: Font labelFont = getItemLabelFont(series, item);
1607: Paint paint = getItemLabelPaint(series, item);
1608: g2.setFont(labelFont);
1609: g2.setPaint(paint);
1610: String label = generator.generateLabel(dataset, series, item);
1611:
1612:
1613: ItemLabelPosition position = null;
1614: if (!negative) {
1615: position = getPositiveItemLabelPosition(series, item);
1616: }
1617: else {
1618: position = getNegativeItemLabelPosition(series, item);
1619: }
1620:
1621:
1622: Point2D anchorPoint = calculateLabelAnchorPoint(
1623: position.getItemLabelAnchor(), x, y, orientation);
1624: TextUtilities.drawRotatedString(label, g2,
1625: (float) anchorPoint.getX(), (float) anchorPoint.getY(),
1626: position.getTextAnchor(), position.getAngle(),
1627: position.getRotationAnchor());
1628: }
1629:
1630: }
1631:
1632:
1642: public void drawAnnotations(Graphics2D g2,
1643: Rectangle2D dataArea,
1644: ValueAxis domainAxis,
1645: ValueAxis rangeAxis,
1646: Layer layer,
1647: PlotRenderingInfo info) {
1648:
1649: Iterator iterator = null;
1650: if (layer.equals(Layer.FOREGROUND)) {
1651: iterator = this.foregroundAnnotations.iterator();
1652: }
1653: else if (layer.equals(Layer.BACKGROUND)) {
1654: iterator = this.backgroundAnnotations.iterator();
1655: }
1656: else {
1657:
1658: throw new RuntimeException("Unknown layer.");
1659: }
1660: while (iterator.hasNext()) {
1661: XYAnnotation annotation = (XYAnnotation) iterator.next();
1662: annotation.draw(g2, this.plot, dataArea, domainAxis, rangeAxis,
1663: 0, info);
1664: }
1665:
1666: }
1667:
1668:
1680: protected void addEntity(EntityCollection entities, Shape area,
1681: XYDataset dataset, int series, int item,
1682: double entityX, double entityY) {
1683: if (!getItemCreateEntity(series, item)) {
1684: return;
1685: }
1686: if (area == null) {
1687: area = new Ellipse2D.Double(entityX - this.defaultEntityRadius,
1688: entityY - this.defaultEntityRadius,
1689: this.defaultEntityRadius * 2, this.defaultEntityRadius * 2);
1690: }
1691: String tip = null;
1692: XYToolTipGenerator generator = getToolTipGenerator(series, item);
1693: if (generator != null) {
1694: tip = generator.generateToolTip(dataset, series, item);
1695: }
1696: String url = null;
1697: if (getURLGenerator() != null) {
1698: url = getURLGenerator().generateURL(dataset, series, item);
1699: }
1700: XYItemEntity entity = new XYItemEntity(area, dataset, series, item,
1701: tip, url);
1702: entities.add(entity);
1703: }
1704:
1705: }