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