1:
105:
106: package ;
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:
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: import ;
158: import ;
159:
160:
164: public abstract class AbstractXYItemRenderer extends AbstractRenderer
165: implements XYItemRenderer,
166: Cloneable,
167: Serializable {
168:
169:
170: private static final long serialVersionUID = 8019124836026607990L;
171:
172:
173: private XYPlot plot;
174:
175:
181: private XYItemLabelGenerator itemLabelGenerator;
182:
183:
184: private ObjectList itemLabelGeneratorList;
185:
186:
187: private XYItemLabelGenerator baseItemLabelGenerator;
188:
189:
195: private XYToolTipGenerator toolTipGenerator;
196:
197:
198: private ObjectList toolTipGeneratorList;
199:
200:
201: private XYToolTipGenerator baseToolTipGenerator;
202:
203:
204: private XYURLGenerator urlGenerator;
205:
206:
210: private List backgroundAnnotations;
211:
212:
216: private List foregroundAnnotations;
217:
218:
219: private int defaultEntityRadius;
220:
221:
222: private XYSeriesLabelGenerator legendItemLabelGenerator;
223:
224:
225: private XYSeriesLabelGenerator legendItemToolTipGenerator;
226:
227:
228: private XYSeriesLabelGenerator legendItemURLGenerator;
229:
230:
234: protected AbstractXYItemRenderer() {
235: super();
236: this.itemLabelGenerator = null;
237: this.itemLabelGeneratorList = new ObjectList();
238: this.toolTipGenerator = null;
239: this.toolTipGeneratorList = new ObjectList();
240: this.urlGenerator = null;
241: this.backgroundAnnotations = new java.util.ArrayList();
242: this.foregroundAnnotations = new java.util.ArrayList();
243: this.defaultEntityRadius = 3;
244: this.legendItemLabelGenerator = new StandardXYSeriesLabelGenerator(
245: "{0}");
246: }
247:
248:
255: public int getPassCount() {
256: return 1;
257: }
258:
259:
264: public XYPlot getPlot() {
265: return this.plot;
266: }
267:
268:
273: public void setPlot(XYPlot plot) {
274: this.plot = plot;
275: }
276:
277:
294: public XYItemRendererState initialise(Graphics2D g2,
295: Rectangle2D dataArea,
296: XYPlot plot,
297: XYDataset data,
298: PlotRenderingInfo info) {
299:
300: XYItemRendererState state = new XYItemRendererState(info);
301: return state;
302:
303: }
304:
305:
306:
307:
318: public XYItemLabelGenerator getItemLabelGenerator(int series, int item) {
319:
320: if (this.itemLabelGenerator != null) {
321: return this.itemLabelGenerator;
322: }
323:
324:
325: XYItemLabelGenerator generator
326: = (XYItemLabelGenerator) this.itemLabelGeneratorList.get(series);
327: if (generator == null) {
328: generator = this.baseItemLabelGenerator;
329: }
330: return generator;
331: }
332:
333:
340: public XYItemLabelGenerator getSeriesItemLabelGenerator(int series) {
341: return (XYItemLabelGenerator) this.itemLabelGeneratorList.get(series);
342: }
343:
344:
357: public XYItemLabelGenerator getItemLabelGenerator() {
358: return this.itemLabelGenerator;
359: }
360:
361:
373: public void setItemLabelGenerator(XYItemLabelGenerator generator) {
374: this.itemLabelGenerator = generator;
375: fireChangeEvent();
376: }
377:
378:
385: public void setSeriesItemLabelGenerator(int series,
386: XYItemLabelGenerator generator) {
387: this.itemLabelGeneratorList.set(series, generator);
388: fireChangeEvent();
389: }
390:
391:
396: public XYItemLabelGenerator getBaseItemLabelGenerator() {
397: return this.baseItemLabelGenerator;
398: }
399:
400:
406: public void setBaseItemLabelGenerator(XYItemLabelGenerator generator) {
407: this.baseItemLabelGenerator = generator;
408: fireChangeEvent();
409: }
410:
411:
412:
413:
423: public XYToolTipGenerator getToolTipGenerator(int series, int item) {
424:
425: if (this.toolTipGenerator != null) {
426: return this.toolTipGenerator;
427: }
428:
429:
430: XYToolTipGenerator generator
431: = (XYToolTipGenerator) this.toolTipGeneratorList.get(series);
432: if (generator == null) {
433: generator = this.baseToolTipGenerator;
434: }
435: return generator;
436: }
437:
438:
451: public XYToolTipGenerator getToolTipGenerator() {
452: return this.toolTipGenerator;
453: }
454:
455:
467: public void setToolTipGenerator(XYToolTipGenerator generator) {
468: this.toolTipGenerator = generator;
469: fireChangeEvent();
470: }
471:
472:
479: public XYToolTipGenerator getSeriesToolTipGenerator(int series) {
480: return (XYToolTipGenerator) this.toolTipGeneratorList.get(series);
481: }
482:
483:
490: public void setSeriesToolTipGenerator(int series,
491: XYToolTipGenerator generator) {
492: this.toolTipGeneratorList.set(series, generator);
493: fireChangeEvent();
494: }
495:
496:
503: public XYToolTipGenerator getBaseToolTipGenerator() {
504: return this.baseToolTipGenerator;
505: }
506:
507:
515: public void setBaseToolTipGenerator(XYToolTipGenerator generator) {
516: this.baseToolTipGenerator = generator;
517: fireChangeEvent();
518: }
519:
520:
521:
522:
527: public XYURLGenerator getURLGenerator() {
528: return this.urlGenerator;
529: }
530:
531:
537: public void setURLGenerator(XYURLGenerator urlGenerator) {
538: this.urlGenerator = urlGenerator;
539: fireChangeEvent();
540: }
541:
542:
549: public void addAnnotation(XYAnnotation annotation) {
550:
551: addAnnotation(annotation, Layer.FOREGROUND);
552: }
553:
554:
561: public void addAnnotation(XYAnnotation annotation, Layer layer) {
562: if (annotation == null) {
563: throw new IllegalArgumentException("Null 'annotation' argument.");
564: }
565: if (layer.equals(Layer.FOREGROUND)) {
566: this.foregroundAnnotations.add(annotation);
567: fireChangeEvent();
568: }
569: else if (layer.equals(Layer.BACKGROUND)) {
570: this.backgroundAnnotations.add(annotation);
571: fireChangeEvent();
572: }
573: else {
574:
575: throw new RuntimeException("Unknown layer.");
576: }
577: }
578:
588: public boolean removeAnnotation(XYAnnotation annotation) {
589: boolean removed = this.foregroundAnnotations.remove(annotation);
590: removed = removed & this.backgroundAnnotations.remove(annotation);
591: fireChangeEvent();
592: return removed;
593: }
594:
595:
599: public void removeAnnotations() {
600: this.foregroundAnnotations.clear();
601: this.backgroundAnnotations.clear();
602: fireChangeEvent();
603: }
604:
605:
611: public int getDefaultEntityRadius() {
612: return this.defaultEntityRadius;
613: }
614:
615:
621: public void setDefaultEntityRadius(int radius) {
622: this.defaultEntityRadius = radius;
623: }
624:
625:
632: public XYSeriesLabelGenerator getLegendItemLabelGenerator() {
633: return this.legendItemLabelGenerator;
634: }
635:
636:
644: public void setLegendItemLabelGenerator(XYSeriesLabelGenerator generator) {
645: if (generator == null) {
646: throw new IllegalArgumentException("Null 'generator' argument.");
647: }
648: this.legendItemLabelGenerator = generator;
649: fireChangeEvent();
650: }
651:
652:
659: public XYSeriesLabelGenerator getLegendItemToolTipGenerator() {
660: return this.legendItemToolTipGenerator;
661: }
662:
663:
671: public void setLegendItemToolTipGenerator(
672: XYSeriesLabelGenerator generator) {
673: this.legendItemToolTipGenerator = generator;
674: fireChangeEvent();
675: }
676:
677:
684: public XYSeriesLabelGenerator getLegendItemURLGenerator() {
685: return this.legendItemURLGenerator;
686: }
687:
688:
696: public void setLegendItemURLGenerator(XYSeriesLabelGenerator generator) {
697: this.legendItemURLGenerator = generator;
698: fireChangeEvent();
699: }
700:
701:
710: public Range findDomainBounds(XYDataset dataset) {
711: if (dataset != null) {
712: return DatasetUtilities.findDomainBounds(dataset, false);
713: }
714: else {
715: return null;
716: }
717: }
718:
719:
728: public Range findRangeBounds(XYDataset dataset) {
729: if (dataset != null) {
730: return DatasetUtilities.findRangeBounds(dataset, false);
731: }
732: else {
733: return null;
734: }
735: }
736:
737:
743: public LegendItemCollection getLegendItems() {
744: if (this.plot == null) {
745: return new LegendItemCollection();
746: }
747: LegendItemCollection result = new LegendItemCollection();
748: int index = this.plot.getIndexOf(this);
749: XYDataset dataset = this.plot.getDataset(index);
750: if (dataset != null) {
751: int seriesCount = dataset.getSeriesCount();
752: for (int i = 0; i < seriesCount; i++) {
753: if (isSeriesVisibleInLegend(i)) {
754: LegendItem item = getLegendItem(index, i);
755: if (item != null) {
756: result.add(item);
757: }
758: }
759: }
760:
761: }
762: return result;
763: }
764:
765:
774: public LegendItem getLegendItem(int datasetIndex, int series) {
775: LegendItem result = null;
776: XYPlot xyplot = getPlot();
777: if (xyplot != null) {
778: XYDataset dataset = xyplot.getDataset(datasetIndex);
779: if (dataset != null) {
780: String label = this.legendItemLabelGenerator.generateLabel(
781: dataset, series);
782: String description = label;
783: String toolTipText = null;
784: if (getLegendItemToolTipGenerator() != null) {
785: toolTipText = getLegendItemToolTipGenerator().generateLabel(
786: dataset, series);
787: }
788: String urlText = null;
789: if (getLegendItemURLGenerator() != null) {
790: urlText = getLegendItemURLGenerator().generateLabel(
791: dataset, series);
792: }
793: Shape shape = lookupSeriesShape(series);
794: Paint paint = lookupSeriesPaint(series);
795: Paint outlinePaint = lookupSeriesOutlinePaint(series);
796: Stroke outlineStroke = lookupSeriesOutlineStroke(series);
797: result = new LegendItem(label, description, toolTipText,
798: urlText, shape, paint, outlineStroke, outlinePaint);
799: result.setSeriesKey(dataset.getSeriesKey(series));
800: result.setSeriesIndex(series);
801: result.setDataset(dataset);
802: result.setDatasetIndex(datasetIndex);
803: }
804: }
805: return result;
806: }
807:
808:
819: public void fillDomainGridBand(Graphics2D g2, XYPlot plot, ValueAxis axis,
820: Rectangle2D dataArea, double start, double end) {
821:
822: double x1 = axis.valueToJava2D(start, dataArea,
823: plot.getDomainAxisEdge());
824: double x2 = axis.valueToJava2D(end, dataArea,
825: plot.getDomainAxisEdge());
826: Rectangle2D band;
827: if (plot.getOrientation() == PlotOrientation.VERTICAL) {
828: band = new Rectangle2D.Double(Math.min(x1, x2), dataArea.getMinY(),
829: Math.abs(x2 - x1), dataArea.getWidth());
830: }
831: else {
832: band = new Rectangle2D.Double(dataArea.getMinX(), Math.min(x1, x2),
833: dataArea.getWidth(), Math.abs(x2 - x1));
834: }
835: Paint paint = plot.getDomainTickBandPaint();
836:
837: if (paint != null) {
838: g2.setPaint(paint);
839: g2.fill(band);
840: }
841:
842: }
843:
844:
855: public void fillRangeGridBand(Graphics2D g2, XYPlot plot, ValueAxis axis,
856: Rectangle2D dataArea, double start, double end) {
857:
858: double y1 = axis.valueToJava2D(start, dataArea,
859: plot.getRangeAxisEdge());
860: double y2 = axis.valueToJava2D(end, dataArea, plot.getRangeAxisEdge());
861: Rectangle2D band;
862: if (plot.getOrientation() == PlotOrientation.VERTICAL) {
863: band = new Rectangle2D.Double(dataArea.getMinX(), Math.min(y1, y2),
864: dataArea.getWidth(), Math.abs(y2 - y1));
865: }
866: else {
867: band = new Rectangle2D.Double(Math.min(y1, y2), dataArea.getMinY(),
868: Math.abs(y2 - y1), dataArea.getHeight());
869: }
870: Paint paint = plot.getRangeTickBandPaint();
871:
872: if (paint != null) {
873: g2.setPaint(paint);
874: g2.fill(band);
875: }
876:
877: }
878:
879:
889: public void drawDomainGridLine(Graphics2D g2,
890: XYPlot plot,
891: ValueAxis axis,
892: Rectangle2D dataArea,
893: double value) {
894:
895: Range range = axis.getRange();
896: if (!range.contains(value)) {
897: return;
898: }
899:
900: PlotOrientation orientation = plot.getOrientation();
901: double v = axis.valueToJava2D(value, dataArea,
902: plot.getDomainAxisEdge());
903: Line2D line = null;
904: if (orientation == PlotOrientation.HORIZONTAL) {
905: line = new Line2D.Double(dataArea.getMinX(), v,
906: dataArea.getMaxX(), v);
907: }
908: else if (orientation == PlotOrientation.VERTICAL) {
909: line = new Line2D.Double(v, dataArea.getMinY(), v,
910: dataArea.getMaxY());
911: }
912:
913: Paint paint = plot.getDomainGridlinePaint();
914: Stroke stroke = plot.getDomainGridlineStroke();
915: g2.setPaint(paint != null ? paint : Plot.DEFAULT_OUTLINE_PAINT);
916: g2.setStroke(stroke != null ? stroke : Plot.DEFAULT_OUTLINE_STROKE);
917: g2.draw(line);
918:
919: }
920:
921:
935: public void drawDomainLine(Graphics2D g2, XYPlot plot, ValueAxis axis,
936: Rectangle2D dataArea, double value, Paint paint, Stroke stroke) {
937:
938: Range range = axis.getRange();
939: if (!range.contains(value)) {
940: return;
941: }
942:
943: PlotOrientation orientation = plot.getOrientation();
944: Line2D line = null;
945: double v = axis.valueToJava2D(value, dataArea,
946: plot.getDomainAxisEdge());
947: if (orientation == PlotOrientation.HORIZONTAL) {
948: line = new Line2D.Double(dataArea.getMinX(), v, dataArea.getMaxX(),
949: v);
950: }
951: else if (orientation == PlotOrientation.VERTICAL) {
952: line = new Line2D.Double(v, dataArea.getMinY(), v,
953: dataArea.getMaxY());
954: }
955:
956: g2.setPaint(paint);
957: g2.setStroke(stroke);
958: g2.draw(line);
959:
960: }
961:
962:
974: public void drawRangeLine(Graphics2D g2,
975: XYPlot plot,
976: ValueAxis axis,
977: Rectangle2D dataArea,
978: double value,
979: Paint paint,
980: Stroke stroke) {
981:
982: Range range = axis.getRange();
983: if (!range.contains(value)) {
984: return;
985: }
986:
987: PlotOrientation orientation = plot.getOrientation();
988: Line2D line = null;
989: double v = axis.valueToJava2D(value, dataArea, plot.getRangeAxisEdge());
990: if (orientation == PlotOrientation.HORIZONTAL) {
991: line = new Line2D.Double(v, dataArea.getMinY(), v,
992: dataArea.getMaxY());
993: }
994: else if (orientation == PlotOrientation.VERTICAL) {
995: line = new Line2D.Double(dataArea.getMinX(), v,
996: dataArea.getMaxX(), v);
997: }
998:
999: g2.setPaint(paint);
1000: g2.setStroke(stroke);
1001: g2.draw(line);
1002:
1003: }
1004:
1005:
1014: public void drawDomainMarker(Graphics2D g2,
1015: XYPlot plot,
1016: ValueAxis domainAxis,
1017: Marker marker,
1018: Rectangle2D dataArea) {
1019:
1020: if (marker instanceof ValueMarker) {
1021: ValueMarker vm = (ValueMarker) marker;
1022: double value = vm.getValue();
1023: Range range = domainAxis.getRange();
1024: if (!range.contains(value)) {
1025: return;
1026: }
1027:
1028: double v = domainAxis.valueToJava2D(value, dataArea,
1029: plot.getDomainAxisEdge());
1030:
1031: PlotOrientation orientation = plot.getOrientation();
1032: Line2D line = null;
1033: if (orientation == PlotOrientation.HORIZONTAL) {
1034: line = new Line2D.Double(dataArea.getMinX(), v,
1035: dataArea.getMaxX(), v);
1036: }
1037: else if (orientation == PlotOrientation.VERTICAL) {
1038: line = new Line2D.Double(v, dataArea.getMinY(), v,
1039: dataArea.getMaxY());
1040: }
1041:
1042: final Composite originalComposite = g2.getComposite();
1043: g2.setComposite(AlphaComposite.getInstance(
1044: AlphaComposite.SRC_OVER, marker.getAlpha()));
1045: g2.setPaint(marker.getPaint());
1046: g2.setStroke(marker.getStroke());
1047: g2.draw(line);
1048:
1049: String label = marker.getLabel();
1050: RectangleAnchor anchor = marker.getLabelAnchor();
1051: if (label != null) {
1052: Font labelFont = marker.getLabelFont();
1053: g2.setFont(labelFont);
1054: g2.setPaint(marker.getLabelPaint());
1055: Point2D coordinates = calculateDomainMarkerTextAnchorPoint(
1056: g2, orientation, dataArea, line.getBounds2D(),
1057: marker.getLabelOffset(),
1058: LengthAdjustmentType.EXPAND, anchor);
1059: TextUtilities.drawAlignedString(label, g2,
1060: (float) coordinates.getX(), (float) coordinates.getY(),
1061: marker.getLabelTextAnchor());
1062: }
1063: g2.setComposite(originalComposite);
1064: }
1065: else if (marker instanceof IntervalMarker) {
1066: IntervalMarker im = (IntervalMarker) marker;
1067: double start = im.getStartValue();
1068: double end = im.getEndValue();
1069: Range range = domainAxis.getRange();
1070: if (!(range.intersects(start, end))) {
1071: return;
1072: }
1073:
1074: double start2d = domainAxis.valueToJava2D(start, dataArea,
1075: plot.getDomainAxisEdge());
1076: double end2d = domainAxis.valueToJava2D(end, dataArea,
1077: plot.getDomainAxisEdge());
1078: double low = Math.min(start2d, end2d);
1079: double high = Math.max(start2d, end2d);
1080:
1081: PlotOrientation orientation = plot.getOrientation();
1082: Rectangle2D rect = null;
1083: if (orientation == PlotOrientation.HORIZONTAL) {
1084:
1085: low = Math.max(low, dataArea.getMinY());
1086: high = Math.min(high, dataArea.getMaxY());
1087: rect = new Rectangle2D.Double(dataArea.getMinX(),
1088: low, dataArea.getWidth(),
1089: high - low);
1090: }
1091: else if (orientation == PlotOrientation.VERTICAL) {
1092:
1093: low = Math.max(low, dataArea.getMinX());
1094: high = Math.min(high, dataArea.getMaxX());
1095: rect = new Rectangle2D.Double(low,
1096: dataArea.getMinY(), high - low,
1097: dataArea.getHeight());
1098: }
1099:
1100: final Composite originalComposite = g2.getComposite();
1101: g2.setComposite(AlphaComposite.getInstance(
1102: AlphaComposite.SRC_OVER, marker.getAlpha()));
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:
1117:
1118: if (im.getOutlinePaint() != null && im.getOutlineStroke() != null) {
1119: if (orientation == PlotOrientation.VERTICAL) {
1120: Line2D line = new Line2D.Double();
1121: double y0 = dataArea.getMinY();
1122: double y1 = dataArea.getMaxY();
1123: g2.setPaint(im.getOutlinePaint());
1124: g2.setStroke(im.getOutlineStroke());
1125: if (range.contains(start)) {
1126: line.setLine(start2d, y0, start2d, y1);
1127: g2.draw(line);
1128: }
1129: if (range.contains(end)) {
1130: line.setLine(end2d, y0, end2d, y1);
1131: g2.draw(line);
1132: }
1133: }
1134: else {
1135: Line2D line = new Line2D.Double();
1136: double x0 = dataArea.getMinX();
1137: double x1 = dataArea.getMaxX();
1138: g2.setPaint(im.getOutlinePaint());
1139: g2.setStroke(im.getOutlineStroke());
1140: if (range.contains(start)) {
1141: line.setLine(x0, start2d, x1, start2d);
1142: g2.draw(line);
1143: }
1144: if (range.contains(end)) {
1145: line.setLine(x0, end2d, x1, end2d);
1146: g2.draw(line);
1147: }
1148: }
1149: }
1150:
1151: String label = marker.getLabel();
1152: RectangleAnchor anchor = marker.getLabelAnchor();
1153: if (label != null) {
1154: Font labelFont = marker.getLabelFont();
1155: g2.setFont(labelFont);
1156: g2.setPaint(marker.getLabelPaint());
1157: Point2D coordinates = calculateDomainMarkerTextAnchorPoint(
1158: g2, orientation, dataArea, rect,
1159: marker.getLabelOffset(), marker.getLabelOffsetType(),
1160: anchor);
1161: TextUtilities.drawAlignedString(label, g2,
1162: (float) coordinates.getX(), (float) coordinates.getY(),
1163: marker.getLabelTextAnchor());
1164: }
1165: g2.setComposite(originalComposite);
1166:
1167: }
1168:
1169: }
1170:
1171:
1184: protected Point2D calculateDomainMarkerTextAnchorPoint(Graphics2D g2,
1185: PlotOrientation orientation,
1186: Rectangle2D dataArea,
1187: Rectangle2D markerArea,
1188: RectangleInsets markerOffset,
1189: LengthAdjustmentType labelOffsetType,
1190: RectangleAnchor anchor) {
1191:
1192: Rectangle2D anchorRect = null;
1193: if (orientation == PlotOrientation.HORIZONTAL) {
1194: anchorRect = markerOffset.createAdjustedRectangle(markerArea,
1195: LengthAdjustmentType.CONTRACT, labelOffsetType);
1196: }
1197: else if (orientation == PlotOrientation.VERTICAL) {
1198: anchorRect = markerOffset.createAdjustedRectangle(markerArea,
1199: labelOffsetType, LengthAdjustmentType.CONTRACT);
1200: }
1201: return RectangleAnchor.coordinates(anchorRect, anchor);
1202:
1203: }
1204:
1205:
1214: public void drawRangeMarker(Graphics2D g2,
1215: XYPlot plot,
1216: ValueAxis rangeAxis,
1217: Marker marker,
1218: Rectangle2D dataArea) {
1219:
1220: if (marker instanceof ValueMarker) {
1221: ValueMarker vm = (ValueMarker) marker;
1222: double value = vm.getValue();
1223: Range range = rangeAxis.getRange();
1224: if (!range.contains(value)) {
1225: return;
1226: }
1227:
1228: double v = rangeAxis.valueToJava2D(value, dataArea,
1229: plot.getRangeAxisEdge());
1230: PlotOrientation orientation = plot.getOrientation();
1231: Line2D line = null;
1232: if (orientation == PlotOrientation.HORIZONTAL) {
1233: line = new Line2D.Double(v, dataArea.getMinY(), v,
1234: dataArea.getMaxY());
1235: }
1236: else if (orientation == PlotOrientation.VERTICAL) {
1237: line = new Line2D.Double(dataArea.getMinX(), v,
1238: dataArea.getMaxX(), v);
1239: }
1240:
1241: final Composite originalComposite = g2.getComposite();
1242: g2.setComposite(AlphaComposite.getInstance(
1243: AlphaComposite.SRC_OVER, marker.getAlpha()));
1244: g2.setPaint(marker.getPaint());
1245: g2.setStroke(marker.getStroke());
1246: g2.draw(line);
1247:
1248: String label = marker.getLabel();
1249: RectangleAnchor anchor = marker.getLabelAnchor();
1250: if (label != null) {
1251: Font labelFont = marker.getLabelFont();
1252: g2.setFont(labelFont);
1253: g2.setPaint(marker.getLabelPaint());
1254: Point2D coordinates = calculateRangeMarkerTextAnchorPoint(
1255: g2, orientation, dataArea, line.getBounds2D(),
1256: marker.getLabelOffset(),
1257: LengthAdjustmentType.EXPAND, anchor);
1258: TextUtilities.drawAlignedString(label, g2,
1259: (float) coordinates.getX(), (float) coordinates.getY(),
1260: marker.getLabelTextAnchor());
1261: }
1262: g2.setComposite(originalComposite);
1263: }
1264: else if (marker instanceof IntervalMarker) {
1265: IntervalMarker im = (IntervalMarker) marker;
1266: double start = im.getStartValue();
1267: double end = im.getEndValue();
1268: Range range = rangeAxis.getRange();
1269: if (!(range.intersects(start, end))) {
1270: return;
1271: }
1272:
1273: double start2d = rangeAxis.valueToJava2D(start, dataArea,
1274: plot.getRangeAxisEdge());
1275: double end2d = rangeAxis.valueToJava2D(end, dataArea,
1276: plot.getRangeAxisEdge());
1277: double low = Math.min(start2d, end2d);
1278: double high = Math.max(start2d, end2d);
1279:
1280: PlotOrientation orientation = plot.getOrientation();
1281: Rectangle2D rect = null;
1282: if (orientation == PlotOrientation.HORIZONTAL) {
1283:
1284: low = Math.max(low, dataArea.getMinX());
1285: high = Math.min(high, dataArea.getMaxX());
1286: rect = new Rectangle2D.Double(low,
1287: dataArea.getMinY(), high - low,
1288: dataArea.getHeight());
1289: }
1290: else if (orientation == PlotOrientation.VERTICAL) {
1291:
1292: low = Math.max(low, dataArea.getMinY());
1293: high = Math.min(high, dataArea.getMaxY());
1294: rect = new Rectangle2D.Double(dataArea.getMinX(),
1295: low, dataArea.getWidth(),
1296: high - low);
1297: }
1298:
1299: final Composite originalComposite = g2.getComposite();
1300: g2.setComposite(AlphaComposite.getInstance(
1301: AlphaComposite.SRC_OVER, marker.getAlpha()));
1302: Paint p = marker.getPaint();
1303: if (p instanceof GradientPaint) {
1304: GradientPaint gp = (GradientPaint) p;
1305: GradientPaintTransformer t = im.getGradientPaintTransformer();
1306: if (t != null) {
1307: gp = t.transform(gp, rect);
1308: }
1309: g2.setPaint(gp);
1310: }
1311: else {
1312: g2.setPaint(p);
1313: }
1314: g2.fill(rect);
1315:
1316:
1317: if (im.getOutlinePaint() != null && im.getOutlineStroke() != null) {
1318: if (orientation == PlotOrientation.VERTICAL) {
1319: Line2D line = new Line2D.Double();
1320: double x0 = dataArea.getMinX();
1321: double x1 = dataArea.getMaxX();
1322: g2.setPaint(im.getOutlinePaint());
1323: g2.setStroke(im.getOutlineStroke());
1324: if (range.contains(start)) {
1325: line.setLine(x0, start2d, x1, start2d);
1326: g2.draw(line);
1327: }
1328: if (range.contains(end)) {
1329: line.setLine(x0, end2d, x1, end2d);
1330: g2.draw(line);
1331: }
1332: }
1333: else {
1334: Line2D line = new Line2D.Double();
1335: double y0 = dataArea.getMinY();
1336: double y1 = dataArea.getMaxY();
1337: g2.setPaint(im.getOutlinePaint());
1338: g2.setStroke(im.getOutlineStroke());
1339: if (range.contains(start)) {
1340: line.setLine(start2d, y0, start2d, y1);
1341: g2.draw(line);
1342: }
1343: if (range.contains(end)) {
1344: line.setLine(end2d, y0, end2d, y1);
1345: g2.draw(line);
1346: }
1347: }
1348: }
1349:
1350: String label = marker.getLabel();
1351: RectangleAnchor anchor = marker.getLabelAnchor();
1352: if (label != null) {
1353: Font labelFont = marker.getLabelFont();
1354: g2.setFont(labelFont);
1355: g2.setPaint(marker.getLabelPaint());
1356: Point2D coordinates = calculateRangeMarkerTextAnchorPoint(
1357: g2, orientation, dataArea, rect,
1358: marker.getLabelOffset(), marker.getLabelOffsetType(),
1359: anchor);
1360: TextUtilities.drawAlignedString(label, g2,
1361: (float) coordinates.getX(), (float) coordinates.getY(),
1362: marker.getLabelTextAnchor());
1363: }
1364: g2.setComposite(originalComposite);
1365: }
1366: }
1367:
1368:
1381: private Point2D calculateRangeMarkerTextAnchorPoint(Graphics2D g2,
1382: PlotOrientation orientation,
1383: Rectangle2D dataArea,
1384: Rectangle2D markerArea,
1385: RectangleInsets markerOffset,
1386: LengthAdjustmentType labelOffsetForRange,
1387: RectangleAnchor anchor) {
1388:
1389: Rectangle2D anchorRect = null;
1390: if (orientation == PlotOrientation.HORIZONTAL) {
1391: anchorRect = markerOffset.createAdjustedRectangle(markerArea,
1392: labelOffsetForRange, LengthAdjustmentType.CONTRACT);
1393: }
1394: else if (orientation == PlotOrientation.VERTICAL) {
1395: anchorRect = markerOffset.createAdjustedRectangle(markerArea,
1396: LengthAdjustmentType.CONTRACT, labelOffsetForRange);
1397: }
1398: return RectangleAnchor.coordinates(anchorRect, anchor);
1399:
1400: }
1401:
1402:
1410: protected Object clone() throws CloneNotSupportedException {
1411: AbstractXYItemRenderer clone = (AbstractXYItemRenderer) super.clone();
1412:
1413:
1414: if (this.itemLabelGenerator != null
1415: && this.itemLabelGenerator instanceof PublicCloneable) {
1416: PublicCloneable pc = (PublicCloneable) this.itemLabelGenerator;
1417: clone.itemLabelGenerator = (XYItemLabelGenerator) pc.clone();
1418: }
1419: clone.itemLabelGeneratorList
1420: = (ObjectList) this.itemLabelGeneratorList.clone();
1421: if (this.baseItemLabelGenerator != null
1422: && this.baseItemLabelGenerator instanceof PublicCloneable) {
1423: PublicCloneable pc = (PublicCloneable) this.baseItemLabelGenerator;
1424: clone.baseItemLabelGenerator = (XYItemLabelGenerator) pc.clone();
1425: }
1426:
1427: if (this.toolTipGenerator != null
1428: && this.toolTipGenerator instanceof PublicCloneable) {
1429: PublicCloneable pc = (PublicCloneable) this.toolTipGenerator;
1430: clone.toolTipGenerator = (XYToolTipGenerator) pc.clone();
1431: }
1432: clone.toolTipGeneratorList
1433: = (ObjectList) this.toolTipGeneratorList.clone();
1434: if (this.baseToolTipGenerator != null
1435: && this.baseToolTipGenerator instanceof PublicCloneable) {
1436: PublicCloneable pc = (PublicCloneable) this.baseToolTipGenerator;
1437: clone.baseToolTipGenerator = (XYToolTipGenerator) pc.clone();
1438: }
1439:
1440: if (clone.legendItemLabelGenerator instanceof PublicCloneable) {
1441: clone.legendItemLabelGenerator = (XYSeriesLabelGenerator)
1442: ObjectUtilities.clone(this.legendItemLabelGenerator);
1443: }
1444: if (clone.legendItemToolTipGenerator instanceof PublicCloneable) {
1445: clone.legendItemToolTipGenerator = (XYSeriesLabelGenerator)
1446: ObjectUtilities.clone(this.legendItemToolTipGenerator);
1447: }
1448: if (clone.legendItemURLGenerator instanceof PublicCloneable) {
1449: clone.legendItemURLGenerator = (XYSeriesLabelGenerator)
1450: ObjectUtilities.clone(this.legendItemURLGenerator);
1451: }
1452:
1453: clone.foregroundAnnotations = (List) ObjectUtilities.deepClone(
1454: this.foregroundAnnotations);
1455: clone.backgroundAnnotations = (List) ObjectUtilities.deepClone(
1456: this.backgroundAnnotations);
1457:
1458: if (clone.legendItemLabelGenerator instanceof PublicCloneable) {
1459: clone.legendItemLabelGenerator = (XYSeriesLabelGenerator)
1460: ObjectUtilities.clone(this.legendItemLabelGenerator);
1461: }
1462: if (clone.legendItemToolTipGenerator instanceof PublicCloneable) {
1463: clone.legendItemToolTipGenerator = (XYSeriesLabelGenerator)
1464: ObjectUtilities.clone(this.legendItemToolTipGenerator);
1465: }
1466: if (clone.legendItemURLGenerator instanceof PublicCloneable) {
1467: clone.legendItemURLGenerator = (XYSeriesLabelGenerator)
1468: ObjectUtilities.clone(this.legendItemURLGenerator);
1469: }
1470:
1471: return clone;
1472: }
1473:
1474:
1481: public boolean equals(Object obj) {
1482: if (obj == this) {
1483: return true;
1484: }
1485: if (!(obj instanceof AbstractXYItemRenderer)) {
1486: return false;
1487: }
1488: AbstractXYItemRenderer that = (AbstractXYItemRenderer) obj;
1489: if (!ObjectUtilities.equal(this.itemLabelGenerator,
1490: that.itemLabelGenerator)) {
1491: return false;
1492: }
1493: if (!this.itemLabelGeneratorList.equals(that.itemLabelGeneratorList)) {
1494: return false;
1495: }
1496: if (!ObjectUtilities.equal(this.baseItemLabelGenerator,
1497: that.baseItemLabelGenerator)) {
1498: return false;
1499: }
1500: if (!ObjectUtilities.equal(this.toolTipGenerator,
1501: that.toolTipGenerator)) {
1502: return false;
1503: }
1504: if (!this.toolTipGeneratorList.equals(that.toolTipGeneratorList)) {
1505: return false;
1506: }
1507: if (!ObjectUtilities.equal(this.baseToolTipGenerator,
1508: that.baseToolTipGenerator)) {
1509: return false;
1510: }
1511: if (!ObjectUtilities.equal(this.urlGenerator, that.urlGenerator)) {
1512: return false;
1513: }
1514: if (!this.foregroundAnnotations.equals(that.foregroundAnnotations)) {
1515: return false;
1516: }
1517: if (!this.backgroundAnnotations.equals(that.backgroundAnnotations)) {
1518: return false;
1519: }
1520: if (this.defaultEntityRadius != that.defaultEntityRadius) {
1521: return false;
1522: }
1523: if (!ObjectUtilities.equal(this.legendItemLabelGenerator,
1524: that.legendItemLabelGenerator)) {
1525: return false;
1526: }
1527: if (!ObjectUtilities.equal(this.legendItemToolTipGenerator,
1528: that.legendItemToolTipGenerator)) {
1529: return false;
1530: }
1531: if (!ObjectUtilities.equal(this.legendItemURLGenerator,
1532: that.legendItemURLGenerator)) {
1533: return false;
1534: }
1535: return super.equals(obj);
1536: }
1537:
1538:
1543: public DrawingSupplier getDrawingSupplier() {
1544: DrawingSupplier result = null;
1545: XYPlot p = getPlot();
1546: if (p != null) {
1547: result = p.getDrawingSupplier();
1548: }
1549: return result;
1550: }
1551:
1552:
1570: protected void updateCrosshairValues(CrosshairState crosshairState,
1571: double x, double y, double transX, double transY,
1572: PlotOrientation orientation) {
1573: updateCrosshairValues(crosshairState, x, y, 0, 0, transX, transY,
1574: orientation);
1575: }
1576:
1577:
1595: protected void updateCrosshairValues(CrosshairState crosshairState,
1596: double x, double y, int domainAxisIndex, int rangeAxisIndex,
1597: double transX, double transY, PlotOrientation orientation) {
1598:
1599: if (orientation == null) {
1600: throw new IllegalArgumentException("Null 'orientation' argument.");
1601: }
1602:
1603: if (crosshairState != null) {
1604:
1605: if (this.plot.isDomainCrosshairLockedOnData()) {
1606: if (this.plot.isRangeCrosshairLockedOnData()) {
1607:
1608: crosshairState.updateCrosshairPoint(x, y, domainAxisIndex,
1609: rangeAxisIndex, transX, transY, orientation);
1610: }
1611: else {
1612:
1613: crosshairState.updateCrosshairX(x, domainAxisIndex);
1614: }
1615: }
1616: else {
1617: if (this.plot.isRangeCrosshairLockedOnData()) {
1618:
1619: crosshairState.updateCrosshairY(y, rangeAxisIndex);
1620: }
1621: }
1622: }
1623:
1624: }
1625:
1626:
1639: protected void drawItemLabel(Graphics2D g2, PlotOrientation orientation,
1640: XYDataset dataset, int series, int item, double x, double y,
1641: boolean negative) {
1642:
1643: XYItemLabelGenerator generator = getItemLabelGenerator(series, item);
1644: if (generator != null) {
1645: Font labelFont = getItemLabelFont(series, item);
1646: Paint paint = getItemLabelPaint(series, item);
1647: g2.setFont(labelFont);
1648: g2.setPaint(paint);
1649: String label = generator.generateLabel(dataset, series, item);
1650:
1651:
1652: ItemLabelPosition position = null;
1653: if (!negative) {
1654: position = getPositiveItemLabelPosition(series, item);
1655: }
1656: else {
1657: position = getNegativeItemLabelPosition(series, item);
1658: }
1659:
1660:
1661: Point2D anchorPoint = calculateLabelAnchorPoint(
1662: position.getItemLabelAnchor(), x, y, orientation);
1663: TextUtilities.drawRotatedString(label, g2,
1664: (float) anchorPoint.getX(), (float) anchorPoint.getY(),
1665: position.getTextAnchor(), position.getAngle(),
1666: position.getRotationAnchor());
1667: }
1668:
1669: }
1670:
1671:
1681: public void drawAnnotations(Graphics2D g2,
1682: Rectangle2D dataArea,
1683: ValueAxis domainAxis,
1684: ValueAxis rangeAxis,
1685: Layer layer,
1686: PlotRenderingInfo info) {
1687:
1688: Iterator iterator = null;
1689: if (layer.equals(Layer.FOREGROUND)) {
1690: iterator = this.foregroundAnnotations.iterator();
1691: }
1692: else if (layer.equals(Layer.BACKGROUND)) {
1693: iterator = this.backgroundAnnotations.iterator();
1694: }
1695: else {
1696:
1697: throw new RuntimeException("Unknown layer.");
1698: }
1699: while (iterator.hasNext()) {
1700: XYAnnotation annotation = (XYAnnotation) iterator.next();
1701: annotation.draw(g2, this.plot, dataArea, domainAxis, rangeAxis,
1702: 0, info);
1703: }
1704:
1705: }
1706:
1707:
1719: protected void addEntity(EntityCollection entities, Shape area,
1720: XYDataset dataset, int series, int item,
1721: double entityX, double entityY) {
1722: if (!getItemCreateEntity(series, item)) {
1723: return;
1724: }
1725: if (area == null) {
1726: area = new Ellipse2D.Double(entityX - this.defaultEntityRadius,
1727: entityY - this.defaultEntityRadius,
1728: this.defaultEntityRadius * 2, this.defaultEntityRadius * 2);
1729: }
1730: String tip = null;
1731: XYToolTipGenerator generator = getToolTipGenerator(series, item);
1732: if (generator != null) {
1733: tip = generator.generateToolTip(dataset, series, item);
1734: }
1735: String url = null;
1736: if (getURLGenerator() != null) {
1737: url = getURLGenerator().generateURL(dataset, series, item);
1738: }
1739: XYItemEntity entity = new XYItemEntity(area, dataset, series, item,
1740: tip, url);
1741: entities.add(entity);
1742: }
1743:
1744: }