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: notifyListeners(new RendererChangeEvent(this));
376: }
377:
378:
385: public void setSeriesItemLabelGenerator(int series,
386: XYItemLabelGenerator generator) {
387: this.itemLabelGeneratorList.set(series, generator);
388: notifyListeners(new RendererChangeEvent(this));
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: notifyListeners(new RendererChangeEvent(this));
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: notifyListeners(new RendererChangeEvent(this));
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: notifyListeners(new RendererChangeEvent(this));
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: notifyListeners(new RendererChangeEvent(this));
518: }
519:
520:
521:
522:
527: public XYURLGenerator getURLGenerator() {
528: return this.urlGenerator;
529: }
530:
531:
536: public void setURLGenerator(XYURLGenerator urlGenerator) {
537: this.urlGenerator = urlGenerator;
538: notifyListeners(new RendererChangeEvent(this));
539: }
540:
541:
548: public void addAnnotation(XYAnnotation annotation) {
549:
550: addAnnotation(annotation, Layer.FOREGROUND);
551: }
552:
553:
559: public void addAnnotation(XYAnnotation annotation, Layer layer) {
560: if (annotation == null) {
561: throw new IllegalArgumentException("Null 'annotation' argument.");
562: }
563: if (layer.equals(Layer.FOREGROUND)) {
564: this.foregroundAnnotations.add(annotation);
565: notifyListeners(new RendererChangeEvent(this));
566: }
567: else if (layer.equals(Layer.BACKGROUND)) {
568: this.backgroundAnnotations.add(annotation);
569: notifyListeners(new RendererChangeEvent(this));
570: }
571: else {
572:
573: throw new RuntimeException("Unknown layer.");
574: }
575: }
576:
586: public boolean removeAnnotation(XYAnnotation annotation) {
587: boolean removed = this.foregroundAnnotations.remove(annotation);
588: removed = removed & this.backgroundAnnotations.remove(annotation);
589: notifyListeners(new RendererChangeEvent(this));
590: return removed;
591: }
592:
593:
597: public void removeAnnotations() {
598: this.foregroundAnnotations.clear();
599: this.backgroundAnnotations.clear();
600: notifyListeners(new RendererChangeEvent(this));
601: }
602:
603:
609: public int getDefaultEntityRadius() {
610: return this.defaultEntityRadius;
611: }
612:
613:
619: public void setDefaultEntityRadius(int radius) {
620: this.defaultEntityRadius = radius;
621: }
622:
623:
630: public XYSeriesLabelGenerator getLegendItemLabelGenerator() {
631: return this.legendItemLabelGenerator;
632: }
633:
634:
642: public void setLegendItemLabelGenerator(XYSeriesLabelGenerator generator) {
643: if (generator == null) {
644: throw new IllegalArgumentException("Null 'generator' argument.");
645: }
646: this.legendItemLabelGenerator = generator;
647: notifyListeners(new RendererChangeEvent(this));
648: }
649:
650:
657: public XYSeriesLabelGenerator getLegendItemToolTipGenerator() {
658: return this.legendItemToolTipGenerator;
659: }
660:
661:
669: public void setLegendItemToolTipGenerator(
670: XYSeriesLabelGenerator generator) {
671: this.legendItemToolTipGenerator = generator;
672: notifyListeners(new RendererChangeEvent(this));
673: }
674:
675:
682: public XYSeriesLabelGenerator getLegendItemURLGenerator() {
683: return this.legendItemURLGenerator;
684: }
685:
686:
694: public void setLegendItemURLGenerator(XYSeriesLabelGenerator generator) {
695: this.legendItemURLGenerator = generator;
696: notifyListeners(new RendererChangeEvent(this));
697: }
698:
699:
708: public Range findDomainBounds(XYDataset dataset) {
709: if (dataset != null) {
710: return DatasetUtilities.findDomainBounds(dataset, false);
711: }
712: else {
713: return null;
714: }
715: }
716:
717:
726: public Range findRangeBounds(XYDataset dataset) {
727: if (dataset != null) {
728: return DatasetUtilities.findRangeBounds(dataset, false);
729: }
730: else {
731: return null;
732: }
733: }
734:
735:
741: public LegendItemCollection getLegendItems() {
742: if (this.plot == null) {
743: return new LegendItemCollection();
744: }
745: LegendItemCollection result = new LegendItemCollection();
746: int index = this.plot.getIndexOf(this);
747: XYDataset dataset = this.plot.getDataset(index);
748: if (dataset != null) {
749: int seriesCount = dataset.getSeriesCount();
750: for (int i = 0; i < seriesCount; i++) {
751: if (isSeriesVisibleInLegend(i)) {
752: LegendItem item = getLegendItem(index, i);
753: if (item != null) {
754: result.add(item);
755: }
756: }
757: }
758:
759: }
760: return result;
761: }
762:
763:
772: public LegendItem getLegendItem(int datasetIndex, int series) {
773: LegendItem result = null;
774: XYPlot xyplot = getPlot();
775: if (xyplot != null) {
776: XYDataset dataset = xyplot.getDataset(datasetIndex);
777: if (dataset != null) {
778: String label = this.legendItemLabelGenerator.generateLabel(
779: dataset, series);
780: String description = label;
781: String toolTipText = null;
782: if (getLegendItemToolTipGenerator() != null) {
783: toolTipText = getLegendItemToolTipGenerator().generateLabel(
784: dataset, series);
785: }
786: String urlText = null;
787: if (getLegendItemURLGenerator() != null) {
788: urlText = getLegendItemURLGenerator().generateLabel(
789: dataset, series);
790: }
791: Shape shape = lookupSeriesShape(series);
792: Paint paint = lookupSeriesPaint(series);
793: Paint outlinePaint = lookupSeriesOutlinePaint(series);
794: Stroke outlineStroke = lookupSeriesOutlineStroke(series);
795: result = new LegendItem(label, description, toolTipText,
796: urlText, shape, paint, outlineStroke, outlinePaint);
797: result.setSeriesKey(dataset.getSeriesKey(series));
798: result.setSeriesIndex(series);
799: result.setDataset(dataset);
800: result.setDatasetIndex(datasetIndex);
801: }
802: }
803: return result;
804: }
805:
806:
817: public void fillDomainGridBand(Graphics2D g2, XYPlot plot, ValueAxis axis,
818: Rectangle2D dataArea, double start, double end) {
819:
820: double x1 = axis.valueToJava2D(start, dataArea,
821: plot.getDomainAxisEdge());
822: double x2 = axis.valueToJava2D(end, dataArea,
823: plot.getDomainAxisEdge());
824: Rectangle2D band;
825: if (plot.getOrientation() == PlotOrientation.VERTICAL) {
826: band = new Rectangle2D.Double(Math.min(x1, x2), dataArea.getMinY(),
827: Math.abs(x2 - x1), dataArea.getWidth());
828: }
829: else {
830: band = new Rectangle2D.Double(dataArea.getMinX(), Math.min(x1, x2),
831: dataArea.getWidth(), Math.abs(x2 - x1));
832: }
833: Paint paint = plot.getDomainTickBandPaint();
834:
835: if (paint != null) {
836: g2.setPaint(paint);
837: g2.fill(band);
838: }
839:
840: }
841:
842:
853: public void fillRangeGridBand(Graphics2D g2, XYPlot plot, ValueAxis axis,
854: Rectangle2D dataArea, double start, double end) {
855:
856: double y1 = axis.valueToJava2D(start, dataArea,
857: plot.getRangeAxisEdge());
858: double y2 = axis.valueToJava2D(end, dataArea, plot.getRangeAxisEdge());
859: Rectangle2D band;
860: if (plot.getOrientation() == PlotOrientation.VERTICAL) {
861: band = new Rectangle2D.Double(dataArea.getMinX(), Math.min(y1, y2),
862: dataArea.getWidth(), Math.abs(y2 - y1));
863: }
864: else {
865: band = new Rectangle2D.Double(Math.min(y1, y2), dataArea.getMinY(),
866: Math.abs(y2 - y1), dataArea.getHeight());
867: }
868: Paint paint = plot.getRangeTickBandPaint();
869:
870: if (paint != null) {
871: g2.setPaint(paint);
872: g2.fill(band);
873: }
874:
875: }
876:
877:
887: public void drawDomainGridLine(Graphics2D g2,
888: XYPlot plot,
889: ValueAxis axis,
890: Rectangle2D dataArea,
891: double value) {
892:
893: Range range = axis.getRange();
894: if (!range.contains(value)) {
895: return;
896: }
897:
898: PlotOrientation orientation = plot.getOrientation();
899: double v = axis.valueToJava2D(value, dataArea,
900: plot.getDomainAxisEdge());
901: Line2D line = null;
902: if (orientation == PlotOrientation.HORIZONTAL) {
903: line = new Line2D.Double(dataArea.getMinX(), v,
904: dataArea.getMaxX(), v);
905: }
906: else if (orientation == PlotOrientation.VERTICAL) {
907: line = new Line2D.Double(v, dataArea.getMinY(), v,
908: dataArea.getMaxY());
909: }
910:
911: Paint paint = plot.getDomainGridlinePaint();
912: Stroke stroke = plot.getDomainGridlineStroke();
913: g2.setPaint(paint != null ? paint : Plot.DEFAULT_OUTLINE_PAINT);
914: g2.setStroke(stroke != null ? stroke : Plot.DEFAULT_OUTLINE_STROKE);
915: g2.draw(line);
916:
917: }
918:
919:
933: public void drawDomainLine(Graphics2D g2, XYPlot plot, ValueAxis axis,
934: Rectangle2D dataArea, double value, Paint paint, Stroke stroke) {
935:
936: Range range = axis.getRange();
937: if (!range.contains(value)) {
938: return;
939: }
940:
941: PlotOrientation orientation = plot.getOrientation();
942: Line2D line = null;
943: double v = axis.valueToJava2D(value, dataArea,
944: plot.getDomainAxisEdge());
945: if (orientation == PlotOrientation.HORIZONTAL) {
946: line = new Line2D.Double(dataArea.getMinX(), v, dataArea.getMaxX(),
947: v);
948: }
949: else if (orientation == PlotOrientation.VERTICAL) {
950: line = new Line2D.Double(v, dataArea.getMinY(), v,
951: dataArea.getMaxY());
952: }
953:
954: g2.setPaint(paint);
955: g2.setStroke(stroke);
956: g2.draw(line);
957:
958: }
959:
960:
972: public void drawRangeLine(Graphics2D g2,
973: XYPlot plot,
974: ValueAxis axis,
975: Rectangle2D dataArea,
976: double value,
977: Paint paint,
978: Stroke stroke) {
979:
980: Range range = axis.getRange();
981: if (!range.contains(value)) {
982: return;
983: }
984:
985: PlotOrientation orientation = plot.getOrientation();
986: Line2D line = null;
987: double v = axis.valueToJava2D(value, dataArea, plot.getRangeAxisEdge());
988: if (orientation == PlotOrientation.HORIZONTAL) {
989: line = new Line2D.Double(v, dataArea.getMinY(), v,
990: dataArea.getMaxY());
991: }
992: else if (orientation == PlotOrientation.VERTICAL) {
993: line = new Line2D.Double(dataArea.getMinX(), v,
994: dataArea.getMaxX(), v);
995: }
996:
997: g2.setPaint(paint);
998: g2.setStroke(stroke);
999: g2.draw(line);
1000:
1001: }
1002:
1003:
1012: public void drawDomainMarker(Graphics2D g2,
1013: XYPlot plot,
1014: ValueAxis domainAxis,
1015: Marker marker,
1016: Rectangle2D dataArea) {
1017:
1018: if (marker instanceof ValueMarker) {
1019: ValueMarker vm = (ValueMarker) marker;
1020: double value = vm.getValue();
1021: Range range = domainAxis.getRange();
1022: if (!range.contains(value)) {
1023: return;
1024: }
1025:
1026: double v = domainAxis.valueToJava2D(value, dataArea,
1027: plot.getDomainAxisEdge());
1028:
1029: PlotOrientation orientation = plot.getOrientation();
1030: Line2D line = null;
1031: if (orientation == PlotOrientation.HORIZONTAL) {
1032: line = new Line2D.Double(dataArea.getMinX(), v,
1033: dataArea.getMaxX(), v);
1034: }
1035: else if (orientation == PlotOrientation.VERTICAL) {
1036: line = new Line2D.Double(v, dataArea.getMinY(), v,
1037: dataArea.getMaxY());
1038: }
1039:
1040: final Composite originalComposite = g2.getComposite();
1041: g2.setComposite(AlphaComposite.getInstance(
1042: AlphaComposite.SRC_OVER, marker.getAlpha()));
1043: g2.setPaint(marker.getPaint());
1044: g2.setStroke(marker.getStroke());
1045: g2.draw(line);
1046:
1047: String label = marker.getLabel();
1048: RectangleAnchor anchor = marker.getLabelAnchor();
1049: if (label != null) {
1050: Font labelFont = marker.getLabelFont();
1051: g2.setFont(labelFont);
1052: g2.setPaint(marker.getLabelPaint());
1053: Point2D coordinates = calculateDomainMarkerTextAnchorPoint(
1054: g2, orientation, dataArea, line.getBounds2D(),
1055: marker.getLabelOffset(),
1056: LengthAdjustmentType.EXPAND, anchor);
1057: TextUtilities.drawAlignedString(label, g2,
1058: (float) coordinates.getX(), (float) coordinates.getY(),
1059: marker.getLabelTextAnchor());
1060: }
1061: g2.setComposite(originalComposite);
1062: }
1063: else if (marker instanceof IntervalMarker) {
1064: IntervalMarker im = (IntervalMarker) marker;
1065: double start = im.getStartValue();
1066: double end = im.getEndValue();
1067: Range range = domainAxis.getRange();
1068: if (!(range.intersects(start, end))) {
1069: return;
1070: }
1071:
1072: double start2d = domainAxis.valueToJava2D(start, dataArea,
1073: plot.getDomainAxisEdge());
1074: double end2d = domainAxis.valueToJava2D(end, dataArea,
1075: plot.getDomainAxisEdge());
1076: double low = Math.min(start2d, end2d);
1077: double high = Math.max(start2d, end2d);
1078:
1079: PlotOrientation orientation = plot.getOrientation();
1080: Rectangle2D rect = null;
1081: if (orientation == PlotOrientation.HORIZONTAL) {
1082:
1083: low = Math.max(low, dataArea.getMinY());
1084: high = Math.min(high, dataArea.getMaxY());
1085: rect = new Rectangle2D.Double(dataArea.getMinX(),
1086: low, dataArea.getWidth(),
1087: high - low);
1088: }
1089: else if (orientation == PlotOrientation.VERTICAL) {
1090:
1091: low = Math.max(low, dataArea.getMinX());
1092: high = Math.min(high, dataArea.getMaxX());
1093: rect = new Rectangle2D.Double(low,
1094: dataArea.getMinY(), high - low,
1095: dataArea.getHeight());
1096: }
1097:
1098: final Composite originalComposite = g2.getComposite();
1099: g2.setComposite(AlphaComposite.getInstance(
1100: AlphaComposite.SRC_OVER, marker.getAlpha()));
1101: Paint p = marker.getPaint();
1102: if (p instanceof GradientPaint) {
1103: GradientPaint gp = (GradientPaint) p;
1104: GradientPaintTransformer t = im.getGradientPaintTransformer();
1105: if (t != null) {
1106: gp = t.transform(gp, rect);
1107: }
1108: g2.setPaint(gp);
1109: }
1110: else {
1111: g2.setPaint(p);
1112: }
1113: g2.fill(rect);
1114:
1115:
1116: if (im.getOutlinePaint() != null && im.getOutlineStroke() != null) {
1117: if (orientation == PlotOrientation.VERTICAL) {
1118: Line2D line = new Line2D.Double();
1119: double y0 = dataArea.getMinY();
1120: double y1 = dataArea.getMaxY();
1121: g2.setPaint(im.getOutlinePaint());
1122: g2.setStroke(im.getOutlineStroke());
1123: if (range.contains(start)) {
1124: line.setLine(start2d, y0, start2d, y1);
1125: g2.draw(line);
1126: }
1127: if (range.contains(end)) {
1128: line.setLine(end2d, y0, end2d, y1);
1129: g2.draw(line);
1130: }
1131: }
1132: else {
1133: Line2D line = new Line2D.Double();
1134: double x0 = dataArea.getMinX();
1135: double x1 = dataArea.getMaxX();
1136: g2.setPaint(im.getOutlinePaint());
1137: g2.setStroke(im.getOutlineStroke());
1138: if (range.contains(start)) {
1139: line.setLine(x0, start2d, x1, start2d);
1140: g2.draw(line);
1141: }
1142: if (range.contains(end)) {
1143: line.setLine(x0, end2d, x1, end2d);
1144: g2.draw(line);
1145: }
1146: }
1147: }
1148:
1149: String label = marker.getLabel();
1150: RectangleAnchor anchor = marker.getLabelAnchor();
1151: if (label != null) {
1152: Font labelFont = marker.getLabelFont();
1153: g2.setFont(labelFont);
1154: g2.setPaint(marker.getLabelPaint());
1155: Point2D coordinates = calculateDomainMarkerTextAnchorPoint(
1156: g2, orientation, dataArea, rect,
1157: marker.getLabelOffset(), marker.getLabelOffsetType(),
1158: anchor);
1159: TextUtilities.drawAlignedString(label, g2,
1160: (float) coordinates.getX(), (float) coordinates.getY(),
1161: marker.getLabelTextAnchor());
1162: }
1163: g2.setComposite(originalComposite);
1164:
1165: }
1166:
1167: }
1168:
1169:
1182: protected Point2D calculateDomainMarkerTextAnchorPoint(Graphics2D g2,
1183: PlotOrientation orientation,
1184: Rectangle2D dataArea,
1185: Rectangle2D markerArea,
1186: RectangleInsets markerOffset,
1187: LengthAdjustmentType labelOffsetType,
1188: RectangleAnchor anchor) {
1189:
1190: Rectangle2D anchorRect = null;
1191: if (orientation == PlotOrientation.HORIZONTAL) {
1192: anchorRect = markerOffset.createAdjustedRectangle(markerArea,
1193: LengthAdjustmentType.CONTRACT, labelOffsetType);
1194: }
1195: else if (orientation == PlotOrientation.VERTICAL) {
1196: anchorRect = markerOffset.createAdjustedRectangle(markerArea,
1197: labelOffsetType, LengthAdjustmentType.CONTRACT);
1198: }
1199: return RectangleAnchor.coordinates(anchorRect, anchor);
1200:
1201: }
1202:
1203:
1212: public void drawRangeMarker(Graphics2D g2,
1213: XYPlot plot,
1214: ValueAxis rangeAxis,
1215: Marker marker,
1216: Rectangle2D dataArea) {
1217:
1218: if (marker instanceof ValueMarker) {
1219: ValueMarker vm = (ValueMarker) marker;
1220: double value = vm.getValue();
1221: Range range = rangeAxis.getRange();
1222: if (!range.contains(value)) {
1223: return;
1224: }
1225:
1226: double v = rangeAxis.valueToJava2D(value, dataArea,
1227: plot.getRangeAxisEdge());
1228: PlotOrientation orientation = plot.getOrientation();
1229: Line2D line = null;
1230: if (orientation == PlotOrientation.HORIZONTAL) {
1231: line = new Line2D.Double(v, dataArea.getMinY(), v,
1232: dataArea.getMaxY());
1233: }
1234: else if (orientation == PlotOrientation.VERTICAL) {
1235: line = new Line2D.Double(dataArea.getMinX(), v,
1236: dataArea.getMaxX(), v);
1237: }
1238:
1239: final Composite originalComposite = g2.getComposite();
1240: g2.setComposite(AlphaComposite.getInstance(
1241: AlphaComposite.SRC_OVER, marker.getAlpha()));
1242: g2.setPaint(marker.getPaint());
1243: g2.setStroke(marker.getStroke());
1244: g2.draw(line);
1245:
1246: String label = marker.getLabel();
1247: RectangleAnchor anchor = marker.getLabelAnchor();
1248: if (label != null) {
1249: Font labelFont = marker.getLabelFont();
1250: g2.setFont(labelFont);
1251: g2.setPaint(marker.getLabelPaint());
1252: Point2D coordinates = calculateRangeMarkerTextAnchorPoint(
1253: g2, orientation, dataArea, line.getBounds2D(),
1254: marker.getLabelOffset(),
1255: LengthAdjustmentType.EXPAND, anchor);
1256: TextUtilities.drawAlignedString(label, g2,
1257: (float) coordinates.getX(), (float) coordinates.getY(),
1258: marker.getLabelTextAnchor());
1259: }
1260: g2.setComposite(originalComposite);
1261: }
1262: else if (marker instanceof IntervalMarker) {
1263: IntervalMarker im = (IntervalMarker) marker;
1264: double start = im.getStartValue();
1265: double end = im.getEndValue();
1266: Range range = rangeAxis.getRange();
1267: if (!(range.intersects(start, end))) {
1268: return;
1269: }
1270:
1271: double start2d = rangeAxis.valueToJava2D(start, dataArea,
1272: plot.getRangeAxisEdge());
1273: double end2d = rangeAxis.valueToJava2D(end, dataArea,
1274: plot.getRangeAxisEdge());
1275: double low = Math.min(start2d, end2d);
1276: double high = Math.max(start2d, end2d);
1277:
1278: PlotOrientation orientation = plot.getOrientation();
1279: Rectangle2D rect = null;
1280: if (orientation == PlotOrientation.HORIZONTAL) {
1281:
1282: low = Math.max(low, dataArea.getMinX());
1283: high = Math.min(high, dataArea.getMaxX());
1284: rect = new Rectangle2D.Double(low,
1285: dataArea.getMinY(), high - low,
1286: dataArea.getHeight());
1287: }
1288: else if (orientation == PlotOrientation.VERTICAL) {
1289:
1290: low = Math.max(low, dataArea.getMinY());
1291: high = Math.min(high, dataArea.getMaxY());
1292: rect = new Rectangle2D.Double(dataArea.getMinX(),
1293: low, dataArea.getWidth(),
1294: high - low);
1295: }
1296:
1297: final Composite originalComposite = g2.getComposite();
1298: g2.setComposite(AlphaComposite.getInstance(
1299: AlphaComposite.SRC_OVER, marker.getAlpha()));
1300: Paint p = marker.getPaint();
1301: if (p instanceof GradientPaint) {
1302: GradientPaint gp = (GradientPaint) p;
1303: GradientPaintTransformer t = im.getGradientPaintTransformer();
1304: if (t != null) {
1305: gp = t.transform(gp, rect);
1306: }
1307: g2.setPaint(gp);
1308: }
1309: else {
1310: g2.setPaint(p);
1311: }
1312: g2.fill(rect);
1313:
1314:
1315: if (im.getOutlinePaint() != null && im.getOutlineStroke() != null) {
1316: if (orientation == PlotOrientation.VERTICAL) {
1317: Line2D line = new Line2D.Double();
1318: double x0 = dataArea.getMinX();
1319: double x1 = dataArea.getMaxX();
1320: g2.setPaint(im.getOutlinePaint());
1321: g2.setStroke(im.getOutlineStroke());
1322: if (range.contains(start)) {
1323: line.setLine(x0, start2d, x1, start2d);
1324: g2.draw(line);
1325: }
1326: if (range.contains(end)) {
1327: line.setLine(x0, end2d, x1, end2d);
1328: g2.draw(line);
1329: }
1330: }
1331: else {
1332: Line2D line = new Line2D.Double();
1333: double y0 = dataArea.getMinY();
1334: double y1 = dataArea.getMaxY();
1335: g2.setPaint(im.getOutlinePaint());
1336: g2.setStroke(im.getOutlineStroke());
1337: if (range.contains(start)) {
1338: line.setLine(start2d, y0, start2d, y1);
1339: g2.draw(line);
1340: }
1341: if (range.contains(end)) {
1342: line.setLine(end2d, y0, end2d, y1);
1343: g2.draw(line);
1344: }
1345: }
1346: }
1347:
1348: String label = marker.getLabel();
1349: RectangleAnchor anchor = marker.getLabelAnchor();
1350: if (label != null) {
1351: Font labelFont = marker.getLabelFont();
1352: g2.setFont(labelFont);
1353: g2.setPaint(marker.getLabelPaint());
1354: Point2D coordinates = calculateRangeMarkerTextAnchorPoint(
1355: g2, orientation, dataArea, rect,
1356: marker.getLabelOffset(), marker.getLabelOffsetType(),
1357: anchor);
1358: TextUtilities.drawAlignedString(label, g2,
1359: (float) coordinates.getX(), (float) coordinates.getY(),
1360: marker.getLabelTextAnchor());
1361: }
1362: g2.setComposite(originalComposite);
1363: }
1364: }
1365:
1366:
1379: private Point2D calculateRangeMarkerTextAnchorPoint(Graphics2D g2,
1380: PlotOrientation orientation,
1381: Rectangle2D dataArea,
1382: Rectangle2D markerArea,
1383: RectangleInsets markerOffset,
1384: LengthAdjustmentType labelOffsetForRange,
1385: RectangleAnchor anchor) {
1386:
1387: Rectangle2D anchorRect = null;
1388: if (orientation == PlotOrientation.HORIZONTAL) {
1389: anchorRect = markerOffset.createAdjustedRectangle(markerArea,
1390: labelOffsetForRange, LengthAdjustmentType.CONTRACT);
1391: }
1392: else if (orientation == PlotOrientation.VERTICAL) {
1393: anchorRect = markerOffset.createAdjustedRectangle(markerArea,
1394: LengthAdjustmentType.CONTRACT, labelOffsetForRange);
1395: }
1396: return RectangleAnchor.coordinates(anchorRect, anchor);
1397:
1398: }
1399:
1400:
1408: protected Object clone() throws CloneNotSupportedException {
1409: AbstractXYItemRenderer clone = (AbstractXYItemRenderer) super.clone();
1410:
1411:
1412: if (this.itemLabelGenerator != null
1413: && this.itemLabelGenerator instanceof PublicCloneable) {
1414: PublicCloneable pc = (PublicCloneable) this.itemLabelGenerator;
1415: clone.itemLabelGenerator = (XYItemLabelGenerator) pc.clone();
1416: }
1417: clone.itemLabelGeneratorList
1418: = (ObjectList) this.itemLabelGeneratorList.clone();
1419: if (this.baseItemLabelGenerator != null
1420: && this.baseItemLabelGenerator instanceof PublicCloneable) {
1421: PublicCloneable pc = (PublicCloneable) this.baseItemLabelGenerator;
1422: clone.baseItemLabelGenerator = (XYItemLabelGenerator) pc.clone();
1423: }
1424:
1425: if (this.toolTipGenerator != null
1426: && this.toolTipGenerator instanceof PublicCloneable) {
1427: PublicCloneable pc = (PublicCloneable) this.toolTipGenerator;
1428: clone.toolTipGenerator = (XYToolTipGenerator) pc.clone();
1429: }
1430: clone.toolTipGeneratorList
1431: = (ObjectList) this.toolTipGeneratorList.clone();
1432: if (this.baseToolTipGenerator != null
1433: && this.baseToolTipGenerator instanceof PublicCloneable) {
1434: PublicCloneable pc = (PublicCloneable) this.baseToolTipGenerator;
1435: clone.baseToolTipGenerator = (XYToolTipGenerator) pc.clone();
1436: }
1437:
1438: if (clone.legendItemLabelGenerator instanceof PublicCloneable) {
1439: clone.legendItemLabelGenerator = (XYSeriesLabelGenerator)
1440: ObjectUtilities.clone(this.legendItemLabelGenerator);
1441: }
1442: if (clone.legendItemToolTipGenerator instanceof PublicCloneable) {
1443: clone.legendItemToolTipGenerator = (XYSeriesLabelGenerator)
1444: ObjectUtilities.clone(this.legendItemToolTipGenerator);
1445: }
1446: if (clone.legendItemURLGenerator instanceof PublicCloneable) {
1447: clone.legendItemURLGenerator = (XYSeriesLabelGenerator)
1448: ObjectUtilities.clone(this.legendItemURLGenerator);
1449: }
1450:
1451: clone.foregroundAnnotations = (List) ObjectUtilities.deepClone(
1452: this.foregroundAnnotations);
1453: clone.backgroundAnnotations = (List) ObjectUtilities.deepClone(
1454: this.backgroundAnnotations);
1455:
1456: if (clone.legendItemLabelGenerator instanceof PublicCloneable) {
1457: clone.legendItemLabelGenerator = (XYSeriesLabelGenerator)
1458: ObjectUtilities.clone(this.legendItemLabelGenerator);
1459: }
1460: if (clone.legendItemToolTipGenerator instanceof PublicCloneable) {
1461: clone.legendItemToolTipGenerator = (XYSeriesLabelGenerator)
1462: ObjectUtilities.clone(this.legendItemToolTipGenerator);
1463: }
1464: if (clone.legendItemURLGenerator instanceof PublicCloneable) {
1465: clone.legendItemURLGenerator = (XYSeriesLabelGenerator)
1466: ObjectUtilities.clone(this.legendItemURLGenerator);
1467: }
1468:
1469: return clone;
1470: }
1471:
1472:
1479: public boolean equals(Object obj) {
1480: if (obj == this) {
1481: return true;
1482: }
1483: if (!(obj instanceof AbstractXYItemRenderer)) {
1484: return false;
1485: }
1486: AbstractXYItemRenderer that = (AbstractXYItemRenderer) obj;
1487: if (!ObjectUtilities.equal(this.itemLabelGenerator,
1488: that.itemLabelGenerator)) {
1489: return false;
1490: }
1491: if (!this.itemLabelGeneratorList.equals(that.itemLabelGeneratorList)) {
1492: return false;
1493: }
1494: if (!ObjectUtilities.equal(this.baseItemLabelGenerator,
1495: that.baseItemLabelGenerator)) {
1496: return false;
1497: }
1498: if (!ObjectUtilities.equal(this.toolTipGenerator,
1499: that.toolTipGenerator)) {
1500: return false;
1501: }
1502: if (!this.toolTipGeneratorList.equals(that.toolTipGeneratorList)) {
1503: return false;
1504: }
1505: if (!ObjectUtilities.equal(this.baseToolTipGenerator,
1506: that.baseToolTipGenerator)) {
1507: return false;
1508: }
1509: if (!ObjectUtilities.equal(this.urlGenerator, that.urlGenerator)) {
1510: return false;
1511: }
1512: if (!this.foregroundAnnotations.equals(that.foregroundAnnotations)) {
1513: return false;
1514: }
1515: if (!this.backgroundAnnotations.equals(that.backgroundAnnotations)) {
1516: return false;
1517: }
1518: if (this.defaultEntityRadius != that.defaultEntityRadius) {
1519: return false;
1520: }
1521: if (!ObjectUtilities.equal(this.legendItemLabelGenerator,
1522: that.legendItemLabelGenerator)) {
1523: return false;
1524: }
1525: if (!ObjectUtilities.equal(this.legendItemToolTipGenerator,
1526: that.legendItemToolTipGenerator)) {
1527: return false;
1528: }
1529: if (!ObjectUtilities.equal(this.legendItemURLGenerator,
1530: that.legendItemURLGenerator)) {
1531: return false;
1532: }
1533: return super.equals(obj);
1534: }
1535:
1536:
1541: public DrawingSupplier getDrawingSupplier() {
1542: DrawingSupplier result = null;
1543: XYPlot p = getPlot();
1544: if (p != null) {
1545: result = p.getDrawingSupplier();
1546: }
1547: return result;
1548: }
1549:
1550:
1568: protected void updateCrosshairValues(CrosshairState crosshairState,
1569: double x, double y, double transX, double transY,
1570: PlotOrientation orientation) {
1571: updateCrosshairValues(crosshairState, x, y, 0, 0, transX, transY,
1572: orientation);
1573: }
1574:
1575:
1593: protected void updateCrosshairValues(CrosshairState crosshairState,
1594: double x, double y, int domainAxisIndex, int rangeAxisIndex,
1595: double transX, double transY, PlotOrientation orientation) {
1596:
1597: if (orientation == null) {
1598: throw new IllegalArgumentException("Null 'orientation' argument.");
1599: }
1600:
1601: if (crosshairState != null) {
1602:
1603: if (this.plot.isDomainCrosshairLockedOnData()) {
1604: if (this.plot.isRangeCrosshairLockedOnData()) {
1605:
1606: crosshairState.updateCrosshairPoint(x, y, domainAxisIndex,
1607: rangeAxisIndex, transX, transY, orientation);
1608: }
1609: else {
1610:
1611: crosshairState.updateCrosshairX(x, domainAxisIndex);
1612: }
1613: }
1614: else {
1615: if (this.plot.isRangeCrosshairLockedOnData()) {
1616:
1617: crosshairState.updateCrosshairY(y, rangeAxisIndex);
1618: }
1619: }
1620: }
1621:
1622: }
1623:
1624:
1637: protected void drawItemLabel(Graphics2D g2, PlotOrientation orientation,
1638: XYDataset dataset, int series, int item, double x, double y,
1639: boolean negative) {
1640:
1641: XYItemLabelGenerator generator = getItemLabelGenerator(series, item);
1642: if (generator != null) {
1643: Font labelFont = getItemLabelFont(series, item);
1644: Paint paint = getItemLabelPaint(series, item);
1645: g2.setFont(labelFont);
1646: g2.setPaint(paint);
1647: String label = generator.generateLabel(dataset, series, item);
1648:
1649:
1650: ItemLabelPosition position = null;
1651: if (!negative) {
1652: position = getPositiveItemLabelPosition(series, item);
1653: }
1654: else {
1655: position = getNegativeItemLabelPosition(series, item);
1656: }
1657:
1658:
1659: Point2D anchorPoint = calculateLabelAnchorPoint(
1660: position.getItemLabelAnchor(), x, y, orientation);
1661: TextUtilities.drawRotatedString(label, g2,
1662: (float) anchorPoint.getX(), (float) anchorPoint.getY(),
1663: position.getTextAnchor(), position.getAngle(),
1664: position.getRotationAnchor());
1665: }
1666:
1667: }
1668:
1669:
1679: public void drawAnnotations(Graphics2D g2,
1680: Rectangle2D dataArea,
1681: ValueAxis domainAxis,
1682: ValueAxis rangeAxis,
1683: Layer layer,
1684: PlotRenderingInfo info) {
1685:
1686: Iterator iterator = null;
1687: if (layer.equals(Layer.FOREGROUND)) {
1688: iterator = this.foregroundAnnotations.iterator();
1689: }
1690: else if (layer.equals(Layer.BACKGROUND)) {
1691: iterator = this.backgroundAnnotations.iterator();
1692: }
1693: else {
1694:
1695: throw new RuntimeException("Unknown layer.");
1696: }
1697: while (iterator.hasNext()) {
1698: XYAnnotation annotation = (XYAnnotation) iterator.next();
1699: annotation.draw(g2, this.plot, dataArea, domainAxis, rangeAxis,
1700: 0, info);
1701: }
1702:
1703: }
1704:
1705:
1717: protected void addEntity(EntityCollection entities, Shape area,
1718: XYDataset dataset, int series, int item,
1719: double entityX, double entityY) {
1720: if (!getItemCreateEntity(series, item)) {
1721: return;
1722: }
1723: if (area == null) {
1724: area = new Ellipse2D.Double(entityX - this.defaultEntityRadius,
1725: entityY - this.defaultEntityRadius,
1726: this.defaultEntityRadius * 2, this.defaultEntityRadius * 2);
1727: }
1728: String tip = null;
1729: XYToolTipGenerator generator = getToolTipGenerator(series, item);
1730: if (generator != null) {
1731: tip = generator.generateToolTip(dataset, series, item);
1732: }
1733: String url = null;
1734: if (getURLGenerator() != null) {
1735: url = getURLGenerator().generateURL(dataset, series, item);
1736: }
1737: XYItemEntity entity = new XYItemEntity(area, dataset, series, item,
1738: tip, url);
1739: entities.add(entity);
1740: }
1741:
1742: }