1:
197:
198: package ;
199:
200: import ;
201: import ;
202: import ;
203: import ;
204: import ;
205: import ;
206: import ;
207: import ;
208: import ;
209: import ;
210: import ;
211: import ;
212: import ;
213: import ;
214: import ;
215: import ;
216: import ;
217: import ;
218: import ;
219: import ;
220: import ;
221: import ;
222: import ;
223: import ;
224: import ;
225:
226: import ;
227: import ;
228: import ;
229: import ;
230: import ;
231: import ;
232: import ;
233: import ;
234: import ;
235: import ;
236: import ;
237: import ;
238: import ;
239: import ;
240: import ;
241: import ;
242: import ;
243: import ;
244: import ;
245: import ;
246: import ;
247: import ;
248: import ;
249: import ;
250: import ;
251: import ;
252: import ;
253: import ;
254: import ;
255: import ;
256: import ;
257:
258:
269: public class XYPlot extends Plot implements ValueAxisPlot,
270: Zoomable,
271: RendererChangeListener,
272: Cloneable, PublicCloneable,
273: Serializable {
274:
275:
276: private static final long serialVersionUID = 7044148245716569264L;
277:
278:
279: public static final Stroke DEFAULT_GRIDLINE_STROKE = new BasicStroke(0.5f,
280: BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0.0f,
281: new float[] {2.0f, 2.0f}, 0.0f);
282:
283:
284: public static final Paint DEFAULT_GRIDLINE_PAINT = Color.lightGray;
285:
286:
287: public static final boolean DEFAULT_CROSSHAIR_VISIBLE = false;
288:
289:
290: public static final Stroke DEFAULT_CROSSHAIR_STROKE
291: = DEFAULT_GRIDLINE_STROKE;
292:
293:
294: public static final Paint DEFAULT_CROSSHAIR_PAINT = Color.blue;
295:
296:
297: protected static ResourceBundle localizationResources
298: = ResourceBundle.getBundle(
299: "org.jfree.chart.plot.LocalizationBundle");
300:
301:
302: private PlotOrientation orientation;
303:
304:
305: private RectangleInsets axisOffset;
306:
307:
308: private ObjectList domainAxes;
309:
310:
311: private ObjectList domainAxisLocations;
312:
313:
314: private ObjectList rangeAxes;
315:
316:
317: private ObjectList rangeAxisLocations;
318:
319:
320: private ObjectList datasets;
321:
322:
323: private ObjectList renderers;
324:
325:
330: private Map datasetToDomainAxisMap;
331:
332:
337: private Map datasetToRangeAxisMap;
338:
339:
340: private transient Point2D quadrantOrigin = new Point2D.Double(0.0, 0.0);
341:
342:
343: private transient Paint[] quadrantPaint
344: = new Paint[] {null, null, null, null};
345:
346:
347: private boolean domainGridlinesVisible;
348:
349:
350: private transient Stroke domainGridlineStroke;
351:
352:
353: private transient Paint domainGridlinePaint;
354:
355:
356: private boolean rangeGridlinesVisible;
357:
358:
359: private transient Stroke rangeGridlineStroke;
360:
361:
362: private transient Paint rangeGridlinePaint;
363:
364:
370: private boolean domainZeroBaselineVisible;
371:
372:
377: private transient Stroke domainZeroBaselineStroke;
378:
379:
384: private transient Paint domainZeroBaselinePaint;
385:
386:
390: private boolean rangeZeroBaselineVisible;
391:
392:
393: private transient Stroke rangeZeroBaselineStroke;
394:
395:
396: private transient Paint rangeZeroBaselinePaint;
397:
398:
399: private boolean domainCrosshairVisible;
400:
401:
402: private double domainCrosshairValue;
403:
404:
405: private transient Stroke domainCrosshairStroke;
406:
407:
408: private transient Paint domainCrosshairPaint;
409:
410:
414: private boolean domainCrosshairLockedOnData = true;
415:
416:
417: private boolean rangeCrosshairVisible;
418:
419:
420: private double rangeCrosshairValue;
421:
422:
423: private transient Stroke rangeCrosshairStroke;
424:
425:
426: private transient Paint rangeCrosshairPaint;
427:
428:
432: private boolean rangeCrosshairLockedOnData = true;
433:
434:
435: private Map foregroundDomainMarkers;
436:
437:
438: private Map backgroundDomainMarkers;
439:
440:
441: private Map foregroundRangeMarkers;
442:
443:
444: private Map backgroundRangeMarkers;
445:
446:
451: private List annotations;
452:
453:
454: private transient Paint domainTickBandPaint;
455:
456:
457: private transient Paint rangeTickBandPaint;
458:
459:
460: private AxisSpace fixedDomainAxisSpace;
461:
462:
463: private AxisSpace fixedRangeAxisSpace;
464:
465:
469: private DatasetRenderingOrder datasetRenderingOrder
470: = DatasetRenderingOrder.REVERSE;
471:
472:
476: private SeriesRenderingOrder seriesRenderingOrder
477: = SeriesRenderingOrder.REVERSE;
478:
479:
483: private int weight;
484:
485:
489: private LegendItemCollection fixedLegendItems;
490:
491:
495: public XYPlot() {
496: this(null, null, null, null);
497: }
498:
499:
510: public XYPlot(XYDataset dataset,
511: ValueAxis domainAxis,
512: ValueAxis rangeAxis,
513: XYItemRenderer renderer) {
514:
515: super();
516:
517: this.orientation = PlotOrientation.VERTICAL;
518: this.weight = 1;
519: this.axisOffset = RectangleInsets.ZERO_INSETS;
520:
521:
522: this.domainAxes = new ObjectList();
523: this.domainAxisLocations = new ObjectList();
524: this.foregroundDomainMarkers = new HashMap();
525: this.backgroundDomainMarkers = new HashMap();
526:
527: this.rangeAxes = new ObjectList();
528: this.rangeAxisLocations = new ObjectList();
529: this.foregroundRangeMarkers = new HashMap();
530: this.backgroundRangeMarkers = new HashMap();
531:
532: this.datasets = new ObjectList();
533: this.renderers = new ObjectList();
534:
535: this.datasetToDomainAxisMap = new TreeMap();
536: this.datasetToRangeAxisMap = new TreeMap();
537:
538: this.datasets.set(0, dataset);
539: if (dataset != null) {
540: dataset.addChangeListener(this);
541: }
542:
543: this.renderers.set(0, renderer);
544: if (renderer != null) {
545: renderer.setPlot(this);
546: renderer.addChangeListener(this);
547: }
548:
549: this.domainAxes.set(0, domainAxis);
550: this.mapDatasetToDomainAxis(0, 0);
551: if (domainAxis != null) {
552: domainAxis.setPlot(this);
553: domainAxis.addChangeListener(this);
554: }
555: this.domainAxisLocations.set(0, AxisLocation.BOTTOM_OR_LEFT);
556:
557: this.rangeAxes.set(0, rangeAxis);
558: this.mapDatasetToRangeAxis(0, 0);
559: if (rangeAxis != null) {
560: rangeAxis.setPlot(this);
561: rangeAxis.addChangeListener(this);
562: }
563: this.rangeAxisLocations.set(0, AxisLocation.BOTTOM_OR_LEFT);
564:
565: configureDomainAxes();
566: configureRangeAxes();
567:
568: this.domainGridlinesVisible = true;
569: this.domainGridlineStroke = DEFAULT_GRIDLINE_STROKE;
570: this.domainGridlinePaint = DEFAULT_GRIDLINE_PAINT;
571:
572: this.domainZeroBaselineVisible = false;
573: this.domainZeroBaselinePaint = Color.black;
574: this.domainZeroBaselineStroke = new BasicStroke(0.5f);
575:
576: this.rangeGridlinesVisible = true;
577: this.rangeGridlineStroke = DEFAULT_GRIDLINE_STROKE;
578: this.rangeGridlinePaint = DEFAULT_GRIDLINE_PAINT;
579:
580: this.rangeZeroBaselineVisible = false;
581: this.rangeZeroBaselinePaint = Color.black;
582: this.rangeZeroBaselineStroke = new BasicStroke(0.5f);
583:
584: this.domainCrosshairVisible = false;
585: this.domainCrosshairValue = 0.0;
586: this.domainCrosshairStroke = DEFAULT_CROSSHAIR_STROKE;
587: this.domainCrosshairPaint = DEFAULT_CROSSHAIR_PAINT;
588:
589: this.rangeCrosshairVisible = false;
590: this.rangeCrosshairValue = 0.0;
591: this.rangeCrosshairStroke = DEFAULT_CROSSHAIR_STROKE;
592: this.rangeCrosshairPaint = DEFAULT_CROSSHAIR_PAINT;
593:
594: this.annotations = new java.util.ArrayList();
595:
596: }
597:
598:
603: public String getPlotType() {
604: return localizationResources.getString("XY_Plot");
605: }
606:
607:
614: public PlotOrientation getOrientation() {
615: return this.orientation;
616: }
617:
618:
626: public void setOrientation(PlotOrientation orientation) {
627: if (orientation == null) {
628: throw new IllegalArgumentException("Null 'orientation' argument.");
629: }
630: if (orientation != this.orientation) {
631: this.orientation = orientation;
632: notifyListeners(new PlotChangeEvent(this));
633: }
634: }
635:
636:
643: public RectangleInsets getAxisOffset() {
644: return this.axisOffset;
645: }
646:
647:
655: public void setAxisOffset(RectangleInsets offset) {
656: if (offset == null) {
657: throw new IllegalArgumentException("Null 'offset' argument.");
658: }
659: this.axisOffset = offset;
660: notifyListeners(new PlotChangeEvent(this));
661: }
662:
663:
673: public ValueAxis getDomainAxis() {
674: return getDomainAxis(0);
675: }
676:
677:
686: public ValueAxis getDomainAxis(int index) {
687: ValueAxis result = null;
688: if (index < this.domainAxes.size()) {
689: result = (ValueAxis) this.domainAxes.get(index);
690: }
691: if (result == null) {
692: Plot parent = getParent();
693: if (parent instanceof XYPlot) {
694: XYPlot xy = (XYPlot) parent;
695: result = xy.getDomainAxis(index);
696: }
697: }
698: return result;
699: }
700:
701:
710: public void setDomainAxis(ValueAxis axis) {
711: setDomainAxis(0, axis);
712: }
713:
714:
724: public void setDomainAxis(int index, ValueAxis axis) {
725: setDomainAxis(index, axis, true);
726: }
727:
728:
738: public void setDomainAxis(int index, ValueAxis axis, boolean notify) {
739: ValueAxis existing = getDomainAxis(index);
740: if (existing != null) {
741: existing.removeChangeListener(this);
742: }
743: if (axis != null) {
744: axis.setPlot(this);
745: }
746: this.domainAxes.set(index, axis);
747: if (axis != null) {
748: axis.configure();
749: axis.addChangeListener(this);
750: }
751: if (notify) {
752: notifyListeners(new PlotChangeEvent(this));
753: }
754: }
755:
756:
764: public void setDomainAxes(ValueAxis[] axes) {
765: for (int i = 0; i < axes.length; i++) {
766: setDomainAxis(i, axes[i], false);
767: }
768: notifyListeners(new PlotChangeEvent(this));
769: }
770:
771:
778: public AxisLocation getDomainAxisLocation() {
779: return (AxisLocation) this.domainAxisLocations.get(0);
780: }
781:
782:
790: public void setDomainAxisLocation(AxisLocation location) {
791:
792: setDomainAxisLocation(0, location, true);
793: }
794:
795:
804: public void setDomainAxisLocation(AxisLocation location, boolean notify) {
805:
806: setDomainAxisLocation(0, location, notify);
807: }
808:
809:
818: public RectangleEdge getDomainAxisEdge() {
819: return Plot.resolveDomainAxisLocation(getDomainAxisLocation(),
820: this.orientation);
821: }
822:
823:
830: public int getDomainAxisCount() {
831: return this.domainAxes.size();
832: }
833:
834:
840: public void clearDomainAxes() {
841: for (int i = 0; i < this.domainAxes.size(); i++) {
842: ValueAxis axis = (ValueAxis) this.domainAxes.get(i);
843: if (axis != null) {
844: axis.removeChangeListener(this);
845: }
846: }
847: this.domainAxes.clear();
848: notifyListeners(new PlotChangeEvent(this));
849: }
850:
851:
854: public void configureDomainAxes() {
855: for (int i = 0; i < this.domainAxes.size(); i++) {
856: ValueAxis axis = (ValueAxis) this.domainAxes.get(i);
857: if (axis != null) {
858: axis.configure();
859: }
860: }
861: }
862:
863:
874: public AxisLocation getDomainAxisLocation(int index) {
875: AxisLocation result = null;
876: if (index < this.domainAxisLocations.size()) {
877: result = (AxisLocation) this.domainAxisLocations.get(index);
878: }
879: if (result == null) {
880: result = AxisLocation.getOpposite(getDomainAxisLocation());
881: }
882: return result;
883: }
884:
885:
895: public void setDomainAxisLocation(int index, AxisLocation location) {
896:
897: setDomainAxisLocation(index, location, true);
898: }
899:
900:
914: public void setDomainAxisLocation(int index, AxisLocation location,
915: boolean notify) {
916:
917: if (index == 0 && location == null) {
918: throw new IllegalArgumentException(
919: "Null 'location' for index 0 not permitted.");
920: }
921: this.domainAxisLocations.set(index, location);
922: if (notify) {
923: notifyListeners(new PlotChangeEvent(this));
924: }
925: }
926:
927:
936: public RectangleEdge getDomainAxisEdge(int index) {
937: AxisLocation location = getDomainAxisLocation(index);
938: RectangleEdge result = Plot.resolveDomainAxisLocation(location,
939: this.orientation);
940: if (result == null) {
941: result = RectangleEdge.opposite(getDomainAxisEdge());
942: }
943: return result;
944: }
945:
946:
956: public ValueAxis getRangeAxis() {
957: return getRangeAxis(0);
958: }
959:
960:
969: public void setRangeAxis(ValueAxis axis) {
970:
971: if (axis != null) {
972: axis.setPlot(this);
973: }
974:
975:
976: ValueAxis existing = getRangeAxis();
977: if (existing != null) {
978: existing.removeChangeListener(this);
979: }
980:
981: this.rangeAxes.set(0, axis);
982: if (axis != null) {
983: axis.configure();
984: axis.addChangeListener(this);
985: }
986: notifyListeners(new PlotChangeEvent(this));
987:
988: }
989:
990:
997: public AxisLocation getRangeAxisLocation() {
998: return (AxisLocation) this.rangeAxisLocations.get(0);
999: }
1000:
1001:
1009: public void setRangeAxisLocation(AxisLocation location) {
1010:
1011: setRangeAxisLocation(0, location, true);
1012: }
1013:
1014:
1023: public void setRangeAxisLocation(AxisLocation location, boolean notify) {
1024:
1025: setRangeAxisLocation(0, location, notify);
1026: }
1027:
1028:
1036: public RectangleEdge getRangeAxisEdge() {
1037: return Plot.resolveRangeAxisLocation(getRangeAxisLocation(),
1038: this.orientation);
1039: }
1040:
1041:
1050: public ValueAxis getRangeAxis(int index) {
1051: ValueAxis result = null;
1052: if (index < this.rangeAxes.size()) {
1053: result = (ValueAxis) this.rangeAxes.get(index);
1054: }
1055: if (result == null) {
1056: Plot parent = getParent();
1057: if (parent instanceof XYPlot) {
1058: XYPlot xy = (XYPlot) parent;
1059: result = xy.getRangeAxis(index);
1060: }
1061: }
1062: return result;
1063: }
1064:
1065:
1074: public void setRangeAxis(int index, ValueAxis axis) {
1075: setRangeAxis(index, axis, true);
1076: }
1077:
1078:
1088: public void setRangeAxis(int index, ValueAxis axis, boolean notify) {
1089: ValueAxis existing = getRangeAxis(index);
1090: if (existing != null) {
1091: existing.removeChangeListener(this);
1092: }
1093: if (axis != null) {
1094: axis.setPlot(this);
1095: }
1096: this.rangeAxes.set(index, axis);
1097: if (axis != null) {
1098: axis.configure();
1099: axis.addChangeListener(this);
1100: }
1101: if (notify) {
1102: notifyListeners(new PlotChangeEvent(this));
1103: }
1104: }
1105:
1106:
1114: public void setRangeAxes(ValueAxis[] axes) {
1115: for (int i = 0; i < axes.length; i++) {
1116: setRangeAxis(i, axes[i], false);
1117: }
1118: notifyListeners(new PlotChangeEvent(this));
1119: }
1120:
1121:
1128: public int getRangeAxisCount() {
1129: return this.rangeAxes.size();
1130: }
1131:
1132:
1138: public void clearRangeAxes() {
1139: for (int i = 0; i < this.rangeAxes.size(); i++) {
1140: ValueAxis axis = (ValueAxis) this.rangeAxes.get(i);
1141: if (axis != null) {
1142: axis.removeChangeListener(this);
1143: }
1144: }
1145: this.rangeAxes.clear();
1146: notifyListeners(new PlotChangeEvent(this));
1147: }
1148:
1149:
1154: public void configureRangeAxes() {
1155: for (int i = 0; i < this.rangeAxes.size(); i++) {
1156: ValueAxis axis = (ValueAxis) this.rangeAxes.get(i);
1157: if (axis != null) {
1158: axis.configure();
1159: }
1160: }
1161: }
1162:
1163:
1174: public AxisLocation getRangeAxisLocation(int index) {
1175: AxisLocation result = null;
1176: if (index < this.rangeAxisLocations.size()) {
1177: result = (AxisLocation) this.rangeAxisLocations.get(index);
1178: }
1179: if (result == null) {
1180: result = AxisLocation.getOpposite(getRangeAxisLocation());
1181: }
1182: return result;
1183: }
1184:
1185:
1194: public void setRangeAxisLocation(int index, AxisLocation location) {
1195:
1196: setRangeAxisLocation(index, location, true);
1197: }
1198:
1199:
1213: public void setRangeAxisLocation(int index, AxisLocation location,
1214: boolean notify) {
1215:
1216: if (index == 0 && location == null) {
1217: throw new IllegalArgumentException(
1218: "Null 'location' for index 0 not permitted.");
1219: }
1220: this.rangeAxisLocations.set(index, location);
1221: if (notify) {
1222: notifyListeners(new PlotChangeEvent(this));
1223: }
1224: }
1225:
1226:
1236: public RectangleEdge getRangeAxisEdge(int index) {
1237: AxisLocation location = getRangeAxisLocation(index);
1238: RectangleEdge result = Plot.resolveRangeAxisLocation(location,
1239: this.orientation);
1240: if (result == null) {
1241: result = RectangleEdge.opposite(getRangeAxisEdge());
1242: }
1243: return result;
1244: }
1245:
1246:
1254: public XYDataset getDataset() {
1255: return getDataset(0);
1256: }
1257:
1258:
1267: public XYDataset getDataset(int index) {
1268: XYDataset result = null;
1269: if (this.datasets.size() > index) {
1270: result = (XYDataset) this.datasets.get(index);
1271: }
1272: return result;
1273: }
1274:
1275:
1284: public void setDataset(XYDataset dataset) {
1285: setDataset(0, dataset);
1286: }
1287:
1288:
1296: public void setDataset(int index, XYDataset dataset) {
1297: XYDataset existing = getDataset(index);
1298: if (existing != null) {
1299: existing.removeChangeListener(this);
1300: }
1301: this.datasets.set(index, dataset);
1302: if (dataset != null) {
1303: dataset.addChangeListener(this);
1304: }
1305:
1306:
1307: DatasetChangeEvent event = new DatasetChangeEvent(this, dataset);
1308: datasetChanged(event);
1309: }
1310:
1311:
1316: public int getDatasetCount() {
1317: return this.datasets.size();
1318: }
1319:
1320:
1328: public int indexOf(XYDataset dataset) {
1329: int result = -1;
1330: for (int i = 0; i < this.datasets.size(); i++) {
1331: if (dataset == this.datasets.get(i)) {
1332: result = i;
1333: break;
1334: }
1335: }
1336: return result;
1337: }
1338:
1339:
1348: public void mapDatasetToDomainAxis(int index, int axisIndex) {
1349: this.datasetToDomainAxisMap.put(new Integer(index),
1350: new Integer(axisIndex));
1351:
1352: datasetChanged(new DatasetChangeEvent(this, getDataset(index)));
1353: }
1354:
1355:
1364: public void mapDatasetToRangeAxis(int index, int axisIndex) {
1365: this.datasetToRangeAxisMap.put(new Integer(index),
1366: new Integer(axisIndex));
1367:
1368: datasetChanged(new DatasetChangeEvent(this, getDataset(index)));
1369: }
1370:
1371:
1378: public XYItemRenderer getRenderer() {
1379: return getRenderer(0);
1380: }
1381:
1382:
1391: public XYItemRenderer getRenderer(int index) {
1392: XYItemRenderer result = null;
1393: if (this.renderers.size() > index) {
1394: result = (XYItemRenderer) this.renderers.get(index);
1395: }
1396: return result;
1397:
1398: }
1399:
1400:
1409: public void setRenderer(XYItemRenderer renderer) {
1410: setRenderer(0, renderer);
1411: }
1412:
1413:
1422: public void setRenderer(int index, XYItemRenderer renderer) {
1423: setRenderer(index, renderer, true);
1424: }
1425:
1426:
1436: public void setRenderer(int index, XYItemRenderer renderer,
1437: boolean notify) {
1438: XYItemRenderer existing = getRenderer(index);
1439: if (existing != null) {
1440: existing.removeChangeListener(this);
1441: }
1442: this.renderers.set(index, renderer);
1443: if (renderer != null) {
1444: renderer.setPlot(this);
1445: renderer.addChangeListener(this);
1446: }
1447: configureDomainAxes();
1448: configureRangeAxes();
1449: if (notify) {
1450: notifyListeners(new PlotChangeEvent(this));
1451: }
1452: }
1453:
1454:
1460: public void setRenderers(XYItemRenderer[] renderers) {
1461: for (int i = 0; i < renderers.length; i++) {
1462: setRenderer(i, renderers[i], false);
1463: }
1464: notifyListeners(new PlotChangeEvent(this));
1465: }
1466:
1467:
1474: public DatasetRenderingOrder getDatasetRenderingOrder() {
1475: return this.datasetRenderingOrder;
1476: }
1477:
1478:
1488: public void setDatasetRenderingOrder(DatasetRenderingOrder order) {
1489: if (order == null) {
1490: throw new IllegalArgumentException("Null 'order' argument.");
1491: }
1492: this.datasetRenderingOrder = order;
1493: notifyListeners(new PlotChangeEvent(this));
1494: }
1495:
1496:
1503: public SeriesRenderingOrder getSeriesRenderingOrder() {
1504: return this.seriesRenderingOrder;
1505: }
1506:
1507:
1517: public void setSeriesRenderingOrder(SeriesRenderingOrder order) {
1518: if (order == null) {
1519: throw new IllegalArgumentException("Null 'order' argument.");
1520: }
1521: this.seriesRenderingOrder = order;
1522: notifyListeners(new PlotChangeEvent(this));
1523: }
1524:
1525:
1533: public int getIndexOf(XYItemRenderer renderer) {
1534: return this.renderers.indexOf(renderer);
1535: }
1536:
1537:
1546: public XYItemRenderer getRendererForDataset(XYDataset dataset) {
1547: XYItemRenderer result = null;
1548: for (int i = 0; i < this.datasets.size(); i++) {
1549: if (this.datasets.get(i) == dataset) {
1550: result = (XYItemRenderer) this.renderers.get(i);
1551: if (result == null) {
1552: result = getRenderer();
1553: }
1554: break;
1555: }
1556: }
1557: return result;
1558: }
1559:
1560:
1568: public int getWeight() {
1569: return this.weight;
1570: }
1571:
1572:
1580: public void setWeight(int weight) {
1581: this.weight = weight;
1582: notifyListeners(new PlotChangeEvent(this));
1583: }
1584:
1585:
1593: public boolean isDomainGridlinesVisible() {
1594: return this.domainGridlinesVisible;
1595: }
1596:
1597:
1608: public void setDomainGridlinesVisible(boolean visible) {
1609: if (this.domainGridlinesVisible != visible) {
1610: this.domainGridlinesVisible = visible;
1611: notifyListeners(new PlotChangeEvent(this));
1612: }
1613: }
1614:
1615:
1623: public Stroke getDomainGridlineStroke() {
1624: return this.domainGridlineStroke;
1625: }
1626:
1627:
1640: public void setDomainGridlineStroke(Stroke stroke) {
1641: if (stroke == null) {
1642: throw new IllegalArgumentException("Null 'stroke' argument.");
1643: }
1644: this.domainGridlineStroke = stroke;
1645: notifyListeners(new PlotChangeEvent(this));
1646: }
1647:
1648:
1656: public Paint getDomainGridlinePaint() {
1657: return this.domainGridlinePaint;
1658: }
1659:
1660:
1671: public void setDomainGridlinePaint(Paint paint) {
1672: if (paint == null) {
1673: throw new IllegalArgumentException("Null 'paint' argument.");
1674: }
1675: this.domainGridlinePaint = paint;
1676: notifyListeners(new PlotChangeEvent(this));
1677: }
1678:
1679:
1687: public boolean isRangeGridlinesVisible() {
1688: return this.rangeGridlinesVisible;
1689: }
1690:
1691:
1702: public void setRangeGridlinesVisible(boolean visible) {
1703: if (this.rangeGridlinesVisible != visible) {
1704: this.rangeGridlinesVisible = visible;
1705: notifyListeners(new PlotChangeEvent(this));
1706: }
1707: }
1708:
1709:
1717: public Stroke getRangeGridlineStroke() {
1718: return this.rangeGridlineStroke;
1719: }
1720:
1721:
1729: public void setRangeGridlineStroke(Stroke stroke) {
1730: if (stroke == null) {
1731: throw new IllegalArgumentException("Null 'stroke' argument.");
1732: }
1733: this.rangeGridlineStroke = stroke;
1734: notifyListeners(new PlotChangeEvent(this));
1735: }
1736:
1737:
1745: public Paint getRangeGridlinePaint() {
1746: return this.rangeGridlinePaint;
1747: }
1748:
1749:
1757: public void setRangeGridlinePaint(Paint paint) {
1758: if (paint == null) {
1759: throw new IllegalArgumentException("Null 'paint' argument.");
1760: }
1761: this.rangeGridlinePaint = paint;
1762: notifyListeners(new PlotChangeEvent(this));
1763: }
1764:
1765:
1775: public boolean isDomainZeroBaselineVisible() {
1776: return this.domainZeroBaselineVisible;
1777: }
1778:
1779:
1790: public void setDomainZeroBaselineVisible(boolean visible) {
1791: this.domainZeroBaselineVisible = visible;
1792: notifyListeners(new PlotChangeEvent(this));
1793: }
1794:
1795:
1804: public Stroke getDomainZeroBaselineStroke() {
1805: return this.domainZeroBaselineStroke;
1806: }
1807:
1808:
1818: public void setDomainZeroBaselineStroke(Stroke stroke) {
1819: if (stroke == null) {
1820: throw new IllegalArgumentException("Null 'stroke' argument.");
1821: }
1822: this.domainZeroBaselineStroke = stroke;
1823: notifyListeners(new PlotChangeEvent(this));
1824: }
1825:
1826:
1836: public Paint getDomainZeroBaselinePaint() {
1837: return this.domainZeroBaselinePaint;
1838: }
1839:
1840:
1850: public void setDomainZeroBaselinePaint(Paint paint) {
1851: if (paint == null) {
1852: throw new IllegalArgumentException("Null 'paint' argument.");
1853: }
1854: this.domainZeroBaselinePaint = paint;
1855: notifyListeners(new PlotChangeEvent(this));
1856: }
1857:
1858:
1866: public boolean isRangeZeroBaselineVisible() {
1867: return this.rangeZeroBaselineVisible;
1868: }
1869:
1870:
1879: public void setRangeZeroBaselineVisible(boolean visible) {
1880: this.rangeZeroBaselineVisible = visible;
1881: notifyListeners(new PlotChangeEvent(this));
1882: }
1883:
1884:
1891: public Stroke getRangeZeroBaselineStroke() {
1892: return this.rangeZeroBaselineStroke;
1893: }
1894:
1895:
1903: public void setRangeZeroBaselineStroke(Stroke stroke) {
1904: if (stroke == null) {
1905: throw new IllegalArgumentException("Null 'stroke' argument.");
1906: }
1907: this.rangeZeroBaselineStroke = stroke;
1908: notifyListeners(new PlotChangeEvent(this));
1909: }
1910:
1911:
1919: public Paint getRangeZeroBaselinePaint() {
1920: return this.rangeZeroBaselinePaint;
1921: }
1922:
1923:
1931: public void setRangeZeroBaselinePaint(Paint paint) {
1932: if (paint == null) {
1933: throw new IllegalArgumentException("Null 'paint' argument.");
1934: }
1935: this.rangeZeroBaselinePaint = paint;
1936: notifyListeners(new PlotChangeEvent(this));
1937: }
1938:
1939:
1947: public Paint getDomainTickBandPaint() {
1948: return this.domainTickBandPaint;
1949: }
1950:
1951:
1958: public void setDomainTickBandPaint(Paint paint) {
1959: this.domainTickBandPaint = paint;
1960: notifyListeners(new PlotChangeEvent(this));
1961: }
1962:
1963:
1971: public Paint getRangeTickBandPaint() {
1972: return this.rangeTickBandPaint;
1973: }
1974:
1975:
1982: public void setRangeTickBandPaint(Paint paint) {
1983: this.rangeTickBandPaint = paint;
1984: notifyListeners(new PlotChangeEvent(this));
1985: }
1986:
1987:
1995: public Point2D getQuadrantOrigin() {
1996: return this.quadrantOrigin;
1997: }
1998:
1999:
2007: public void setQuadrantOrigin(Point2D origin) {
2008: if (origin == null) {
2009: throw new IllegalArgumentException("Null 'origin' argument.");
2010: }
2011: this.quadrantOrigin = origin;
2012: notifyListeners(new PlotChangeEvent(this));
2013: }
2014:
2015:
2024: public Paint getQuadrantPaint(int index) {
2025: if (index < 0 || index > 3) {
2026: throw new IllegalArgumentException("The index value (" + index
2027: + ") should be in the range 0 to 3.");
2028: }
2029: return this.quadrantPaint[index];
2030: }
2031:
2032:
2041: public void setQuadrantPaint(int index, Paint paint) {
2042: if (index < 0 || index > 3) {
2043: throw new IllegalArgumentException("The index value (" + index
2044: + ") should be in the range 0 to 3.");
2045: }
2046: this.quadrantPaint[index] = paint;
2047: notifyListeners(new PlotChangeEvent(this));
2048: }
2049:
2050:
2062: public void addDomainMarker(Marker marker) {
2063:
2064: addDomainMarker(marker, Layer.FOREGROUND);
2065: }
2066:
2067:
2079: public void addDomainMarker(Marker marker, Layer layer) {
2080: addDomainMarker(0, marker, layer);
2081: }
2082:
2083:
2089: public void clearDomainMarkers() {
2090: if (this.backgroundDomainMarkers != null) {
2091: Set keys = this.backgroundDomainMarkers.keySet();
2092: Iterator iterator = keys.iterator();
2093: while (iterator.hasNext()) {
2094: Integer key = (Integer) iterator.next();
2095: clearDomainMarkers(key.intValue());
2096: }
2097: this.backgroundDomainMarkers.clear();
2098: }
2099: if (this.foregroundDomainMarkers != null) {
2100: Set keys = this.foregroundDomainMarkers.keySet();
2101: Iterator iterator = keys.iterator();
2102: while (iterator.hasNext()) {
2103: Integer key = (Integer) iterator.next();
2104: clearDomainMarkers(key.intValue());
2105: }
2106: this.foregroundDomainMarkers.clear();
2107: }
2108: notifyListeners(new PlotChangeEvent(this));
2109: }
2110:
2111:
2119: public void clearDomainMarkers(int index) {
2120: Integer key = new Integer(index);
2121: if (this.backgroundDomainMarkers != null) {
2122: Collection markers
2123: = (Collection) this.backgroundDomainMarkers.get(key);
2124: if (markers != null) {
2125: Iterator iterator = markers.iterator();
2126: while (iterator.hasNext()) {
2127: Marker m = (Marker) iterator.next();
2128: m.removeChangeListener(this);
2129: }
2130: markers.clear();
2131: }
2132: }
2133: if (this.foregroundRangeMarkers != null) {
2134: Collection markers
2135: = (Collection) this.foregroundDomainMarkers.get(key);
2136: if (markers != null) {
2137: Iterator iterator = markers.iterator();
2138: while (iterator.hasNext()) {
2139: Marker m = (Marker) iterator.next();
2140: m.removeChangeListener(this);
2141: }
2142: markers.clear();
2143: }
2144: }
2145: notifyListeners(new PlotChangeEvent(this));
2146: }
2147:
2148:
2163: public void addDomainMarker(int index, Marker marker, Layer layer) {
2164: if (marker == null) {
2165: throw new IllegalArgumentException("Null 'marker' not permitted.");
2166: }
2167: if (layer == null) {
2168: throw new IllegalArgumentException("Null 'layer' not permitted.");
2169: }
2170: Collection markers;
2171: if (layer == Layer.FOREGROUND) {
2172: markers = (Collection) this.foregroundDomainMarkers.get(
2173: new Integer(index));
2174: if (markers == null) {
2175: markers = new java.util.ArrayList();
2176: this.foregroundDomainMarkers.put(new Integer(index), markers);
2177: }
2178: markers.add(marker);
2179: }
2180: else if (layer == Layer.BACKGROUND) {
2181: markers = (Collection) this.backgroundDomainMarkers.get(
2182: new Integer(index));
2183: if (markers == null) {
2184: markers = new java.util.ArrayList();
2185: this.backgroundDomainMarkers.put(new Integer(index), markers);
2186: }
2187: markers.add(marker);
2188: }
2189: marker.addChangeListener(this);
2190: notifyListeners(new PlotChangeEvent(this));
2191: }
2192:
2193:
2204: public boolean removeDomainMarker(Marker marker) {
2205: return removeDomainMarker(marker, Layer.FOREGROUND);
2206: }
2207:
2208:
2220: public boolean removeDomainMarker(Marker marker, Layer layer) {
2221: return removeDomainMarker(0, marker, layer);
2222: }
2223:
2224:
2237: public boolean removeDomainMarker(int index, Marker marker, Layer layer) {
2238: ArrayList markers;
2239: if (layer == Layer.FOREGROUND) {
2240: markers = (ArrayList) this.foregroundDomainMarkers.get(new Integer(
2241: index));
2242: }
2243: else {
2244: markers = (ArrayList) this.backgroundDomainMarkers.get(new Integer(
2245: index));
2246: }
2247: boolean removed = markers.remove(marker);
2248: if (removed) {
2249: notifyListeners(new PlotChangeEvent(this));
2250: }
2251: return removed;
2252: }
2253:
2254:
2265: public void addRangeMarker(Marker marker) {
2266: addRangeMarker(marker, Layer.FOREGROUND);
2267: }
2268:
2269:
2281: public void addRangeMarker(Marker marker, Layer layer) {
2282: addRangeMarker(0, marker, layer);
2283: }
2284:
2285:
2291: public void clearRangeMarkers() {
2292: if (this.backgroundRangeMarkers != null) {
2293: Set keys = this.backgroundRangeMarkers.keySet();
2294: Iterator iterator = keys.iterator();
2295: while (iterator.hasNext()) {
2296: Integer key = (Integer) iterator.next();
2297: clearRangeMarkers(key.intValue());
2298: }
2299: this.backgroundRangeMarkers.clear();
2300: }
2301: if (this.foregroundRangeMarkers != null) {
2302: Set keys = this.foregroundRangeMarkers.keySet();
2303: Iterator iterator = keys.iterator();
2304: while (iterator.hasNext()) {
2305: Integer key = (Integer) iterator.next();
2306: clearRangeMarkers(key.intValue());
2307: }
2308: this.foregroundRangeMarkers.clear();
2309: }
2310: notifyListeners(new PlotChangeEvent(this));
2311: }
2312:
2313:
2327: public void addRangeMarker(int index, Marker marker, Layer layer) {
2328: Collection markers;
2329: if (layer == Layer.FOREGROUND) {
2330: markers = (Collection) this.foregroundRangeMarkers.get(
2331: new Integer(index));
2332: if (markers == null) {
2333: markers = new java.util.ArrayList();
2334: this.foregroundRangeMarkers.put(new Integer(index), markers);
2335: }
2336: markers.add(marker);
2337: }
2338: else if (layer == Layer.BACKGROUND) {
2339: markers = (Collection) this.backgroundRangeMarkers.get(
2340: new Integer(index));
2341: if (markers == null) {
2342: markers = new java.util.ArrayList();
2343: this.backgroundRangeMarkers.put(new Integer(index), markers);
2344: }
2345: markers.add(marker);
2346: }
2347: marker.addChangeListener(this);
2348: notifyListeners(new PlotChangeEvent(this));
2349: }
2350:
2351:
2357: public void clearRangeMarkers(int index) {
2358: Integer key = new Integer(index);
2359: if (this.backgroundRangeMarkers != null) {
2360: Collection markers
2361: = (Collection) this.backgroundRangeMarkers.get(key);
2362: if (markers != null) {
2363: Iterator iterator = markers.iterator();
2364: while (iterator.hasNext()) {
2365: Marker m = (Marker) iterator.next();
2366: m.removeChangeListener(this);
2367: }
2368: markers.clear();
2369: }
2370: }
2371: if (this.foregroundRangeMarkers != null) {
2372: Collection markers
2373: = (Collection) this.foregroundRangeMarkers.get(key);
2374: if (markers != null) {
2375: Iterator iterator = markers.iterator();
2376: while (iterator.hasNext()) {
2377: Marker m = (Marker) iterator.next();
2378: m.removeChangeListener(this);
2379: }
2380: markers.clear();
2381: }
2382: }
2383: notifyListeners(new PlotChangeEvent(this));
2384: }
2385:
2386:
2397: public boolean removeRangeMarker(Marker marker) {
2398: return removeRangeMarker(marker, Layer.FOREGROUND);
2399: }
2400:
2401:
2413: public boolean removeRangeMarker(Marker marker, Layer layer) {
2414: return removeRangeMarker(0, marker, layer);
2415: }
2416:
2417:
2430: public boolean removeRangeMarker(int index, Marker marker, Layer layer) {
2431: if (marker == null) {
2432: throw new IllegalArgumentException("Null 'marker' argument.");
2433: }
2434: ArrayList markers;
2435: if (layer == Layer.FOREGROUND) {
2436: markers = (ArrayList) this.foregroundRangeMarkers.get(new Integer(
2437: index));
2438: }
2439: else {
2440: markers = (ArrayList) this.backgroundRangeMarkers.get(new Integer(
2441: index));
2442: }
2443:
2444: boolean removed = markers.remove(marker);
2445: if (removed) {
2446: notifyListeners(new PlotChangeEvent(this));
2447: }
2448: return removed;
2449: }
2450:
2451:
2460: public void addAnnotation(XYAnnotation annotation) {
2461: if (annotation == null) {
2462: throw new IllegalArgumentException("Null 'annotation' argument.");
2463: }
2464: this.annotations.add(annotation);
2465: notifyListeners(new PlotChangeEvent(this));
2466: }
2467:
2468:
2479: public boolean removeAnnotation(XYAnnotation annotation) {
2480: if (annotation == null) {
2481: throw new IllegalArgumentException("Null 'annotation' argument.");
2482: }
2483: boolean removed = this.annotations.remove(annotation);
2484: if (removed) {
2485: notifyListeners(new PlotChangeEvent(this));
2486: }
2487: return removed;
2488: }
2489:
2490:
2499: public List getAnnotations() {
2500: return new ArrayList(this.annotations);
2501: }
2502:
2503:
2509: public void clearAnnotations() {
2510: this.annotations.clear();
2511: notifyListeners(new PlotChangeEvent(this));
2512: }
2513:
2514:
2522: protected AxisSpace calculateAxisSpace(Graphics2D g2,
2523: Rectangle2D plotArea) {
2524: AxisSpace space = new AxisSpace();
2525: space = calculateDomainAxisSpace(g2, plotArea, space);
2526: space = calculateRangeAxisSpace(g2, plotArea, space);
2527: return space;
2528: }
2529:
2530:
2539: protected AxisSpace calculateDomainAxisSpace(Graphics2D g2,
2540: Rectangle2D plotArea,
2541: AxisSpace space) {
2542:
2543: if (space == null) {
2544: space = new AxisSpace();
2545: }
2546:
2547:
2548: if (this.fixedDomainAxisSpace != null) {
2549: if (this.orientation == PlotOrientation.HORIZONTAL) {
2550: space.ensureAtLeast(this.fixedDomainAxisSpace.getLeft(),
2551: RectangleEdge.LEFT);
2552: space.ensureAtLeast(this.fixedDomainAxisSpace.getRight(),
2553: RectangleEdge.RIGHT);
2554: }
2555: else if (this.orientation == PlotOrientation.VERTICAL) {
2556: space.ensureAtLeast(this.fixedDomainAxisSpace.getTop(),
2557: RectangleEdge.TOP);
2558: space.ensureAtLeast(this.fixedDomainAxisSpace.getBottom(),
2559: RectangleEdge.BOTTOM);
2560: }
2561: }
2562: else {
2563:
2564: for (int i = 0; i < this.domainAxes.size(); i++) {
2565: Axis axis = (Axis) this.domainAxes.get(i);
2566: if (axis != null) {
2567: RectangleEdge edge = getDomainAxisEdge(i);
2568: space = axis.reserveSpace(g2, this, plotArea, edge, space);
2569: }
2570: }
2571: }
2572:
2573: return space;
2574:
2575: }
2576:
2577:
2586: protected AxisSpace calculateRangeAxisSpace(Graphics2D g2,
2587: Rectangle2D plotArea,
2588: AxisSpace space) {
2589:
2590: if (space == null) {
2591: space = new AxisSpace();
2592: }
2593:
2594:
2595: if (this.fixedRangeAxisSpace != null) {
2596: if (this.orientation == PlotOrientation.HORIZONTAL) {
2597: space.ensureAtLeast(this.fixedRangeAxisSpace.getTop(),
2598: RectangleEdge.TOP);
2599: space.ensureAtLeast(this.fixedRangeAxisSpace.getBottom(),
2600: RectangleEdge.BOTTOM);
2601: }
2602: else if (this.orientation == PlotOrientation.VERTICAL) {
2603: space.ensureAtLeast(this.fixedRangeAxisSpace.getLeft(),
2604: RectangleEdge.LEFT);
2605: space.ensureAtLeast(this.fixedRangeAxisSpace.getRight(),
2606: RectangleEdge.RIGHT);
2607: }
2608: }
2609: else {
2610:
2611: for (int i = 0; i < this.rangeAxes.size(); i++) {
2612: Axis axis = (Axis) this.rangeAxes.get(i);
2613: if (axis != null) {
2614: RectangleEdge edge = getRangeAxisEdge(i);
2615: space = axis.reserveSpace(g2, this, plotArea, edge, space);
2616: }
2617: }
2618: }
2619: return space;
2620:
2621: }
2622:
2623:
2635: public void draw(Graphics2D g2,
2636: Rectangle2D area,
2637: Point2D anchor,
2638: PlotState parentState,
2639: PlotRenderingInfo info) {
2640:
2641:
2642: boolean b1 = (area.getWidth() <= MINIMUM_WIDTH_TO_DRAW);
2643: boolean b2 = (area.getHeight() <= MINIMUM_HEIGHT_TO_DRAW);
2644: if (b1 || b2) {
2645: return;
2646: }
2647:
2648:
2649: if (info != null) {
2650: info.setPlotArea(area);
2651: }
2652:
2653:
2654: RectangleInsets insets = getInsets();
2655: insets.trim(area);
2656:
2657: AxisSpace space = calculateAxisSpace(g2, area);
2658: Rectangle2D dataArea = space.shrink(area, null);
2659: this.axisOffset.trim(dataArea);
2660:
2661: if (info != null) {
2662: info.setDataArea(dataArea);
2663: }
2664:
2665:
2666: drawBackground(g2, dataArea);
2667: Map axisStateMap = drawAxes(g2, area, dataArea, info);
2668:
2669: PlotOrientation orient = getOrientation();
2670:
2671:
2672:
2673: if (anchor != null && !dataArea.contains(anchor)) {
2674: anchor = null;
2675: }
2676: CrosshairState crosshairState = new CrosshairState();
2677: crosshairState.setCrosshairDistance(Double.POSITIVE_INFINITY);
2678: crosshairState.setAnchor(anchor);
2679:
2680: crosshairState.setAnchorX(Double.NaN);
2681: crosshairState.setAnchorY(Double.NaN);
2682: if (anchor != null) {
2683: ValueAxis domainAxis = getDomainAxis();
2684: if (domainAxis != null) {
2685: double x;
2686: if (orient == PlotOrientation.VERTICAL) {
2687: x = domainAxis.java2DToValue(anchor.getX(), dataArea,
2688: getDomainAxisEdge());
2689: }
2690: else {
2691: x = domainAxis.java2DToValue(anchor.getY(), dataArea,
2692: getDomainAxisEdge());
2693: }
2694: crosshairState.setAnchorX(x);
2695: }
2696: ValueAxis rangeAxis = getRangeAxis();
2697: if (rangeAxis != null) {
2698: double y;
2699: if (orient == PlotOrientation.VERTICAL) {
2700: y = rangeAxis.java2DToValue(anchor.getY(), dataArea,
2701: getRangeAxisEdge());
2702: }
2703: else {
2704: y = rangeAxis.java2DToValue(anchor.getX(), dataArea,
2705: getRangeAxisEdge());
2706: }
2707: crosshairState.setAnchorY(y);
2708: }
2709: }
2710: crosshairState.setCrosshairX(getDomainCrosshairValue());
2711: crosshairState.setCrosshairY(getRangeCrosshairValue());
2712: Shape originalClip = g2.getClip();
2713: Composite originalComposite = g2.getComposite();
2714:
2715: g2.clip(dataArea);
2716: g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
2717: getForegroundAlpha()));
2718:
2719: AxisState domainAxisState = (AxisState) axisStateMap.get(
2720: getDomainAxis());
2721: if (domainAxisState == null) {
2722: if (parentState != null) {
2723: domainAxisState = (AxisState) parentState.getSharedAxisStates()
2724: .get(getDomainAxis());
2725: }
2726: }
2727:
2728: AxisState rangeAxisState = (AxisState) axisStateMap.get(getRangeAxis());
2729: if (rangeAxisState == null) {
2730: if (parentState != null) {
2731: rangeAxisState = (AxisState) parentState.getSharedAxisStates()
2732: .get(getRangeAxis());
2733: }
2734: }
2735: if (domainAxisState != null) {
2736: drawDomainTickBands(g2, dataArea, domainAxisState.getTicks());
2737: }
2738: if (rangeAxisState != null) {
2739: drawRangeTickBands(g2, dataArea, rangeAxisState.getTicks());
2740: }
2741: if (domainAxisState != null) {
2742: drawDomainGridlines(g2, dataArea, domainAxisState.getTicks());
2743: drawZeroDomainBaseline(g2, dataArea);
2744: }
2745: if (rangeAxisState != null) {
2746: drawRangeGridlines(g2, dataArea, rangeAxisState.getTicks());
2747: drawZeroRangeBaseline(g2, dataArea);
2748: }
2749:
2750:
2751: for (int i = 0; i < this.renderers.size(); i++) {
2752: drawDomainMarkers(g2, dataArea, i, Layer.BACKGROUND);
2753: }
2754: for (int i = 0; i < this.renderers.size(); i++) {
2755: drawRangeMarkers(g2, dataArea, i, Layer.BACKGROUND);
2756: }
2757:
2758:
2759: boolean foundData = false;
2760: DatasetRenderingOrder order = getDatasetRenderingOrder();
2761: if (order == DatasetRenderingOrder.FORWARD) {
2762:
2763:
2764: int rendererCount = this.renderers.size();
2765: for (int i = 0; i < rendererCount; i++) {
2766: XYItemRenderer r = getRenderer(i);
2767: if (r != null) {
2768: ValueAxis domainAxis = getDomainAxisForDataset(i);
2769: ValueAxis rangeAxis = getRangeAxisForDataset(i);
2770: r.drawAnnotations(g2, dataArea, domainAxis, rangeAxis,
2771: Layer.BACKGROUND, info);
2772: }
2773: }
2774:
2775:
2776: for (int i = 0; i < getDatasetCount(); i++) {
2777: foundData = render(g2, dataArea, i, info, crosshairState)
2778: || foundData;
2779: }
2780:
2781:
2782: for (int i = 0; i < rendererCount; i++) {
2783: XYItemRenderer r = getRenderer(i);
2784: if (r != null) {
2785: ValueAxis domainAxis = getDomainAxisForDataset(i);
2786: ValueAxis rangeAxis = getRangeAxisForDataset(i);
2787: r.drawAnnotations(g2, dataArea, domainAxis, rangeAxis,
2788: Layer.FOREGROUND, info);
2789: }
2790: }
2791:
2792: }
2793: else if (order == DatasetRenderingOrder.REVERSE) {
2794:
2795:
2796: int rendererCount = this.renderers.size();
2797: for (int i = rendererCount - 1; i >= 0; i--) {
2798: XYItemRenderer r = getRenderer(i);
2799: if (i >= getDatasetCount()) {
2800: continue;
2801: }
2802: if (r != null) {
2803: ValueAxis domainAxis = getDomainAxisForDataset(i);
2804: ValueAxis rangeAxis = getRangeAxisForDataset(i);
2805: r.drawAnnotations(g2, dataArea, domainAxis, rangeAxis,
2806: Layer.BACKGROUND, info);
2807: }
2808: }
2809:
2810: for (int i = getDatasetCount() - 1; i >= 0; i--) {
2811: foundData = render(g2, dataArea, i, info, crosshairState)
2812: || foundData;
2813: }
2814:
2815:
2816: for (int i = rendererCount - 1; i >= 0; i--) {
2817: XYItemRenderer r = getRenderer(i);
2818: if (i >= getDatasetCount()) {
2819: continue;
2820: }
2821: if (r != null) {
2822: ValueAxis domainAxis = getDomainAxisForDataset(i);
2823: ValueAxis rangeAxis = getRangeAxisForDataset(i);
2824: r.drawAnnotations(g2, dataArea, domainAxis, rangeAxis,
2825: Layer.FOREGROUND, info);
2826: }
2827: }
2828:
2829: }
2830:
2831:
2832: int xAxisIndex = crosshairState.getDomainAxisIndex();
2833: ValueAxis xAxis = getDomainAxis(xAxisIndex);
2834: RectangleEdge xAxisEdge = getDomainAxisEdge(xAxisIndex);
2835: if (!this.domainCrosshairLockedOnData && anchor != null) {
2836: double xx;
2837: if (orient == PlotOrientation.VERTICAL) {
2838: xx = xAxis.java2DToValue(anchor.getX(), dataArea, xAxisEdge);
2839: }
2840: else {
2841: xx = xAxis.java2DToValue(anchor.getY(), dataArea, xAxisEdge);
2842: }
2843: crosshairState.setCrosshairX(xx);
2844: }
2845: setDomainCrosshairValue(crosshairState.getCrosshairX(), false);
2846: if (isDomainCrosshairVisible()) {
2847: double x = getDomainCrosshairValue();
2848: Paint paint = getDomainCrosshairPaint();
2849: Stroke stroke = getDomainCrosshairStroke();
2850: drawDomainCrosshair(g2, dataArea, orient, x, xAxis, stroke, paint);
2851: }
2852:
2853:
2854: int yAxisIndex = crosshairState.getRangeAxisIndex();
2855: ValueAxis yAxis = getRangeAxis(yAxisIndex);
2856: RectangleEdge yAxisEdge = getRangeAxisEdge(yAxisIndex);
2857: if (!this.rangeCrosshairLockedOnData && anchor != null) {
2858: double yy;
2859: if (orient == PlotOrientation.VERTICAL) {
2860: yy = yAxis.java2DToValue(anchor.getY(), dataArea, yAxisEdge);
2861: } else {
2862: yy = yAxis.java2DToValue(anchor.getX(), dataArea, yAxisEdge);
2863: }
2864: crosshairState.setCrosshairY(yy);
2865: }
2866: setRangeCrosshairValue(crosshairState.getCrosshairY(), false);
2867: if (isRangeCrosshairVisible()) {
2868: double y = getRangeCrosshairValue();
2869: Paint paint = getRangeCrosshairPaint();
2870: Stroke stroke = getRangeCrosshairStroke();
2871: drawRangeCrosshair(g2, dataArea, orient, y, yAxis, stroke, paint);
2872: }
2873:
2874: if (!foundData) {
2875: drawNoDataMessage(g2, dataArea);
2876: }
2877:
2878: for (int i = 0; i < this.renderers.size(); i++) {
2879: drawDomainMarkers(g2, dataArea, i, Layer.FOREGROUND);
2880: }
2881: for (int i = 0; i < this.renderers.size(); i++) {
2882: drawRangeMarkers(g2, dataArea, i, Layer.FOREGROUND);
2883: }
2884:
2885: drawAnnotations(g2, dataArea, info);
2886: g2.setClip(originalClip);
2887: g2.setComposite(originalComposite);
2888:
2889: drawOutline(g2, dataArea);
2890:
2891: }
2892:
2893:
2899: public void drawBackground(Graphics2D g2, Rectangle2D area) {
2900: fillBackground(g2, area, this.orientation);
2901: drawQuadrants(g2, area);
2902: drawBackgroundImage(g2, area);
2903: }
2904:
2905:
2914: protected void drawQuadrants(Graphics2D g2, Rectangle2D area) {
2915:
2916:
2917:
2918: boolean somethingToDraw = false;
2919:
2920: ValueAxis xAxis = getDomainAxis();
2921: double x = this.quadrantOrigin.getX();
2922: double xx = xAxis.valueToJava2D(x, area, getDomainAxisEdge());
2923:
2924: ValueAxis yAxis = getRangeAxis();
2925: double y = this.quadrantOrigin.getY();
2926: double yy = yAxis.valueToJava2D(y, area, getRangeAxisEdge());
2927:
2928: double xmin = xAxis.getLowerBound();
2929: double xxmin = xAxis.valueToJava2D(xmin, area, getDomainAxisEdge());
2930:
2931: double xmax = xAxis.getUpperBound();
2932: double xxmax = xAxis.valueToJava2D(xmax, area, getDomainAxisEdge());
2933:
2934: double ymin = yAxis.getLowerBound();
2935: double yymin = yAxis.valueToJava2D(ymin, area, getRangeAxisEdge());
2936:
2937: double ymax = yAxis.getUpperBound();
2938: double yymax = yAxis.valueToJava2D(ymax, area, getRangeAxisEdge());
2939:
2940: Rectangle2D[] r = new Rectangle2D[] {null, null, null, null};
2941: if (this.quadrantPaint[0] != null) {
2942: if (x > xmin && y < ymax) {
2943: if (this.orientation == PlotOrientation.HORIZONTAL) {
2944: r[0] = new Rectangle2D.Double(Math.min(yymax, yy),
2945: Math.min(xxmin, xx), Math.abs(yy - yymax),
2946: Math.abs(xx - xxmin)
2947: );
2948: }
2949: else {
2950: r[0] = new Rectangle2D.Double(Math.min(xxmin, xx),
2951: Math.min(yymax, yy), Math.abs(xx - xxmin),
2952: Math.abs(yy - yymax));
2953: }
2954: somethingToDraw = true;
2955: }
2956: }
2957: if (this.quadrantPaint[1] != null) {
2958: if (x < xmax && y < ymax) {
2959: if (this.orientation == PlotOrientation.HORIZONTAL) {
2960: r[1] = new Rectangle2D.Double(Math.min(yymax, yy),
2961: Math.min(xxmax, xx), Math.abs(yy - yymax),
2962: Math.abs(xx - xxmax));
2963: }
2964: else {
2965: r[1] = new Rectangle2D.Double(Math.min(xx, xxmax),
2966: Math.min(yymax, yy), Math.abs(xx - xxmax),
2967: Math.abs(yy - yymax));
2968: }
2969: somethingToDraw = true;
2970: }
2971: }
2972: if (this.quadrantPaint[2] != null) {
2973: if (x > xmin && y > ymin) {
2974: if (this.orientation == PlotOrientation.HORIZONTAL) {
2975: r[2] = new Rectangle2D.Double(Math.min(yymin, yy),
2976: Math.min(xxmin, xx), Math.abs(yy - yymin),
2977: Math.abs(xx - xxmin));
2978: }
2979: else {
2980: r[2] = new Rectangle2D.Double(Math.min(xxmin, xx),
2981: Math.min(yymin, yy), Math.abs(xx - xxmin),
2982: Math.abs(yy - yymin));
2983: }
2984: somethingToDraw = true;
2985: }
2986: }
2987: if (this.quadrantPaint[3] != null) {
2988: if (x < xmax && y > ymin) {
2989: if (this.orientation == PlotOrientation.HORIZONTAL) {
2990: r[3] = new Rectangle2D.Double(Math.min(yymin, yy),
2991: Math.min(xxmax, xx), Math.abs(yy - yymin),
2992: Math.abs(xx - xxmax));
2993: }
2994: else {
2995: r[3] = new Rectangle2D.Double(Math.min(xx, xxmax),
2996: Math.min(yymin, yy), Math.abs(xx - xxmax),
2997: Math.abs(yy - yymin));
2998: }
2999: somethingToDraw = true;
3000: }
3001: }
3002: if (somethingToDraw) {
3003: Composite originalComposite = g2.getComposite();
3004: g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
3005: getBackgroundAlpha()));
3006: for (int i = 0; i < 4; i++) {
3007: if (this.quadrantPaint[i] != null && r[i] != null) {
3008: g2.setPaint(this.quadrantPaint[i]);
3009: g2.fill(r[i]);
3010: }
3011: }
3012: g2.setComposite(originalComposite);
3013: }
3014: }
3015:
3016:
3025: public void drawDomainTickBands(Graphics2D g2, Rectangle2D dataArea,
3026: List ticks) {
3027: Paint bandPaint = getDomainTickBandPaint();
3028: if (bandPaint != null) {
3029: boolean fillBand = false;
3030: ValueAxis xAxis = getDomainAxis();
3031: double previous = xAxis.getLowerBound();
3032: Iterator iterator = ticks.iterator();
3033: while (iterator.hasNext()) {
3034: ValueTick tick = (ValueTick) iterator.next();
3035: double current = tick.getValue();
3036: if (fillBand) {
3037: getRenderer().fillDomainGridBand(g2, this, xAxis, dataArea,
3038: previous, current);
3039: }
3040: previous = current;
3041: fillBand = !fillBand;
3042: }
3043: double end = xAxis.getUpperBound();
3044: if (fillBand) {
3045: getRenderer().fillDomainGridBand(g2, this, xAxis, dataArea,
3046: previous, end);
3047: }
3048: }
3049: }
3050:
3051:
3060: public void drawRangeTickBands(Graphics2D g2, Rectangle2D dataArea,
3061: List ticks) {
3062: Paint bandPaint = getRangeTickBandPaint();
3063: if (bandPaint != null) {
3064: boolean fillBand = false;
3065: ValueAxis axis = getRangeAxis();
3066: double previous = axis.getLowerBound();
3067: Iterator iterator = ticks.iterator();
3068: while (iterator.hasNext()) {
3069: ValueTick tick = (ValueTick) iterator.next();
3070: double current = tick.getValue();
3071: if (fillBand) {
3072: getRenderer().fillRangeGridBand(g2, this, axis, dataArea,
3073: previous, current);
3074: }
3075: previous = current;
3076: fillBand = !fillBand;
3077: }
3078: double end = axis.getUpperBound();
3079: if (fillBand) {
3080: getRenderer().fillRangeGridBand(g2, this, axis, dataArea,
3081: previous, end);
3082: }
3083: }
3084: }
3085:
3086:
3097: protected Map drawAxes(Graphics2D g2,
3098: Rectangle2D plotArea,
3099: Rectangle2D dataArea,
3100: PlotRenderingInfo plotState) {
3101:
3102: AxisCollection axisCollection = new AxisCollection();
3103:
3104:
3105: for (int index = 0; index < this.domainAxes.size(); index++) {
3106: ValueAxis axis = (ValueAxis) this.domainAxes.get(index);
3107: if (axis != null) {
3108: axisCollection.add(axis, getDomainAxisEdge(index));
3109: }
3110: }
3111:
3112:
3113: for (int index = 0; index < this.rangeAxes.size(); index++) {
3114: ValueAxis yAxis = (ValueAxis) this.rangeAxes.get(index);
3115: if (yAxis != null) {
3116: axisCollection.add(yAxis, getRangeAxisEdge(index));
3117: }
3118: }
3119:
3120: Map axisStateMap = new HashMap();
3121:
3122:
3123: double cursor = dataArea.getMinY() - this.axisOffset.calculateTopOutset(
3124: dataArea.getHeight());
3125: Iterator iterator = axisCollection.getAxesAtTop().iterator();
3126: while (iterator.hasNext()) {
3127: ValueAxis axis = (ValueAxis) iterator.next();
3128: AxisState info = axis.draw(g2, cursor, plotArea, dataArea,
3129: RectangleEdge.TOP, plotState);
3130: cursor = info.getCursor();
3131: axisStateMap.put(axis, info);
3132: }
3133:
3134:
3135: cursor = dataArea.getMaxY()
3136: + this.axisOffset.calculateBottomOutset(dataArea.getHeight());
3137: iterator = axisCollection.getAxesAtBottom().iterator();
3138: while (iterator.hasNext()) {
3139: ValueAxis axis = (ValueAxis) iterator.next();
3140: AxisState info = axis.draw(g2, cursor, plotArea, dataArea,
3141: RectangleEdge.BOTTOM, plotState);
3142: cursor = info.getCursor();
3143: axisStateMap.put(axis, info);
3144: }
3145:
3146:
3147: cursor = dataArea.getMinX()
3148: - this.axisOffset.calculateLeftOutset(dataArea.getWidth());
3149: iterator = axisCollection.getAxesAtLeft().iterator();
3150: while (iterator.hasNext()) {
3151: ValueAxis axis = (ValueAxis) iterator.next();
3152: AxisState info = axis.draw(g2, cursor, plotArea, dataArea,
3153: RectangleEdge.LEFT, plotState);
3154: cursor = info.getCursor();
3155: axisStateMap.put(axis, info);
3156: }
3157:
3158:
3159: cursor = dataArea.getMaxX()
3160: + this.axisOffset.calculateRightOutset(dataArea.getWidth());
3161: iterator = axisCollection.getAxesAtRight().iterator();
3162: while (iterator.hasNext()) {
3163: ValueAxis axis = (ValueAxis) iterator.next();
3164: AxisState info = axis.draw(g2, cursor, plotArea, dataArea,
3165: RectangleEdge.RIGHT, plotState);
3166: cursor = info.getCursor();
3167: axisStateMap.put(axis, info);
3168: }
3169:
3170: return axisStateMap;
3171: }
3172:
3173:
3189: public boolean render(Graphics2D g2,
3190: Rectangle2D dataArea,
3191: int index,
3192: PlotRenderingInfo info,
3193: CrosshairState crosshairState) {
3194:
3195: boolean foundData = false;
3196: XYDataset dataset = getDataset(index);
3197: if (!DatasetUtilities.isEmptyOrNull(dataset)) {
3198: foundData = true;
3199: ValueAxis xAxis = getDomainAxisForDataset(index);
3200: ValueAxis yAxis = getRangeAxisForDataset(index);
3201: XYItemRenderer renderer = getRenderer(index);
3202: if (renderer == null) {
3203: renderer = getRenderer();
3204: if (renderer == null) {
3205: return foundData;
3206: }
3207: }
3208:
3209: XYItemRendererState state = renderer.initialise(g2, dataArea, this,
3210: dataset, info);
3211: int passCount = renderer.getPassCount();
3212:
3213: SeriesRenderingOrder seriesOrder = getSeriesRenderingOrder();
3214: if (seriesOrder == SeriesRenderingOrder.REVERSE) {
3215:
3216: for (int pass = 0; pass < passCount; pass++) {
3217: int seriesCount = dataset.getSeriesCount();
3218: for (int series = seriesCount - 1; series >= 0; series--) {
3219: int firstItem = 0;
3220: int lastItem = dataset.getItemCount(series) - 1;
3221: if (lastItem == -1) {
3222: continue;
3223: }
3224: if (state.getProcessVisibleItemsOnly()) {
3225: int[] itemBounds = RendererUtilities.findLiveItems(
3226: dataset, series, xAxis.getLowerBound(),
3227: xAxis.getUpperBound());
3228: firstItem = itemBounds[0];
3229: lastItem = itemBounds[1];
3230: }
3231: for (int item = firstItem; item <= lastItem; item++) {
3232: renderer.drawItem(g2, state, dataArea, info,
3233: this, xAxis, yAxis, dataset, series, item,
3234: crosshairState, pass);
3235: }
3236: }
3237: }
3238: }
3239: else {
3240:
3241: for (int pass = 0; pass < passCount; pass++) {
3242: int seriesCount = dataset.getSeriesCount();
3243: for (int series = 0; series < seriesCount; series++) {
3244: int firstItem = 0;
3245: int lastItem = dataset.getItemCount(series) - 1;
3246: if (state.getProcessVisibleItemsOnly()) {
3247: int[] itemBounds = RendererUtilities.findLiveItems(
3248: dataset, series, xAxis.getLowerBound(),
3249: xAxis.getUpperBound());
3250: firstItem = itemBounds[0];
3251: lastItem = itemBounds[1];
3252: }
3253: for (int item = firstItem; item <= lastItem; item++) {
3254: renderer.drawItem(g2, state, dataArea, info,
3255: this, xAxis, yAxis, dataset, series, item,
3256: crosshairState, pass);
3257: }
3258: }
3259: }
3260: }
3261: }
3262: return foundData;
3263: }
3264:
3265:
3272: public ValueAxis getDomainAxisForDataset(int index) {
3273:
3274: if (index < 0 || index >= getDatasetCount()) {
3275: throw new IllegalArgumentException("Index " + index
3276: + " out of bounds.");
3277: }
3278:
3279: ValueAxis valueAxis = null;
3280: Integer axisIndex = (Integer) this.datasetToDomainAxisMap.get(
3281: new Integer(index));
3282: if (axisIndex != null) {
3283: valueAxis = getDomainAxis(axisIndex.intValue());
3284: }
3285: else {
3286: valueAxis = getDomainAxis(0);
3287: }
3288: return valueAxis;
3289:
3290: }
3291:
3292:
3299: public ValueAxis getRangeAxisForDataset(int index) {
3300:
3301: if (index < 0 || index >= getDatasetCount()) {
3302: throw new IllegalArgumentException("Index " + index
3303: + " out of bounds.");
3304: }
3305:
3306: ValueAxis valueAxis = null;
3307: Integer axisIndex
3308: = (Integer) this.datasetToRangeAxisMap.get(new Integer(index));
3309: if (axisIndex != null) {
3310: valueAxis = getRangeAxis(axisIndex.intValue());
3311: }
3312: else {
3313: valueAxis = getRangeAxis(0);
3314: }
3315: return valueAxis;
3316:
3317: }
3318:
3319:
3328: protected void drawDomainGridlines(Graphics2D g2, Rectangle2D dataArea,
3329: List ticks) {
3330:
3331:
3332: if (getRenderer() == null) {
3333: return;
3334: }
3335:
3336:
3337: if (isDomainGridlinesVisible()) {
3338: Stroke gridStroke = getDomainGridlineStroke();
3339: Paint gridPaint = getDomainGridlinePaint();
3340: if ((gridStroke != null) && (gridPaint != null)) {
3341: Iterator iterator = ticks.iterator();
3342: while (iterator.hasNext()) {
3343: ValueTick tick = (ValueTick) iterator.next();
3344: getRenderer().drawDomainGridLine(g2, this, getDomainAxis(),
3345: dataArea, tick.getValue());
3346: }
3347: }
3348: }
3349: }
3350:
3351:
3361: protected void drawRangeGridlines(Graphics2D g2, Rectangle2D area,
3362: List ticks) {
3363:
3364:
3365: if (getRenderer() == null) {
3366: return;
3367: }
3368:
3369:
3370: if (isRangeGridlinesVisible()) {
3371: Stroke gridStroke = getRangeGridlineStroke();
3372: Paint gridPaint = getRangeGridlinePaint();
3373: ValueAxis axis = getRangeAxis();
3374: if (axis != null) {
3375: Iterator iterator = ticks.iterator();
3376: while (iterator.hasNext()) {
3377: ValueTick tick = (ValueTick) iterator.next();
3378: if (tick.getValue() != 0.0
3379: || !isRangeZeroBaselineVisible()) {
3380: getRenderer().drawRangeLine(g2, this, getRangeAxis(),
3381: area, tick.getValue(), gridPaint, gridStroke);
3382: }
3383: }
3384: }
3385: }
3386: }
3387:
3388:
3398: protected void drawZeroDomainBaseline(Graphics2D g2, Rectangle2D area) {
3399: if (isDomainZeroBaselineVisible()) {
3400: XYItemRenderer r = getRenderer();
3401:
3402:
3403:
3404: if (r instanceof AbstractXYItemRenderer) {
3405: AbstractXYItemRenderer renderer = (AbstractXYItemRenderer) r;
3406: renderer.drawDomainLine(g2, this, getDomainAxis(), area, 0.0,
3407: this.domainZeroBaselinePaint,
3408: this.domainZeroBaselineStroke);
3409: }
3410: }
3411: }
3412:
3413:
3421: protected void drawZeroRangeBaseline(Graphics2D g2, Rectangle2D area) {
3422: if (isRangeZeroBaselineVisible()) {
3423: getRenderer().drawRangeLine(g2, this, getRangeAxis(), area, 0.0,
3424: this.rangeZeroBaselinePaint, this.rangeZeroBaselineStroke);
3425: }
3426: }
3427:
3428:
3435: public void drawAnnotations(Graphics2D g2,
3436: Rectangle2D dataArea,
3437: PlotRenderingInfo info) {
3438:
3439: Iterator iterator = this.annotations.iterator();
3440: while (iterator.hasNext()) {
3441: XYAnnotation annotation = (XYAnnotation) iterator.next();
3442: ValueAxis xAxis = getDomainAxis();
3443: ValueAxis yAxis = getRangeAxis();
3444: annotation.draw(g2, this, dataArea, xAxis, yAxis, 0, info);
3445: }
3446:
3447: }
3448:
3449:
3458: protected void drawDomainMarkers(Graphics2D g2, Rectangle2D dataArea,
3459: int index, Layer layer) {
3460:
3461: XYItemRenderer r = getRenderer(index);
3462: if (r == null) {
3463: return;
3464: }
3465:
3466:
3467: if (index >= getDatasetCount()) {
3468: return;
3469: }
3470: Collection markers = getDomainMarkers(index, layer);
3471: ValueAxis axis = getDomainAxisForDataset(index);
3472: if (markers != null && axis != null) {
3473: Iterator iterator = markers.iterator();
3474: while (iterator.hasNext()) {
3475: Marker marker = (Marker) iterator.next();
3476: r.drawDomainMarker(g2, this, axis, marker, dataArea);
3477: }
3478: }
3479:
3480: }
3481:
3482:
3491: protected void drawRangeMarkers(Graphics2D g2, Rectangle2D dataArea,
3492: int index, Layer layer) {
3493:
3494: XYItemRenderer r = getRenderer(index);
3495: if (r == null) {
3496: return;
3497: }
3498:
3499:
3500: if (index >= getDatasetCount()) {
3501: return;
3502: }
3503: Collection markers = getRangeMarkers(index, layer);
3504: ValueAxis axis = getRangeAxisForDataset(index);
3505: if (markers != null && axis != null) {
3506: Iterator iterator = markers.iterator();
3507: while (iterator.hasNext()) {
3508: Marker marker = (Marker) iterator.next();
3509: r.drawRangeMarker(g2, this, axis, marker, dataArea);
3510: }
3511: }
3512: }
3513:
3514:
3523: public Collection getDomainMarkers(Layer layer) {
3524: return getDomainMarkers(0, layer);
3525: }
3526:
3527:
3536: public Collection getRangeMarkers(Layer layer) {
3537: return getRangeMarkers(0, layer);
3538: }
3539:
3540:
3551: public Collection getDomainMarkers(int index, Layer layer) {
3552: Collection result = null;
3553: Integer key = new Integer(index);
3554: if (layer == Layer.FOREGROUND) {
3555: result = (Collection) this.foregroundDomainMarkers.get(key);
3556: }
3557: else if (layer == Layer.BACKGROUND) {
3558: result = (Collection) this.backgroundDomainMarkers.get(key);
3559: }
3560: if (result != null) {
3561: result = Collections.unmodifiableCollection(result);
3562: }
3563: return result;
3564: }
3565:
3566:
3577: public Collection getRangeMarkers(int index, Layer layer) {
3578: Collection result = null;
3579: Integer key = new Integer(index);
3580: if (layer == Layer.FOREGROUND) {
3581: result = (Collection) this.foregroundRangeMarkers.get(key);
3582: }
3583: else if (layer == Layer.BACKGROUND) {
3584: result = (Collection) this.backgroundRangeMarkers.get(key);
3585: }
3586: if (result != null) {
3587: result = Collections.unmodifiableCollection(result);
3588: }
3589: return result;
3590: }
3591:
3592:
3602: protected void drawHorizontalLine(Graphics2D g2, Rectangle2D dataArea,
3603: double value, Stroke stroke,
3604: Paint paint) {
3605:
3606: ValueAxis axis = getRangeAxis();
3607: if (getOrientation() == PlotOrientation.HORIZONTAL) {
3608: axis = getDomainAxis();
3609: }
3610: if (axis.getRange().contains(value)) {
3611: double yy = axis.valueToJava2D(value, dataArea, RectangleEdge.LEFT);
3612: Line2D line = new Line2D.Double(dataArea.getMinX(), yy,
3613: dataArea.getMaxX(), yy);
3614: g2.setStroke(stroke);
3615: g2.setPaint(paint);
3616: g2.draw(line);
3617: }
3618:
3619: }
3620:
3621:
3634: protected void drawDomainCrosshair(Graphics2D g2, Rectangle2D dataArea,
3635: PlotOrientation orientation, double value, ValueAxis axis,
3636: Stroke stroke, Paint paint) {
3637:
3638: if (axis.getRange().contains(value)) {
3639: Line2D line = null;
3640: if (orientation == PlotOrientation.VERTICAL) {
3641: double xx = axis.valueToJava2D(value, dataArea,
3642: RectangleEdge.BOTTOM);
3643: line = new Line2D.Double(xx, dataArea.getMinY(), xx,
3644: dataArea.getMaxY());
3645: }
3646: else {
3647: double yy = axis.valueToJava2D(value, dataArea,
3648: RectangleEdge.LEFT);
3649: line = new Line2D.Double(dataArea.getMinX(), yy,
3650: dataArea.getMaxX(), yy);
3651: }
3652: g2.setStroke(stroke);
3653: g2.setPaint(paint);
3654: g2.draw(line);
3655: }
3656:
3657: }
3658:
3659:
3668: protected void drawVerticalLine(Graphics2D g2, Rectangle2D dataArea,
3669: double value, Stroke stroke, Paint paint) {
3670:
3671: ValueAxis axis = getDomainAxis();
3672: if (getOrientation() == PlotOrientation.HORIZONTAL) {
3673: axis = getRangeAxis();
3674: }
3675: if (axis.getRange().contains(value)) {
3676: double xx = axis.valueToJava2D(value, dataArea,
3677: RectangleEdge.BOTTOM);
3678: Line2D line = new Line2D.Double(xx, dataArea.getMinY(), xx,
3679: dataArea.getMaxY());
3680: g2.setStroke(stroke);
3681: g2.setPaint(paint);
3682: g2.draw(line);
3683: }
3684:
3685: }
3686:
3687:
3700: protected void drawRangeCrosshair(Graphics2D g2, Rectangle2D dataArea,
3701: PlotOrientation orientation, double value, ValueAxis axis,
3702: Stroke stroke, Paint paint) {
3703:
3704: if (axis.getRange().contains(value)) {
3705: Line2D line = null;
3706: if (orientation == PlotOrientation.HORIZONTAL) {
3707: double xx = axis.valueToJava2D(value, dataArea,
3708: RectangleEdge.BOTTOM);
3709: line = new Line2D.Double(xx, dataArea.getMinY(), xx,
3710: dataArea.getMaxY());
3711: }
3712: else {
3713: double yy = axis.valueToJava2D(value, dataArea,
3714: RectangleEdge.LEFT);
3715: line = new Line2D.Double(dataArea.getMinX(), yy,
3716: dataArea.getMaxX(), yy);
3717: }
3718: g2.setStroke(stroke);
3719: g2.setPaint(paint);
3720: g2.draw(line);
3721: }
3722:
3723: }
3724:
3725:
3732: public void handleClick(int x, int y, PlotRenderingInfo info) {
3733:
3734: Rectangle2D dataArea = info.getDataArea();
3735: if (dataArea.contains(x, y)) {
3736:
3737: ValueAxis da = getDomainAxis();
3738: if (da != null) {
3739: double hvalue = da.java2DToValue(x, info.getDataArea(),
3740: getDomainAxisEdge());
3741: setDomainCrosshairValue(hvalue);
3742: }
3743:
3744:
3745: ValueAxis ra = getRangeAxis();
3746: if (ra != null) {
3747: double vvalue = ra.java2DToValue(y, info.getDataArea(),
3748: getRangeAxisEdge());
3749: setRangeCrosshairValue(vvalue);
3750: }
3751: }
3752: }
3753:
3754:
3762: private List getDatasetsMappedToDomainAxis(Integer axisIndex) {
3763: if (axisIndex == null) {
3764: throw new IllegalArgumentException("Null 'axisIndex' argument.");
3765: }
3766: List result = new ArrayList();
3767: for (int i = 0; i < this.datasets.size(); i++) {
3768: Integer mappedAxis = (Integer) this.datasetToDomainAxisMap.get(
3769: new Integer(i));
3770: if (mappedAxis == null) {
3771: if (axisIndex.equals(ZERO)) {
3772: result.add(this.datasets.get(i));
3773: }
3774: }
3775: else {
3776: if (mappedAxis.equals(axisIndex)) {
3777: result.add(this.datasets.get(i));
3778: }
3779: }
3780: }
3781: return result;
3782: }
3783:
3784:
3792: private List getDatasetsMappedToRangeAxis(Integer axisIndex) {
3793: if (axisIndex == null) {
3794: throw new IllegalArgumentException("Null 'axisIndex' argument.");
3795: }
3796: List result = new ArrayList();
3797: for (int i = 0; i < this.datasets.size(); i++) {
3798: Integer mappedAxis = (Integer) this.datasetToRangeAxisMap.get(
3799: new Integer(i));
3800: if (mappedAxis == null) {
3801: if (axisIndex.equals(ZERO)) {
3802: result.add(this.datasets.get(i));
3803: }
3804: }
3805: else {
3806: if (mappedAxis.equals(axisIndex)) {
3807: result.add(this.datasets.get(i));
3808: }
3809: }
3810: }
3811: return result;
3812: }
3813:
3814:
3823: public int getDomainAxisIndex(ValueAxis axis) {
3824: int result = this.domainAxes.indexOf(axis);
3825: if (result < 0) {
3826:
3827: Plot parent = getParent();
3828: if (parent instanceof XYPlot) {
3829: XYPlot p = (XYPlot) parent;
3830: result = p.getDomainAxisIndex(axis);
3831: }
3832: }
3833: return result;
3834: }
3835:
3836:
3845: public int getRangeAxisIndex(ValueAxis axis) {
3846: int result = this.rangeAxes.indexOf(axis);
3847: if (result < 0) {
3848:
3849: Plot parent = getParent();
3850: if (parent instanceof XYPlot) {
3851: XYPlot p = (XYPlot) parent;
3852: result = p.getRangeAxisIndex(axis);
3853: }
3854: }
3855: return result;
3856: }
3857:
3858:
3865: public Range getDataRange(ValueAxis axis) {
3866:
3867: Range result = null;
3868: List mappedDatasets = new ArrayList();
3869: boolean isDomainAxis = true;
3870:
3871:
3872: int domainIndex = getDomainAxisIndex(axis);
3873: if (domainIndex >= 0) {
3874: isDomainAxis = true;
3875: mappedDatasets.addAll(getDatasetsMappedToDomainAxis(
3876: new Integer(domainIndex)));
3877: }
3878:
3879:
3880: int rangeIndex = getRangeAxisIndex(axis);
3881: if (rangeIndex >= 0) {
3882: isDomainAxis = false;
3883: mappedDatasets.addAll(getDatasetsMappedToRangeAxis(
3884: new Integer(rangeIndex)));
3885: }
3886:
3887:
3888:
3889: Iterator iterator = mappedDatasets.iterator();
3890: while (iterator.hasNext()) {
3891: XYDataset d = (XYDataset) iterator.next();
3892: if (d != null) {
3893: XYItemRenderer r = getRendererForDataset(d);
3894: if (isDomainAxis) {
3895: if (r != null) {
3896: result = Range.combine(result, r.findDomainBounds(d));
3897: }
3898: else {
3899: result = Range.combine(result,
3900: DatasetUtilities.findDomainBounds(d));
3901: }
3902: }
3903: else {
3904: if (r != null) {
3905: result = Range.combine(result, r.findRangeBounds(d));
3906: }
3907: else {
3908: result = Range.combine(result,
3909: DatasetUtilities.findRangeBounds(d));
3910: }
3911: }
3912: }
3913: }
3914: return result;
3915:
3916: }
3917:
3918:
3925: public void datasetChanged(DatasetChangeEvent event) {
3926: configureDomainAxes();
3927: configureRangeAxes();
3928: if (getParent() != null) {
3929: getParent().datasetChanged(event);
3930: }
3931: else {
3932: PlotChangeEvent e = new PlotChangeEvent(this);
3933: e.setType(ChartChangeEventType.DATASET_UPDATED);
3934: notifyListeners(e);
3935: }
3936: }
3937:
3938:
3943: public void rendererChanged(RendererChangeEvent event) {
3944: notifyListeners(new PlotChangeEvent(this));
3945: }
3946:
3947:
3954: public boolean isDomainCrosshairVisible() {
3955: return this.domainCrosshairVisible;
3956: }
3957:
3958:
3967: public void setDomainCrosshairVisible(boolean flag) {
3968: if (this.domainCrosshairVisible != flag) {
3969: this.domainCrosshairVisible = flag;
3970: notifyListeners(new PlotChangeEvent(this));
3971: }
3972: }
3973:
3974:
3982: public boolean isDomainCrosshairLockedOnData() {
3983: return this.domainCrosshairLockedOnData;
3984: }
3985:
3986:
3995: public void setDomainCrosshairLockedOnData(boolean flag) {
3996: if (this.domainCrosshairLockedOnData != flag) {
3997: this.domainCrosshairLockedOnData = flag;
3998: notifyListeners(new PlotChangeEvent(this));
3999: }
4000: }
4001:
4002:
4009: public double getDomainCrosshairValue() {
4010: return this.domainCrosshairValue;
4011: }
4012:
4013:
4021: public void setDomainCrosshairValue(double value) {
4022: setDomainCrosshairValue(value, true);
4023: }
4024:
4025:
4035: public void setDomainCrosshairValue(double value, boolean notify) {
4036: this.domainCrosshairValue = value;
4037: if (isDomainCrosshairVisible() && notify) {
4038: notifyListeners(new PlotChangeEvent(this));
4039: }
4040: }
4041:
4042:
4051: public Stroke getDomainCrosshairStroke() {
4052: return this.domainCrosshairStroke;
4053: }
4054:
4055:
4064: public void setDomainCrosshairStroke(Stroke stroke) {
4065: if (stroke == null) {
4066: throw new IllegalArgumentException("Null 'stroke' argument.");
4067: }
4068: this.domainCrosshairStroke = stroke;
4069: notifyListeners(new PlotChangeEvent(this));
4070: }
4071:
4072:
4081: public Paint getDomainCrosshairPaint() {
4082: return this.domainCrosshairPaint;
4083: }
4084:
4085:
4093: public void setDomainCrosshairPaint(Paint paint) {
4094: if (paint == null) {
4095: throw new IllegalArgumentException("Null 'paint' argument.");
4096: }
4097: this.domainCrosshairPaint = paint;
4098: notifyListeners(new PlotChangeEvent(this));
4099: }
4100:
4101:
4109: public boolean isRangeCrosshairVisible() {
4110: return this.rangeCrosshairVisible;
4111: }
4112:
4113:
4122: public void setRangeCrosshairVisible(boolean flag) {
4123: if (this.rangeCrosshairVisible != flag) {
4124: this.rangeCrosshairVisible = flag;
4125: notifyListeners(new PlotChangeEvent(this));
4126: }
4127: }
4128:
4129:
4137: public boolean isRangeCrosshairLockedOnData() {
4138: return this.rangeCrosshairLockedOnData;
4139: }
4140:
4141:
4150: public void setRangeCrosshairLockedOnData(boolean flag) {
4151: if (this.rangeCrosshairLockedOnData != flag) {
4152: this.rangeCrosshairLockedOnData = flag;
4153: notifyListeners(new PlotChangeEvent(this));
4154: }
4155: }
4156:
4157:
4164: public double getRangeCrosshairValue() {
4165: return this.rangeCrosshairValue;
4166: }
4167:
4168:
4178: public void setRangeCrosshairValue(double value) {
4179: setRangeCrosshairValue(value, true);
4180: }
4181:
4182:
4192: public void setRangeCrosshairValue(double value, boolean notify) {
4193: this.rangeCrosshairValue = value;
4194: if (isRangeCrosshairVisible() && notify) {
4195: notifyListeners(new PlotChangeEvent(this));
4196: }
4197: }
4198:
4199:
4208: public Stroke getRangeCrosshairStroke() {
4209: return this.rangeCrosshairStroke;
4210: }
4211:
4212:
4221: public void setRangeCrosshairStroke(Stroke stroke) {
4222: if (stroke == null) {
4223: throw new IllegalArgumentException("Null 'stroke' argument.");
4224: }
4225: this.rangeCrosshairStroke = stroke;
4226: notifyListeners(new PlotChangeEvent(this));
4227: }
4228:
4229:
4238: public Paint getRangeCrosshairPaint() {
4239: return this.rangeCrosshairPaint;
4240: }
4241:
4242:
4250: public void setRangeCrosshairPaint(Paint paint) {
4251: if (paint == null) {
4252: throw new IllegalArgumentException("Null 'paint' argument.");
4253: }
4254: this.rangeCrosshairPaint = paint;
4255: notifyListeners(new PlotChangeEvent(this));
4256: }
4257:
4258:
4265: public AxisSpace getFixedDomainAxisSpace() {
4266: return this.fixedDomainAxisSpace;
4267: }
4268:
4269:
4277: public void setFixedDomainAxisSpace(AxisSpace space) {
4278: this.fixedDomainAxisSpace = space;
4279: notifyListeners(new PlotChangeEvent(this));
4280: }
4281:
4282:
4289: public AxisSpace getFixedRangeAxisSpace() {
4290: return this.fixedRangeAxisSpace;
4291: }
4292:
4293:
4301: public void setFixedRangeAxisSpace(AxisSpace space) {
4302: this.fixedRangeAxisSpace = space;
4303: notifyListeners(new PlotChangeEvent(this));
4304: }
4305:
4306:
4315: public void zoomDomainAxes(double factor, PlotRenderingInfo info,
4316: Point2D source) {
4317:
4318: zoomDomainAxes(factor, info, source, false);
4319: }
4320:
4321:
4333: public void zoomDomainAxes(double factor, PlotRenderingInfo info,
4334: Point2D source, boolean useAnchor) {
4335:
4336:
4337: for (int i = 0; i < this.domainAxes.size(); i++) {
4338: ValueAxis domainAxis = (ValueAxis) this.domainAxes.get(i);
4339: if (domainAxis != null) {
4340: if (useAnchor) {
4341:
4342:
4343: double sourceX = source.getX();
4344: if (this.orientation == PlotOrientation.HORIZONTAL) {
4345: sourceX = source.getY();
4346: }
4347: double anchorX = domainAxis.java2DToValue(sourceX,
4348: info.getDataArea(), getDomainAxisEdge());
4349: domainAxis.resizeRange(factor, anchorX);
4350: }
4351: else {
4352: domainAxis.resizeRange(factor);
4353: }
4354: }
4355: }
4356: }
4357:
4358:
4372: public void zoomDomainAxes(double lowerPercent, double upperPercent,
4373: PlotRenderingInfo info, Point2D source) {
4374: for (int i = 0; i < this.domainAxes.size(); i++) {
4375: ValueAxis domainAxis = (ValueAxis) this.domainAxes.get(i);
4376: if (domainAxis != null) {
4377: domainAxis.zoomRange(lowerPercent, upperPercent);
4378: }
4379: }
4380: }
4381:
4382:
4391: public void zoomRangeAxes(double factor, PlotRenderingInfo info,
4392: Point2D source) {
4393:
4394: zoomRangeAxes(factor, info, source, false);
4395: }
4396:
4397:
4410: public void zoomRangeAxes(double factor, PlotRenderingInfo info,
4411: Point2D source, boolean useAnchor) {
4412:
4413:
4414: for (int i = 0; i < this.rangeAxes.size(); i++) {
4415: ValueAxis rangeAxis = (ValueAxis) this.rangeAxes.get(i);
4416: if (rangeAxis != null) {
4417: if (useAnchor) {
4418:
4419:
4420: double sourceY = source.getY();
4421: if (this.orientation == PlotOrientation.HORIZONTAL) {
4422: sourceY = source.getX();
4423: }
4424: double anchorY = rangeAxis.java2DToValue(sourceY,
4425: info.getDataArea(), getRangeAxisEdge());
4426: rangeAxis.resizeRange(factor, anchorY);
4427: }
4428: else {
4429: rangeAxis.resizeRange(factor);
4430: }
4431: }
4432: }
4433: }
4434:
4435:
4445: public void zoomRangeAxes(double lowerPercent, double upperPercent,
4446: PlotRenderingInfo info, Point2D source) {
4447: for (int i = 0; i < this.rangeAxes.size(); i++) {
4448: ValueAxis rangeAxis = (ValueAxis) this.rangeAxes.get(i);
4449: if (rangeAxis != null) {
4450: rangeAxis.zoomRange(lowerPercent, upperPercent);
4451: }
4452: }
4453: }
4454:
4455:
4463: public boolean isDomainZoomable() {
4464: return true;
4465: }
4466:
4467:
4475: public boolean isRangeZoomable() {
4476: return true;
4477: }
4478:
4479:
4485: public int getSeriesCount() {
4486: int result = 0;
4487: XYDataset dataset = getDataset();
4488: if (dataset != null) {
4489: result = dataset.getSeriesCount();
4490: }
4491: return result;
4492: }
4493:
4494:
4501: public LegendItemCollection getFixedLegendItems() {
4502: return this.fixedLegendItems;
4503: }
4504:
4505:
4514: public void setFixedLegendItems(LegendItemCollection items) {
4515: this.fixedLegendItems = items;
4516: notifyListeners(new PlotChangeEvent(this));
4517: }
4518:
4519:
4526: public LegendItemCollection getLegendItems() {
4527: if (this.fixedLegendItems != null) {
4528: return this.fixedLegendItems;
4529: }
4530: LegendItemCollection result = new LegendItemCollection();
4531: int count = this.datasets.size();
4532: for (int datasetIndex = 0; datasetIndex < count; datasetIndex++) {
4533: XYDataset dataset = getDataset(datasetIndex);
4534: if (dataset != null) {
4535: XYItemRenderer renderer = getRenderer(datasetIndex);
4536: if (renderer == null) {
4537: renderer = getRenderer(0);
4538: }
4539: if (renderer != null) {
4540: int seriesCount = dataset.getSeriesCount();
4541: for (int i = 0; i < seriesCount; i++) {
4542: if (renderer.isSeriesVisible(i)
4543: && renderer.isSeriesVisibleInLegend(i)) {
4544: LegendItem item = renderer.getLegendItem(
4545: datasetIndex, i);
4546: if (item != null) {
4547: result.add(item);
4548: }
4549: }
4550: }
4551: }
4552: }
4553: }
4554: return result;
4555: }
4556:
4557:
4564: public boolean equals(Object obj) {
4565:
4566: if (obj == this) {
4567: return true;
4568: }
4569: if (!(obj instanceof XYPlot)) {
4570: return false;
4571: }
4572:
4573: XYPlot that = (XYPlot) obj;
4574: if (this.weight != that.weight) {
4575: return false;
4576: }
4577: if (this.orientation != that.orientation) {
4578: return false;
4579: }
4580: if (!this.domainAxes.equals(that.domainAxes)) {
4581: return false;
4582: }
4583: if (!this.domainAxisLocations.equals(that.domainAxisLocations)) {
4584: return false;
4585: }
4586: if (this.rangeCrosshairLockedOnData
4587: != that.rangeCrosshairLockedOnData) {
4588: return false;
4589: }
4590: if (this.domainGridlinesVisible != that.domainGridlinesVisible) {
4591: return false;
4592: }
4593: if (this.rangeGridlinesVisible != that.rangeGridlinesVisible) {
4594: return false;
4595: }
4596: if (this.domainZeroBaselineVisible != that.domainZeroBaselineVisible) {
4597: return false;
4598: }
4599: if (this.rangeZeroBaselineVisible != that.rangeZeroBaselineVisible) {
4600: return false;
4601: }
4602: if (this.domainCrosshairVisible != that.domainCrosshairVisible) {
4603: return false;
4604: }
4605: if (this.domainCrosshairValue != that.domainCrosshairValue) {
4606: return false;
4607: }
4608: if (this.domainCrosshairLockedOnData
4609: != that.domainCrosshairLockedOnData) {
4610: return false;
4611: }
4612: if (this.rangeCrosshairVisible != that.rangeCrosshairVisible) {
4613: return false;
4614: }
4615: if (this.rangeCrosshairValue != that.rangeCrosshairValue) {
4616: return false;
4617: }
4618: if (!ObjectUtilities.equal(this.axisOffset, that.axisOffset)) {
4619: return false;
4620: }
4621: if (!ObjectUtilities.equal(this.renderers, that.renderers)) {
4622: return false;
4623: }
4624: if (!ObjectUtilities.equal(this.rangeAxes, that.rangeAxes)) {
4625: return false;
4626: }
4627: if (!this.rangeAxisLocations.equals(that.rangeAxisLocations)) {
4628: return false;
4629: }
4630: if (!ObjectUtilities.equal(this.datasetToDomainAxisMap,
4631: that.datasetToDomainAxisMap)) {
4632: return false;
4633: }
4634: if (!ObjectUtilities.equal(this.datasetToRangeAxisMap,
4635: that.datasetToRangeAxisMap)) {
4636: return false;
4637: }
4638: if (!ObjectUtilities.equal(this.domainGridlineStroke,
4639: that.domainGridlineStroke)) {
4640: return false;
4641: }
4642: if (!PaintUtilities.equal(this.domainGridlinePaint,
4643: that.domainGridlinePaint)) {
4644: return false;
4645: }
4646: if (!ObjectUtilities.equal(this.rangeGridlineStroke,
4647: that.rangeGridlineStroke)) {
4648: return false;
4649: }
4650: if (!PaintUtilities.equal(this.rangeGridlinePaint,
4651: that.rangeGridlinePaint)) {
4652: return false;
4653: }
4654: if (!PaintUtilities.equal(this.domainZeroBaselinePaint,
4655: that.domainZeroBaselinePaint)) {
4656: return false;
4657: }
4658: if (!ObjectUtilities.equal(this.domainZeroBaselineStroke,
4659: that.domainZeroBaselineStroke)) {
4660: return false;
4661: }
4662: if (!PaintUtilities.equal(this.rangeZeroBaselinePaint,
4663: that.rangeZeroBaselinePaint)) {
4664: return false;
4665: }
4666: if (!ObjectUtilities.equal(this.rangeZeroBaselineStroke,
4667: that.rangeZeroBaselineStroke)) {
4668: return false;
4669: }
4670: if (!ObjectUtilities.equal(this.domainCrosshairStroke,
4671: that.domainCrosshairStroke)) {
4672: return false;
4673: }
4674: if (!PaintUtilities.equal(this.domainCrosshairPaint,
4675: that.domainCrosshairPaint)) {
4676: return false;
4677: }
4678: if (!ObjectUtilities.equal(this.rangeCrosshairStroke,
4679: that.rangeCrosshairStroke)) {
4680: return false;
4681: }
4682: if (!PaintUtilities.equal(this.rangeCrosshairPaint,
4683: that.rangeCrosshairPaint)) {
4684: return false;
4685: }
4686: if (!ObjectUtilities.equal(this.foregroundDomainMarkers,
4687: that.foregroundDomainMarkers)) {
4688: return false;
4689: }
4690: if (!ObjectUtilities.equal(this.backgroundDomainMarkers,
4691: that.backgroundDomainMarkers)) {
4692: return false;
4693: }
4694: if (!ObjectUtilities.equal(this.foregroundRangeMarkers,
4695: that.foregroundRangeMarkers)) {
4696: return false;
4697: }
4698: if (!ObjectUtilities.equal(this.backgroundRangeMarkers,
4699: that.backgroundRangeMarkers)) {
4700: return false;
4701: }
4702: if (!ObjectUtilities.equal(this.foregroundDomainMarkers,
4703: that.foregroundDomainMarkers)) {
4704: return false;
4705: }
4706: if (!ObjectUtilities.equal(this.backgroundDomainMarkers,
4707: that.backgroundDomainMarkers)) {
4708: return false;
4709: }
4710: if (!ObjectUtilities.equal(this.foregroundRangeMarkers,
4711: that.foregroundRangeMarkers)) {
4712: return false;
4713: }
4714: if (!ObjectUtilities.equal(this.backgroundRangeMarkers,
4715: that.backgroundRangeMarkers)) {
4716: return false;
4717: }
4718: if (!ObjectUtilities.equal(this.annotations, that.annotations)) {
4719: return false;
4720: }
4721: if (!PaintUtilities.equal(this.domainTickBandPaint,
4722: that.domainTickBandPaint)) {
4723: return false;
4724: }
4725: if (!PaintUtilities.equal(this.rangeTickBandPaint,
4726: that.rangeTickBandPaint)) {
4727: return false;
4728: }
4729: if (!this.quadrantOrigin.equals(that.quadrantOrigin)) {
4730: return false;
4731: }
4732: for (int i = 0; i < 4; i++) {
4733: if (!PaintUtilities.equal(this.quadrantPaint[i],
4734: that.quadrantPaint[i])) {
4735: return false;
4736: }
4737: }
4738: return super.equals(obj);
4739: }
4740:
4741:
4749: public Object clone() throws CloneNotSupportedException {
4750:
4751: XYPlot clone = (XYPlot) super.clone();
4752: clone.domainAxes = (ObjectList) ObjectUtilities.clone(this.domainAxes);
4753: for (int i = 0; i < this.domainAxes.size(); i++) {
4754: ValueAxis axis = (ValueAxis) this.domainAxes.get(i);
4755: if (axis != null) {
4756: ValueAxis clonedAxis = (ValueAxis) axis.clone();
4757: clone.domainAxes.set(i, clonedAxis);
4758: clonedAxis.setPlot(clone);
4759: clonedAxis.addChangeListener(clone);
4760: }
4761: }
4762: clone.domainAxisLocations = (ObjectList)
4763: this.domainAxisLocations.clone();
4764:
4765: clone.rangeAxes = (ObjectList) ObjectUtilities.clone(this.rangeAxes);
4766: for (int i = 0; i < this.rangeAxes.size(); i++) {
4767: ValueAxis axis = (ValueAxis) this.rangeAxes.get(i);
4768: if (axis != null) {
4769: ValueAxis clonedAxis = (ValueAxis) axis.clone();
4770: clone.rangeAxes.set(i, clonedAxis);
4771: clonedAxis.setPlot(clone);
4772: clonedAxis.addChangeListener(clone);
4773: }
4774: }
4775: clone.rangeAxisLocations = (ObjectList) ObjectUtilities.clone(
4776: this.rangeAxisLocations);
4777:
4778:
4779: clone.datasets = (ObjectList) ObjectUtilities.clone(this.datasets);
4780: for (int i = 0; i < clone.datasets.size(); ++i) {
4781: XYDataset d = getDataset(i);
4782: if (d != null) {
4783: d.addChangeListener(clone);
4784: }
4785: }
4786:
4787: clone.datasetToDomainAxisMap = new TreeMap();
4788: clone.datasetToDomainAxisMap.putAll(this.datasetToDomainAxisMap);
4789: clone.datasetToRangeAxisMap = new TreeMap();
4790: clone.datasetToRangeAxisMap.putAll(this.datasetToRangeAxisMap);
4791:
4792: clone.renderers = (ObjectList) ObjectUtilities.clone(this.renderers);
4793: for (int i = 0; i < this.renderers.size(); i++) {
4794: XYItemRenderer renderer2 = (XYItemRenderer) this.renderers.get(i);
4795: if (renderer2 instanceof PublicCloneable) {
4796: PublicCloneable pc = (PublicCloneable) renderer2;
4797: clone.renderers.set(i, pc.clone());
4798: }
4799: }
4800: clone.foregroundDomainMarkers = (Map) ObjectUtilities.clone(
4801: this.foregroundDomainMarkers);
4802: clone.backgroundDomainMarkers = (Map) ObjectUtilities.clone(
4803: this.backgroundDomainMarkers);
4804: clone.foregroundRangeMarkers = (Map) ObjectUtilities.clone(
4805: this.foregroundRangeMarkers);
4806: clone.backgroundRangeMarkers = (Map) ObjectUtilities.clone(
4807: this.backgroundRangeMarkers);
4808: clone.annotations = (List) ObjectUtilities.deepClone(this.annotations);
4809: if (this.fixedDomainAxisSpace != null) {
4810: clone.fixedDomainAxisSpace = (AxisSpace) ObjectUtilities.clone(
4811: this.fixedDomainAxisSpace);
4812: }
4813: if (this.fixedRangeAxisSpace != null) {
4814: clone.fixedRangeAxisSpace = (AxisSpace) ObjectUtilities.clone(
4815: this.fixedRangeAxisSpace);
4816: }
4817:
4818: clone.quadrantOrigin = (Point2D) ObjectUtilities.clone(
4819: this.quadrantOrigin);
4820: clone.quadrantPaint = (Paint[]) this.quadrantPaint.clone();
4821: return clone;
4822:
4823: }
4824:
4825:
4832: private void writeObject(ObjectOutputStream stream) throws IOException {
4833: stream.defaultWriteObject();
4834: SerialUtilities.writeStroke(this.domainGridlineStroke, stream);
4835: SerialUtilities.writePaint(this.domainGridlinePaint, stream);
4836: SerialUtilities.writeStroke(this.rangeGridlineStroke, stream);
4837: SerialUtilities.writePaint(this.rangeGridlinePaint, stream);
4838: SerialUtilities.writeStroke(this.rangeZeroBaselineStroke, stream);
4839: SerialUtilities.writePaint(this.rangeZeroBaselinePaint, stream);
4840: SerialUtilities.writeStroke(this.domainCrosshairStroke, stream);
4841: SerialUtilities.writePaint(this.domainCrosshairPaint, stream);
4842: SerialUtilities.writeStroke(this.rangeCrosshairStroke, stream);
4843: SerialUtilities.writePaint(this.rangeCrosshairPaint, stream);
4844: SerialUtilities.writePaint(this.domainTickBandPaint, stream);
4845: SerialUtilities.writePaint(this.rangeTickBandPaint, stream);
4846: SerialUtilities.writePoint2D(this.quadrantOrigin, stream);
4847: for (int i = 0; i < 4; i++) {
4848: SerialUtilities.writePaint(this.quadrantPaint[i], stream);
4849: }
4850: SerialUtilities.writeStroke(this.domainZeroBaselineStroke, stream);
4851: SerialUtilities.writePaint(this.domainZeroBaselinePaint, stream);
4852: }
4853:
4854:
4862: private void readObject(ObjectInputStream stream)
4863: throws IOException, ClassNotFoundException {
4864:
4865: stream.defaultReadObject();
4866: this.domainGridlineStroke = SerialUtilities.readStroke(stream);
4867: this.domainGridlinePaint = SerialUtilities.readPaint(stream);
4868: this.rangeGridlineStroke = SerialUtilities.readStroke(stream);
4869: this.rangeGridlinePaint = SerialUtilities.readPaint(stream);
4870: this.rangeZeroBaselineStroke = SerialUtilities.readStroke(stream);
4871: this.rangeZeroBaselinePaint = SerialUtilities.readPaint(stream);
4872: this.domainCrosshairStroke = SerialUtilities.readStroke(stream);
4873: this.domainCrosshairPaint = SerialUtilities.readPaint(stream);
4874: this.rangeCrosshairStroke = SerialUtilities.readStroke(stream);
4875: this.rangeCrosshairPaint = SerialUtilities.readPaint(stream);
4876: this.domainTickBandPaint = SerialUtilities.readPaint(stream);
4877: this.rangeTickBandPaint = SerialUtilities.readPaint(stream);
4878: this.quadrantOrigin = SerialUtilities.readPoint2D(stream);
4879: this.quadrantPaint = new Paint[4];
4880: for (int i = 0; i < 4; i++) {
4881: this.quadrantPaint[i] = SerialUtilities.readPaint(stream);
4882: }
4883:
4884: this.domainZeroBaselineStroke = SerialUtilities.readStroke(stream);
4885: this.domainZeroBaselinePaint = SerialUtilities.readPaint(stream);
4886:
4887:
4888:
4889: int domainAxisCount = this.domainAxes.size();
4890: for (int i = 0; i < domainAxisCount; i++) {
4891: Axis axis = (Axis) this.domainAxes.get(i);
4892: if (axis != null) {
4893: axis.setPlot(this);
4894: axis.addChangeListener(this);
4895: }
4896: }
4897: int rangeAxisCount = this.rangeAxes.size();
4898: for (int i = 0; i < rangeAxisCount; i++) {
4899: Axis axis = (Axis) this.rangeAxes.get(i);
4900: if (axis != null) {
4901: axis.setPlot(this);
4902: axis.addChangeListener(this);
4903: }
4904: }
4905: int datasetCount = this.datasets.size();
4906: for (int i = 0; i < datasetCount; i++) {
4907: Dataset dataset = (Dataset) this.datasets.get(i);
4908: if (dataset != null) {
4909: dataset.addChangeListener(this);
4910: }
4911: }
4912: int rendererCount = this.renderers.size();
4913: for (int i = 0; i < rendererCount; i++) {
4914: XYItemRenderer renderer = (XYItemRenderer) this.renderers.get(i);
4915: if (renderer != null) {
4916: renderer.addChangeListener(this);
4917: }
4918: }
4919:
4920: }
4921:
4922: }