1:
158:
159: package ;
160:
161: import ;
162: import ;
163: import ;
164: import ;
165: import ;
166: import ;
167: import ;
168: import ;
169: import ;
170: import ;
171: import ;
172: import ;
173: import ;
174: import ;
175: import ;
176: import ;
177: import ;
178: import ;
179: import ;
180: import ;
181: import ;
182: import ;
183: import ;
184: import ;
185: import ;
186:
187: import ;
188: import ;
189: import ;
190: import ;
191: import ;
192: import ;
193: import ;
194: import ;
195: import ;
196: import ;
197: import ;
198: import ;
199: import ;
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:
220:
224: public class CategoryPlot extends Plot implements ValueAxisPlot,
225: Zoomable, RendererChangeListener, Cloneable, PublicCloneable,
226: Serializable {
227:
228:
229: private static final long serialVersionUID = -3537691700434728188L;
230:
231:
235: public static final boolean DEFAULT_DOMAIN_GRIDLINES_VISIBLE = false;
236:
237:
241: public static final boolean DEFAULT_RANGE_GRIDLINES_VISIBLE = true;
242:
243:
244: public static final Stroke DEFAULT_GRIDLINE_STROKE = new BasicStroke(0.5f,
245: BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0.0f, new float[]
246: {2.0f, 2.0f}, 0.0f);
247:
248:
249: public static final Paint DEFAULT_GRIDLINE_PAINT = Color.lightGray;
250:
251:
252: public static final Font DEFAULT_VALUE_LABEL_FONT = new Font("SansSerif",
253: Font.PLAIN, 10);
254:
255:
260: public static final boolean DEFAULT_CROSSHAIR_VISIBLE = false;
261:
262:
267: public static final Stroke DEFAULT_CROSSHAIR_STROKE
268: = DEFAULT_GRIDLINE_STROKE;
269:
270:
275: public static final Paint DEFAULT_CROSSHAIR_PAINT = Color.blue;
276:
277:
278: protected static ResourceBundle localizationResources
279: = ResourceBundle.getBundle(
280: "org.jfree.chart.plot.LocalizationBundle");
281:
282:
283: private PlotOrientation orientation;
284:
285:
286: private RectangleInsets axisOffset;
287:
288:
289: private ObjectList domainAxes;
290:
291:
292: private ObjectList domainAxisLocations;
293:
294:
298: private boolean drawSharedDomainAxis;
299:
300:
301: private ObjectList rangeAxes;
302:
303:
304: private ObjectList rangeAxisLocations;
305:
306:
307: private ObjectList datasets;
308:
309:
310: private ObjectList datasetToDomainAxisMap;
311:
312:
313: private ObjectList datasetToRangeAxisMap;
314:
315:
316: private ObjectList renderers;
317:
318:
319: private DatasetRenderingOrder renderingOrder
320: = DatasetRenderingOrder.REVERSE;
321:
322:
326: private SortOrder columnRenderingOrder = SortOrder.ASCENDING;
327:
328:
332: private SortOrder rowRenderingOrder = SortOrder.ASCENDING;
333:
334:
338: private boolean domainGridlinesVisible;
339:
340:
341: private CategoryAnchor domainGridlinePosition;
342:
343:
344: private transient Stroke domainGridlineStroke;
345:
346:
347: private transient Paint domainGridlinePaint;
348:
349:
353: private boolean rangeGridlinesVisible;
354:
355:
356: private transient Stroke rangeGridlineStroke;
357:
358:
359: private transient Paint rangeGridlinePaint;
360:
361:
362: private double anchorValue;
363:
364:
365: private boolean rangeCrosshairVisible;
366:
367:
368: private double rangeCrosshairValue;
369:
370:
371: private transient Stroke rangeCrosshairStroke;
372:
373:
374: private transient Paint rangeCrosshairPaint;
375:
376:
380: private boolean rangeCrosshairLockedOnData = true;
381:
382:
383: private Map foregroundDomainMarkers;
384:
385:
386: private Map backgroundDomainMarkers;
387:
388:
389: private Map foregroundRangeMarkers;
390:
391:
392: private Map backgroundRangeMarkers;
393:
394:
399: private List annotations;
400:
401:
405: private int weight;
406:
407:
408: private AxisSpace fixedDomainAxisSpace;
409:
410:
411: private AxisSpace fixedRangeAxisSpace;
412:
413:
417: private LegendItemCollection fixedLegendItems;
418:
419:
422: public CategoryPlot() {
423: this(null, null, null, null);
424: }
425:
426:
435: public CategoryPlot(CategoryDataset dataset,
436: CategoryAxis domainAxis,
437: ValueAxis rangeAxis,
438: CategoryItemRenderer renderer) {
439:
440: super();
441:
442: this.orientation = PlotOrientation.VERTICAL;
443:
444:
445: this.domainAxes = new ObjectList();
446: this.domainAxisLocations = new ObjectList();
447: this.rangeAxes = new ObjectList();
448: this.rangeAxisLocations = new ObjectList();
449:
450: this.datasetToDomainAxisMap = new ObjectList();
451: this.datasetToRangeAxisMap = new ObjectList();
452:
453: this.renderers = new ObjectList();
454:
455: this.datasets = new ObjectList();
456: this.datasets.set(0, dataset);
457: if (dataset != null) {
458: dataset.addChangeListener(this);
459: }
460:
461: this.axisOffset = RectangleInsets.ZERO_INSETS;
462:
463: setDomainAxisLocation(AxisLocation.BOTTOM_OR_LEFT, false);
464: setRangeAxisLocation(AxisLocation.TOP_OR_LEFT, false);
465:
466: this.renderers.set(0, renderer);
467: if (renderer != null) {
468: renderer.setPlot(this);
469: renderer.addChangeListener(this);
470: }
471:
472: this.domainAxes.set(0, domainAxis);
473: this.mapDatasetToDomainAxis(0, 0);
474: if (domainAxis != null) {
475: domainAxis.setPlot(this);
476: domainAxis.addChangeListener(this);
477: }
478: this.drawSharedDomainAxis = false;
479:
480: this.rangeAxes.set(0, rangeAxis);
481: this.mapDatasetToRangeAxis(0, 0);
482: if (rangeAxis != null) {
483: rangeAxis.setPlot(this);
484: rangeAxis.addChangeListener(this);
485: }
486:
487: configureDomainAxes();
488: configureRangeAxes();
489:
490: this.domainGridlinesVisible = DEFAULT_DOMAIN_GRIDLINES_VISIBLE;
491: this.domainGridlinePosition = CategoryAnchor.MIDDLE;
492: this.domainGridlineStroke = DEFAULT_GRIDLINE_STROKE;
493: this.domainGridlinePaint = DEFAULT_GRIDLINE_PAINT;
494:
495: this.rangeGridlinesVisible = DEFAULT_RANGE_GRIDLINES_VISIBLE;
496: this.rangeGridlineStroke = DEFAULT_GRIDLINE_STROKE;
497: this.rangeGridlinePaint = DEFAULT_GRIDLINE_PAINT;
498:
499: this.foregroundDomainMarkers = new HashMap();
500: this.backgroundDomainMarkers = new HashMap();
501: this.foregroundRangeMarkers = new HashMap();
502: this.backgroundRangeMarkers = new HashMap();
503:
504: Marker baseline = new ValueMarker(0.0, new Color(0.8f, 0.8f, 0.8f,
505: 0.5f), new BasicStroke(1.0f), new Color(0.85f, 0.85f, 0.95f,
506: 0.5f), new BasicStroke(1.0f), 0.6f);
507: addRangeMarker(baseline, Layer.BACKGROUND);
508:
509: this.anchorValue = 0.0;
510:
511: this.rangeCrosshairVisible = DEFAULT_CROSSHAIR_VISIBLE;
512: this.rangeCrosshairValue = 0.0;
513: this.rangeCrosshairStroke = DEFAULT_CROSSHAIR_STROKE;
514: this.rangeCrosshairPaint = DEFAULT_CROSSHAIR_PAINT;
515:
516: this.annotations = new java.util.ArrayList();
517:
518: }
519:
520:
525: public String getPlotType() {
526: return localizationResources.getString("Category_Plot");
527: }
528:
529:
536: public PlotOrientation getOrientation() {
537: return this.orientation;
538: }
539:
540:
548: public void setOrientation(PlotOrientation orientation) {
549: if (orientation == null) {
550: throw new IllegalArgumentException("Null 'orientation' argument.");
551: }
552: this.orientation = orientation;
553: notifyListeners(new PlotChangeEvent(this));
554: }
555:
556:
563: public RectangleInsets getAxisOffset() {
564: return this.axisOffset;
565: }
566:
567:
575: public void setAxisOffset(RectangleInsets offset) {
576: if (offset == null) {
577: throw new IllegalArgumentException("Null 'offset' argument.");
578: }
579: this.axisOffset = offset;
580: notifyListeners(new PlotChangeEvent(this));
581: }
582:
583:
592: public CategoryAxis getDomainAxis() {
593: return getDomainAxis(0);
594: }
595:
596:
605: public CategoryAxis getDomainAxis(int index) {
606: CategoryAxis result = null;
607: if (index < this.domainAxes.size()) {
608: result = (CategoryAxis) this.domainAxes.get(index);
609: }
610: if (result == null) {
611: Plot parent = getParent();
612: if (parent instanceof CategoryPlot) {
613: CategoryPlot cp = (CategoryPlot) parent;
614: result = cp.getDomainAxis(index);
615: }
616: }
617: return result;
618: }
619:
620:
628: public void setDomainAxis(CategoryAxis axis) {
629: setDomainAxis(0, axis);
630: }
631:
632:
641: public void setDomainAxis(int index, CategoryAxis axis) {
642: setDomainAxis(index, axis, true);
643: }
644:
645:
653: public void setDomainAxis(int index, CategoryAxis axis, boolean notify) {
654: CategoryAxis existing = (CategoryAxis) this.domainAxes.get(index);
655: if (existing != null) {
656: existing.removeChangeListener(this);
657: }
658: if (axis != null) {
659: axis.setPlot(this);
660: }
661: this.domainAxes.set(index, axis);
662: if (axis != null) {
663: axis.configure();
664: axis.addChangeListener(this);
665: }
666: if (notify) {
667: notifyListeners(new PlotChangeEvent(this));
668: }
669: }
670:
671:
679: public void setDomainAxes(CategoryAxis[] axes) {
680: for (int i = 0; i < axes.length; i++) {
681: setDomainAxis(i, axes[i], false);
682: }
683: notifyListeners(new PlotChangeEvent(this));
684: }
685:
686:
699: public int getDomainAxisIndex(CategoryAxis axis) {
700: if (axis == null) {
701: throw new IllegalArgumentException("Null 'axis' argument.");
702: }
703: return this.domainAxes.indexOf(axis);
704: }
705:
706:
713: public AxisLocation getDomainAxisLocation() {
714: return getDomainAxisLocation(0);
715: }
716:
717:
726: public AxisLocation getDomainAxisLocation(int index) {
727: AxisLocation result = null;
728: if (index < this.domainAxisLocations.size()) {
729: result = (AxisLocation) this.domainAxisLocations.get(index);
730: }
731: if (result == null) {
732: result = AxisLocation.getOpposite(getDomainAxisLocation(0));
733: }
734: return result;
735: }
736:
737:
746: public void setDomainAxisLocation(AxisLocation location) {
747:
748: setDomainAxisLocation(0, location, true);
749: }
750:
751:
758: public void setDomainAxisLocation(AxisLocation location, boolean notify) {
759:
760: setDomainAxisLocation(0, location, notify);
761: }
762:
763:
773: public void setDomainAxisLocation(int index, AxisLocation location) {
774:
775: setDomainAxisLocation(index, location, true);
776: }
777:
778:
791: public void setDomainAxisLocation(int index, AxisLocation location,
792: boolean notify) {
793: if (index == 0 && location == null) {
794: throw new IllegalArgumentException(
795: "Null 'location' for index 0 not permitted.");
796: }
797: this.domainAxisLocations.set(index, location);
798: if (notify) {
799: notifyListeners(new PlotChangeEvent(this));
800: }
801: }
802:
803:
809: public RectangleEdge getDomainAxisEdge() {
810: return getDomainAxisEdge(0);
811: }
812:
813:
820: public RectangleEdge getDomainAxisEdge(int index) {
821: RectangleEdge result = null;
822: AxisLocation location = getDomainAxisLocation(index);
823: if (location != null) {
824: result = Plot.resolveDomainAxisLocation(location, this.orientation);
825: }
826: else {
827: result = RectangleEdge.opposite(getDomainAxisEdge(0));
828: }
829: return result;
830: }
831:
832:
837: public int getDomainAxisCount() {
838: return this.domainAxes.size();
839: }
840:
841:
845: public void clearDomainAxes() {
846: for (int i = 0; i < this.domainAxes.size(); i++) {
847: CategoryAxis axis = (CategoryAxis) this.domainAxes.get(i);
848: if (axis != null) {
849: axis.removeChangeListener(this);
850: }
851: }
852: this.domainAxes.clear();
853: notifyListeners(new PlotChangeEvent(this));
854: }
855:
856:
859: public void configureDomainAxes() {
860: for (int i = 0; i < this.domainAxes.size(); i++) {
861: CategoryAxis axis = (CategoryAxis) this.domainAxes.get(i);
862: if (axis != null) {
863: axis.configure();
864: }
865: }
866: }
867:
868:
875: public ValueAxis getRangeAxis() {
876: return getRangeAxis(0);
877: }
878:
879:
886: public ValueAxis getRangeAxis(int index) {
887: ValueAxis result = null;
888: if (index < this.rangeAxes.size()) {
889: result = (ValueAxis) this.rangeAxes.get(index);
890: }
891: if (result == null) {
892: Plot parent = getParent();
893: if (parent instanceof CategoryPlot) {
894: CategoryPlot cp = (CategoryPlot) parent;
895: result = cp.getRangeAxis(index);
896: }
897: }
898: return result;
899: }
900:
901:
907: public void setRangeAxis(ValueAxis axis) {
908: setRangeAxis(0, axis);
909: }
910:
911:
918: public void setRangeAxis(int index, ValueAxis axis) {
919: setRangeAxis(index, axis, true);
920: }
921:
922:
930: public void setRangeAxis(int index, ValueAxis axis, boolean notify) {
931: ValueAxis existing = (ValueAxis) this.rangeAxes.get(index);
932: if (existing != null) {
933: existing.removeChangeListener(this);
934: }
935: if (axis != null) {
936: axis.setPlot(this);
937: }
938: this.rangeAxes.set(index, axis);
939: if (axis != null) {
940: axis.configure();
941: axis.addChangeListener(this);
942: }
943: if (notify) {
944: notifyListeners(new PlotChangeEvent(this));
945: }
946: }
947:
948:
956: public void setRangeAxes(ValueAxis[] axes) {
957: for (int i = 0; i < axes.length; i++) {
958: setRangeAxis(i, axes[i], false);
959: }
960: notifyListeners(new PlotChangeEvent(this));
961: }
962:
963:
976: public int getRangeAxisIndex(ValueAxis axis) {
977: if (axis == null) {
978: throw new IllegalArgumentException("Null 'axis' argument.");
979: }
980: int result = this.rangeAxes.indexOf(axis);
981: if (result < 0) {
982: Plot parent = getParent();
983: if (parent instanceof CategoryPlot) {
984: CategoryPlot p = (CategoryPlot) parent;
985: result = p.getRangeAxisIndex(axis);
986: }
987: }
988: return result;
989: }
990:
991:
996: public AxisLocation getRangeAxisLocation() {
997: return getRangeAxisLocation(0);
998: }
999:
1000:
1009: public AxisLocation getRangeAxisLocation(int index) {
1010: AxisLocation result = null;
1011: if (index < this.rangeAxisLocations.size()) {
1012: result = (AxisLocation) this.rangeAxisLocations.get(index);
1013: }
1014: if (result == null) {
1015: result = AxisLocation.getOpposite(getRangeAxisLocation(0));
1016: }
1017: return result;
1018: }
1019:
1020:
1029: public void setRangeAxisLocation(AxisLocation location) {
1030:
1031: setRangeAxisLocation(location, true);
1032: }
1033:
1034:
1043: public void setRangeAxisLocation(AxisLocation location, boolean notify) {
1044: setRangeAxisLocation(0, location, notify);
1045: }
1046:
1047:
1057: public void setRangeAxisLocation(int index, AxisLocation location) {
1058: setRangeAxisLocation(index, location, true);
1059: }
1060:
1061:
1072: public void setRangeAxisLocation(int index, AxisLocation location,
1073: boolean notify) {
1074: if (index == 0 && location == null) {
1075: throw new IllegalArgumentException(
1076: "Null 'location' for index 0 not permitted.");
1077: }
1078: this.rangeAxisLocations.set(index, location);
1079: if (notify) {
1080: notifyListeners(new PlotChangeEvent(this));
1081: }
1082: }
1083:
1084:
1089: public RectangleEdge getRangeAxisEdge() {
1090: return getRangeAxisEdge(0);
1091: }
1092:
1093:
1100: public RectangleEdge getRangeAxisEdge(int index) {
1101: AxisLocation location = getRangeAxisLocation(index);
1102: RectangleEdge result = Plot.resolveRangeAxisLocation(location,
1103: this.orientation);
1104: if (result == null) {
1105: result = RectangleEdge.opposite(getRangeAxisEdge(0));
1106: }
1107: return result;
1108: }
1109:
1110:
1115: public int getRangeAxisCount() {
1116: return this.rangeAxes.size();
1117: }
1118:
1119:
1123: public void clearRangeAxes() {
1124: for (int i = 0; i < this.rangeAxes.size(); i++) {
1125: ValueAxis axis = (ValueAxis) this.rangeAxes.get(i);
1126: if (axis != null) {
1127: axis.removeChangeListener(this);
1128: }
1129: }
1130: this.rangeAxes.clear();
1131: notifyListeners(new PlotChangeEvent(this));
1132: }
1133:
1134:
1137: public void configureRangeAxes() {
1138: for (int i = 0; i < this.rangeAxes.size(); i++) {
1139: ValueAxis axis = (ValueAxis) this.rangeAxes.get(i);
1140: if (axis != null) {
1141: axis.configure();
1142: }
1143: }
1144: }
1145:
1146:
1153: public CategoryDataset getDataset() {
1154: return getDataset(0);
1155: }
1156:
1157:
1166: public CategoryDataset getDataset(int index) {
1167: CategoryDataset result = null;
1168: if (this.datasets.size() > index) {
1169: result = (CategoryDataset) this.datasets.get(index);
1170: }
1171: return result;
1172: }
1173:
1174:
1185: public void setDataset(CategoryDataset dataset) {
1186: setDataset(0, dataset);
1187: }
1188:
1189:
1197: public void setDataset(int index, CategoryDataset dataset) {
1198:
1199: CategoryDataset existing = (CategoryDataset) this.datasets.get(index);
1200: if (existing != null) {
1201: existing.removeChangeListener(this);
1202: }
1203: this.datasets.set(index, dataset);
1204: if (dataset != null) {
1205: dataset.addChangeListener(this);
1206: }
1207:
1208:
1209: DatasetChangeEvent event = new DatasetChangeEvent(this, dataset);
1210: datasetChanged(event);
1211:
1212: }
1213:
1214:
1221: public int getDatasetCount() {
1222: return this.datasets.size();
1223: }
1224:
1225:
1233: public void mapDatasetToDomainAxis(int index, int axisIndex) {
1234: this.datasetToDomainAxisMap.set(index, new Integer(axisIndex));
1235:
1236: datasetChanged(new DatasetChangeEvent(this, getDataset(index)));
1237: }
1238:
1239:
1249: public CategoryAxis getDomainAxisForDataset(int index) {
1250: CategoryAxis result = getDomainAxis();
1251: Integer axisIndex = (Integer) this.datasetToDomainAxisMap.get(index);
1252: if (axisIndex != null) {
1253: result = getDomainAxis(axisIndex.intValue());
1254: }
1255: return result;
1256: }
1257:
1258:
1266: public void mapDatasetToRangeAxis(int index, int axisIndex) {
1267: this.datasetToRangeAxisMap.set(index, new Integer(axisIndex));
1268:
1269: datasetChanged(new DatasetChangeEvent(this, getDataset(index)));
1270: }
1271:
1272:
1282: public ValueAxis getRangeAxisForDataset(int index) {
1283: ValueAxis result = getRangeAxis();
1284: Integer axisIndex = (Integer) this.datasetToRangeAxisMap.get(index);
1285: if (axisIndex != null) {
1286: result = getRangeAxis(axisIndex.intValue());
1287: }
1288: return result;
1289: }
1290:
1291:
1298: public CategoryItemRenderer getRenderer() {
1299: return getRenderer(0);
1300: }
1301:
1302:
1311: public CategoryItemRenderer getRenderer(int index) {
1312: CategoryItemRenderer result = null;
1313: if (this.renderers.size() > index) {
1314: result = (CategoryItemRenderer) this.renderers.get(index);
1315: }
1316: return result;
1317: }
1318:
1319:
1328: public void setRenderer(CategoryItemRenderer renderer) {
1329: setRenderer(0, renderer, true);
1330: }
1331:
1332:
1349: public void setRenderer(CategoryItemRenderer renderer, boolean notify) {
1350: setRenderer(0, renderer, notify);
1351: }
1352:
1353:
1363: public void setRenderer(int index, CategoryItemRenderer renderer) {
1364: setRenderer(index, renderer, true);
1365: }
1366:
1367:
1377: public void setRenderer(int index, CategoryItemRenderer renderer,
1378: boolean notify) {
1379:
1380:
1381: CategoryItemRenderer existing
1382: = (CategoryItemRenderer) this.renderers.get(index);
1383: if (existing != null) {
1384: existing.removeChangeListener(this);
1385: }
1386:
1387:
1388: this.renderers.set(index, renderer);
1389: if (renderer != null) {
1390: renderer.setPlot(this);
1391: renderer.addChangeListener(this);
1392: }
1393:
1394: configureDomainAxes();
1395: configureRangeAxes();
1396:
1397: if (notify) {
1398: notifyListeners(new PlotChangeEvent(this));
1399: }
1400: }
1401:
1402:
1408: public void setRenderers(CategoryItemRenderer[] renderers) {
1409: for (int i = 0; i < renderers.length; i++) {
1410: setRenderer(i, renderers[i], false);
1411: }
1412: notifyListeners(new PlotChangeEvent(this));
1413: }
1414:
1415:
1423: public CategoryItemRenderer getRendererForDataset(CategoryDataset dataset) {
1424: CategoryItemRenderer result = null;
1425: for (int i = 0; i < this.datasets.size(); i++) {
1426: if (this.datasets.get(i) == dataset) {
1427: result = (CategoryItemRenderer) this.renderers.get(i);
1428: break;
1429: }
1430: }
1431: return result;
1432: }
1433:
1434:
1442: public int getIndexOf(CategoryItemRenderer renderer) {
1443: return this.renderers.indexOf(renderer);
1444: }
1445:
1446:
1453: public DatasetRenderingOrder getDatasetRenderingOrder() {
1454: return this.renderingOrder;
1455: }
1456:
1457:
1467: public void setDatasetRenderingOrder(DatasetRenderingOrder order) {
1468: if (order == null) {
1469: throw new IllegalArgumentException("Null 'order' argument.");
1470: }
1471: this.renderingOrder = order;
1472: notifyListeners(new PlotChangeEvent(this));
1473: }
1474:
1475:
1483: public SortOrder getColumnRenderingOrder() {
1484: return this.columnRenderingOrder;
1485: }
1486:
1487:
1498: public void setColumnRenderingOrder(SortOrder order) {
1499: if (order == null) {
1500: throw new IllegalArgumentException("Null 'order' argument.");
1501: }
1502: this.columnRenderingOrder = order;
1503: notifyListeners(new PlotChangeEvent(this));
1504: }
1505:
1506:
1514: public SortOrder getRowRenderingOrder() {
1515: return this.rowRenderingOrder;
1516: }
1517:
1518:
1529: public void setRowRenderingOrder(SortOrder order) {
1530: if (order == null) {
1531: throw new IllegalArgumentException("Null 'order' argument.");
1532: }
1533: this.rowRenderingOrder = order;
1534: notifyListeners(new PlotChangeEvent(this));
1535: }
1536:
1537:
1544: public boolean isDomainGridlinesVisible() {
1545: return this.domainGridlinesVisible;
1546: }
1547:
1548:
1559: public void setDomainGridlinesVisible(boolean visible) {
1560: if (this.domainGridlinesVisible != visible) {
1561: this.domainGridlinesVisible = visible;
1562: notifyListeners(new PlotChangeEvent(this));
1563: }
1564: }
1565:
1566:
1573: public CategoryAnchor getDomainGridlinePosition() {
1574: return this.domainGridlinePosition;
1575: }
1576:
1577:
1585: public void setDomainGridlinePosition(CategoryAnchor position) {
1586: if (position == null) {
1587: throw new IllegalArgumentException("Null 'position' argument.");
1588: }
1589: this.domainGridlinePosition = position;
1590: notifyListeners(new PlotChangeEvent(this));
1591: }
1592:
1593:
1600: public Stroke getDomainGridlineStroke() {
1601: return this.domainGridlineStroke;
1602: }
1603:
1604:
1612: public void setDomainGridlineStroke(Stroke stroke) {
1613: if (stroke == null) {
1614: throw new IllegalArgumentException("Null 'stroke' not permitted.");
1615: }
1616: this.domainGridlineStroke = stroke;
1617: notifyListeners(new PlotChangeEvent(this));
1618: }
1619:
1620:
1627: public Paint getDomainGridlinePaint() {
1628: return this.domainGridlinePaint;
1629: }
1630:
1631:
1639: public void setDomainGridlinePaint(Paint paint) {
1640: if (paint == null) {
1641: throw new IllegalArgumentException("Null 'paint' argument.");
1642: }
1643: this.domainGridlinePaint = paint;
1644: notifyListeners(new PlotChangeEvent(this));
1645: }
1646:
1647:
1654: public boolean isRangeGridlinesVisible() {
1655: return this.rangeGridlinesVisible;
1656: }
1657:
1658:
1667: public void setRangeGridlinesVisible(boolean visible) {
1668: if (this.rangeGridlinesVisible != visible) {
1669: this.rangeGridlinesVisible = visible;
1670: notifyListeners(new PlotChangeEvent(this));
1671: }
1672: }
1673:
1674:
1681: public Stroke getRangeGridlineStroke() {
1682: return this.rangeGridlineStroke;
1683: }
1684:
1685:
1693: public void setRangeGridlineStroke(Stroke stroke) {
1694: if (stroke == null) {
1695: throw new IllegalArgumentException("Null 'stroke' argument.");
1696: }
1697: this.rangeGridlineStroke = stroke;
1698: notifyListeners(new PlotChangeEvent(this));
1699: }
1700:
1701:
1708: public Paint getRangeGridlinePaint() {
1709: return this.rangeGridlinePaint;
1710: }
1711:
1712:
1720: public void setRangeGridlinePaint(Paint paint) {
1721: if (paint == null) {
1722: throw new IllegalArgumentException("Null 'paint' argument.");
1723: }
1724: this.rangeGridlinePaint = paint;
1725: notifyListeners(new PlotChangeEvent(this));
1726: }
1727:
1728:
1735: public LegendItemCollection getFixedLegendItems() {
1736: return this.fixedLegendItems;
1737: }
1738:
1739:
1748: public void setFixedLegendItems(LegendItemCollection items) {
1749: this.fixedLegendItems = items;
1750: notifyListeners(new PlotChangeEvent(this));
1751: }
1752:
1753:
1760: public LegendItemCollection getLegendItems() {
1761: LegendItemCollection result = this.fixedLegendItems;
1762: if (result == null) {
1763: result = new LegendItemCollection();
1764:
1765: int count = this.datasets.size();
1766: for (int datasetIndex = 0; datasetIndex < count; datasetIndex++) {
1767: CategoryDataset dataset = getDataset(datasetIndex);
1768: if (dataset != null) {
1769: CategoryItemRenderer renderer = getRenderer(datasetIndex);
1770: if (renderer != null) {
1771: int seriesCount = dataset.getRowCount();
1772: for (int i = 0; i < seriesCount; i++) {
1773: LegendItem item = renderer.getLegendItem(
1774: datasetIndex, i);
1775: if (item != null) {
1776: result.add(item);
1777: }
1778: }
1779: }
1780: }
1781: }
1782: }
1783: return result;
1784: }
1785:
1786:
1794: public void handleClick(int x, int y, PlotRenderingInfo info) {
1795:
1796: Rectangle2D dataArea = info.getDataArea();
1797: if (dataArea.contains(x, y)) {
1798:
1799: double java2D = 0.0;
1800: if (this.orientation == PlotOrientation.HORIZONTAL) {
1801: java2D = x;
1802: }
1803: else if (this.orientation == PlotOrientation.VERTICAL) {
1804: java2D = y;
1805: }
1806: RectangleEdge edge = Plot.resolveRangeAxisLocation(
1807: getRangeAxisLocation(), this.orientation);
1808: double value = getRangeAxis().java2DToValue(
1809: java2D, info.getDataArea(), edge);
1810: setAnchorValue(value);
1811: setRangeCrosshairValue(value);
1812: }
1813:
1814: }
1815:
1816:
1825: public void zoom(double percent) {
1826:
1827: if (percent > 0.0) {
1828: double range = getRangeAxis().getRange().getLength();
1829: double scaledRange = range * percent;
1830: getRangeAxis().setRange(this.anchorValue - scaledRange / 2.0,
1831: this.anchorValue + scaledRange / 2.0);
1832: }
1833: else {
1834: getRangeAxis().setAutoRange(true);
1835: }
1836:
1837: }
1838:
1839:
1846: public void datasetChanged(DatasetChangeEvent event) {
1847:
1848: int count = this.rangeAxes.size();
1849: for (int axisIndex = 0; axisIndex < count; axisIndex++) {
1850: ValueAxis yAxis = getRangeAxis(axisIndex);
1851: if (yAxis != null) {
1852: yAxis.configure();
1853: }
1854: }
1855: if (getParent() != null) {
1856: getParent().datasetChanged(event);
1857: }
1858: else {
1859: PlotChangeEvent e = new PlotChangeEvent(this);
1860: e.setType(ChartChangeEventType.DATASET_UPDATED);
1861: notifyListeners(e);
1862: }
1863:
1864: }
1865:
1866:
1871: public void rendererChanged(RendererChangeEvent event) {
1872: Plot parent = getParent();
1873: if (parent != null) {
1874: if (parent instanceof RendererChangeListener) {
1875: RendererChangeListener rcl = (RendererChangeListener) parent;
1876: rcl.rendererChanged(event);
1877: }
1878: else {
1879:
1880:
1881: throw new RuntimeException(
1882: "The renderer has changed and I don't know what to do!");
1883: }
1884: }
1885: else {
1886: configureRangeAxes();
1887: PlotChangeEvent e = new PlotChangeEvent(this);
1888: notifyListeners(e);
1889: }
1890: }
1891:
1892:
1900: public void addDomainMarker(CategoryMarker marker) {
1901: addDomainMarker(marker, Layer.FOREGROUND);
1902: }
1903:
1904:
1914: public void addDomainMarker(CategoryMarker marker, Layer layer) {
1915: addDomainMarker(0, marker, layer);
1916: }
1917:
1918:
1928: public void addDomainMarker(int index, CategoryMarker marker, Layer layer) {
1929: if (marker == null) {
1930: throw new IllegalArgumentException("Null 'marker' not permitted.");
1931: }
1932: if (layer == null) {
1933: throw new IllegalArgumentException("Null 'layer' not permitted.");
1934: }
1935: Collection markers;
1936: if (layer == Layer.FOREGROUND) {
1937: markers = (Collection) this.foregroundDomainMarkers.get(
1938: new Integer(index));
1939: if (markers == null) {
1940: markers = new java.util.ArrayList();
1941: this.foregroundDomainMarkers.put(new Integer(index), markers);
1942: }
1943: markers.add(marker);
1944: }
1945: else if (layer == Layer.BACKGROUND) {
1946: markers = (Collection) this.backgroundDomainMarkers.get(
1947: new Integer(index));
1948: if (markers == null) {
1949: markers = new java.util.ArrayList();
1950: this.backgroundDomainMarkers.put(new Integer(index), markers);
1951: }
1952: markers.add(marker);
1953: }
1954: marker.addChangeListener(this);
1955: notifyListeners(new PlotChangeEvent(this));
1956: }
1957:
1958:
1964: public void clearDomainMarkers() {
1965: if (this.backgroundDomainMarkers != null) {
1966: Set keys = this.backgroundDomainMarkers.keySet();
1967: Iterator iterator = keys.iterator();
1968: while (iterator.hasNext()) {
1969: Integer key = (Integer) iterator.next();
1970: clearDomainMarkers(key.intValue());
1971: }
1972: this.backgroundDomainMarkers.clear();
1973: }
1974: if (this.foregroundDomainMarkers != null) {
1975: Set keys = this.foregroundDomainMarkers.keySet();
1976: Iterator iterator = keys.iterator();
1977: while (iterator.hasNext()) {
1978: Integer key = (Integer) iterator.next();
1979: clearDomainMarkers(key.intValue());
1980: }
1981: this.foregroundDomainMarkers.clear();
1982: }
1983: notifyListeners(new PlotChangeEvent(this));
1984: }
1985:
1986:
1993: public Collection getDomainMarkers(Layer layer) {
1994: return getDomainMarkers(0, layer);
1995: }
1996:
1997:
2006: public Collection getDomainMarkers(int index, Layer layer) {
2007: Collection result = null;
2008: Integer key = new Integer(index);
2009: if (layer == Layer.FOREGROUND) {
2010: result = (Collection) this.foregroundDomainMarkers.get(key);
2011: }
2012: else if (layer == Layer.BACKGROUND) {
2013: result = (Collection) this.backgroundDomainMarkers.get(key);
2014: }
2015: if (result != null) {
2016: result = Collections.unmodifiableCollection(result);
2017: }
2018: return result;
2019: }
2020:
2021:
2028: public void clearDomainMarkers(int index) {
2029: Integer key = new Integer(index);
2030: if (this.backgroundDomainMarkers != null) {
2031: Collection markers
2032: = (Collection) this.backgroundDomainMarkers.get(key);
2033: if (markers != null) {
2034: Iterator iterator = markers.iterator();
2035: while (iterator.hasNext()) {
2036: Marker m = (Marker) iterator.next();
2037: m.removeChangeListener(this);
2038: }
2039: markers.clear();
2040: }
2041: }
2042: if (this.foregroundDomainMarkers != null) {
2043: Collection markers
2044: = (Collection) this.foregroundDomainMarkers.get(key);
2045: if (markers != null) {
2046: Iterator iterator = markers.iterator();
2047: while (iterator.hasNext()) {
2048: Marker m = (Marker) iterator.next();
2049: m.removeChangeListener(this);
2050: }
2051: markers.clear();
2052: }
2053: }
2054: notifyListeners(new PlotChangeEvent(this));
2055: }
2056:
2057:
2068: public boolean removeDomainMarker(Marker marker) {
2069: return removeDomainMarker(marker, Layer.FOREGROUND);
2070: }
2071:
2072:
2084: public boolean removeDomainMarker(Marker marker, Layer layer) {
2085: return removeDomainMarker(0, marker, layer);
2086: }
2087:
2088:
2101: public boolean removeDomainMarker(int index, Marker marker, Layer layer) {
2102: ArrayList markers;
2103: if (layer == Layer.FOREGROUND) {
2104: markers = (ArrayList) this.foregroundDomainMarkers.get(new Integer(
2105: index));
2106: }
2107: else {
2108: markers = (ArrayList) this.backgroundDomainMarkers.get(new Integer(
2109: index));
2110: }
2111: boolean removed = markers.remove(marker);
2112: if (removed) {
2113: notifyListeners(new PlotChangeEvent(this));
2114: }
2115: return removed;
2116: }
2117:
2118:
2126: public void addRangeMarker(Marker marker) {
2127: addRangeMarker(marker, Layer.FOREGROUND);
2128: }
2129:
2130:
2140: public void addRangeMarker(Marker marker, Layer layer) {
2141: addRangeMarker(0, marker, layer);
2142: }
2143:
2144:
2154: public void addRangeMarker(int index, Marker marker, Layer layer) {
2155: Collection markers;
2156: if (layer == Layer.FOREGROUND) {
2157: markers = (Collection) this.foregroundRangeMarkers.get(
2158: new Integer(index));
2159: if (markers == null) {
2160: markers = new java.util.ArrayList();
2161: this.foregroundRangeMarkers.put(new Integer(index), markers);
2162: }
2163: markers.add(marker);
2164: }
2165: else if (layer == Layer.BACKGROUND) {
2166: markers = (Collection) this.backgroundRangeMarkers.get(
2167: new Integer(index));
2168: if (markers == null) {
2169: markers = new java.util.ArrayList();
2170: this.backgroundRangeMarkers.put(new Integer(index), markers);
2171: }
2172: markers.add(marker);
2173: }
2174: marker.addChangeListener(this);
2175: notifyListeners(new PlotChangeEvent(this));
2176: }
2177:
2178:
2184: public void clearRangeMarkers() {
2185: if (this.backgroundRangeMarkers != null) {
2186: Set keys = this.backgroundRangeMarkers.keySet();
2187: Iterator iterator = keys.iterator();
2188: while (iterator.hasNext()) {
2189: Integer key = (Integer) iterator.next();
2190: clearRangeMarkers(key.intValue());
2191: }
2192: this.backgroundRangeMarkers.clear();
2193: }
2194: if (this.foregroundRangeMarkers != null) {
2195: Set keys = this.foregroundRangeMarkers.keySet();
2196: Iterator iterator = keys.iterator();
2197: while (iterator.hasNext()) {
2198: Integer key = (Integer) iterator.next();
2199: clearRangeMarkers(key.intValue());
2200: }
2201: this.foregroundRangeMarkers.clear();
2202: }
2203: notifyListeners(new PlotChangeEvent(this));
2204: }
2205:
2206:
2215: public Collection getRangeMarkers(Layer layer) {
2216: return getRangeMarkers(0, layer);
2217: }
2218:
2219:
2228: public Collection getRangeMarkers(int index, Layer layer) {
2229: Collection result = null;
2230: Integer key = new Integer(index);
2231: if (layer == Layer.FOREGROUND) {
2232: result = (Collection) this.foregroundRangeMarkers.get(key);
2233: }
2234: else if (layer == Layer.BACKGROUND) {
2235: result = (Collection) this.backgroundRangeMarkers.get(key);
2236: }
2237: if (result != null) {
2238: result = Collections.unmodifiableCollection(result);
2239: }
2240: return result;
2241: }
2242:
2243:
2250: public void clearRangeMarkers(int index) {
2251: Integer key = new Integer(index);
2252: if (this.backgroundRangeMarkers != null) {
2253: Collection markers
2254: = (Collection) this.backgroundRangeMarkers.get(key);
2255: if (markers != null) {
2256: Iterator iterator = markers.iterator();
2257: while (iterator.hasNext()) {
2258: Marker m = (Marker) iterator.next();
2259: m.removeChangeListener(this);
2260: }
2261: markers.clear();
2262: }
2263: }
2264: if (this.foregroundRangeMarkers != null) {
2265: Collection markers
2266: = (Collection) this.foregroundRangeMarkers.get(key);
2267: if (markers != null) {
2268: Iterator iterator = markers.iterator();
2269: while (iterator.hasNext()) {
2270: Marker m = (Marker) iterator.next();
2271: m.removeChangeListener(this);
2272: }
2273: markers.clear();
2274: }
2275: }
2276: notifyListeners(new PlotChangeEvent(this));
2277: }
2278:
2279:
2290: public boolean removeRangeMarker(Marker marker) {
2291: return removeRangeMarker(marker, Layer.FOREGROUND);
2292: }
2293:
2294:
2306: public boolean removeRangeMarker(Marker marker, Layer layer) {
2307: return removeRangeMarker(0, marker, layer);
2308: }
2309:
2310:
2323: public boolean removeRangeMarker(int index, Marker marker, Layer layer) {
2324: if (marker == null) {
2325: throw new IllegalArgumentException("Null 'marker' argument.");
2326: }
2327: ArrayList markers;
2328: if (layer == Layer.FOREGROUND) {
2329: markers = (ArrayList) this.foregroundRangeMarkers.get(new Integer(
2330: index));
2331: }
2332: else {
2333: markers = (ArrayList) this.backgroundRangeMarkers.get(new Integer(
2334: index));
2335: }
2336:
2337: boolean removed = markers.remove(marker);
2338: if (removed) {
2339: notifyListeners(new PlotChangeEvent(this));
2340: }
2341: return removed;
2342: }
2343:
2344:
2351: public boolean isRangeCrosshairVisible() {
2352: return this.rangeCrosshairVisible;
2353: }
2354:
2355:
2362: public void setRangeCrosshairVisible(boolean flag) {
2363: if (this.rangeCrosshairVisible != flag) {
2364: this.rangeCrosshairVisible = flag;
2365: notifyListeners(new PlotChangeEvent(this));
2366: }
2367: }
2368:
2369:
2377: public boolean isRangeCrosshairLockedOnData() {
2378: return this.rangeCrosshairLockedOnData;
2379: }
2380:
2381:
2389: public void setRangeCrosshairLockedOnData(boolean flag) {
2390:
2391: if (this.rangeCrosshairLockedOnData != flag) {
2392: this.rangeCrosshairLockedOnData = flag;
2393: notifyListeners(new PlotChangeEvent(this));
2394: }
2395:
2396: }
2397:
2398:
2405: public double getRangeCrosshairValue() {
2406: return this.rangeCrosshairValue;
2407: }
2408:
2409:
2419: public void setRangeCrosshairValue(double value) {
2420: setRangeCrosshairValue(value, true);
2421: }
2422:
2423:
2434: public void setRangeCrosshairValue(double value, boolean notify) {
2435: this.rangeCrosshairValue = value;
2436: if (isRangeCrosshairVisible() && notify) {
2437: notifyListeners(new PlotChangeEvent(this));
2438: }
2439: }
2440:
2441:
2451: public Stroke getRangeCrosshairStroke() {
2452: return this.rangeCrosshairStroke;
2453: }
2454:
2455:
2465: public void setRangeCrosshairStroke(Stroke stroke) {
2466: if (stroke == null) {
2467: throw new IllegalArgumentException("Null 'stroke' argument.");
2468: }
2469: this.rangeCrosshairStroke = stroke;
2470: notifyListeners(new PlotChangeEvent(this));
2471: }
2472:
2473:
2482: public Paint getRangeCrosshairPaint() {
2483: return this.rangeCrosshairPaint;
2484: }
2485:
2486:
2494: public void setRangeCrosshairPaint(Paint paint) {
2495: if (paint == null) {
2496: throw new IllegalArgumentException("Null 'paint' argument.");
2497: }
2498: this.rangeCrosshairPaint = paint;
2499: notifyListeners(new PlotChangeEvent(this));
2500: }
2501:
2502:
2507: public List getAnnotations() {
2508: return this.annotations;
2509: }
2510:
2511:
2519: public void addAnnotation(CategoryAnnotation annotation) {
2520: if (annotation == null) {
2521: throw new IllegalArgumentException("Null 'annotation' argument.");
2522: }
2523: this.annotations.add(annotation);
2524: notifyListeners(new PlotChangeEvent(this));
2525: }
2526:
2527:
2537: public boolean removeAnnotation(CategoryAnnotation annotation) {
2538: if (annotation == null) {
2539: throw new IllegalArgumentException("Null 'annotation' argument.");
2540: }
2541: boolean removed = this.annotations.remove(annotation);
2542: if (removed) {
2543: notifyListeners(new PlotChangeEvent(this));
2544: }
2545: return removed;
2546: }
2547:
2548:
2552: public void clearAnnotations() {
2553: this.annotations.clear();
2554: notifyListeners(new PlotChangeEvent(this));
2555: }
2556:
2557:
2566: protected AxisSpace calculateDomainAxisSpace(Graphics2D g2,
2567: Rectangle2D plotArea,
2568: AxisSpace space) {
2569:
2570: if (space == null) {
2571: space = new AxisSpace();
2572: }
2573:
2574:
2575: if (this.fixedDomainAxisSpace != null) {
2576: if (this.orientation == PlotOrientation.HORIZONTAL) {
2577: space.ensureAtLeast(
2578: this.fixedDomainAxisSpace.getLeft(), RectangleEdge.LEFT);
2579: space.ensureAtLeast(this.fixedDomainAxisSpace.getRight(),
2580: RectangleEdge.RIGHT);
2581: }
2582: else if (this.orientation == PlotOrientation.VERTICAL) {
2583: space.ensureAtLeast(this.fixedDomainAxisSpace.getTop(),
2584: RectangleEdge.TOP);
2585: space.ensureAtLeast(this.fixedDomainAxisSpace.getBottom(),
2586: RectangleEdge.BOTTOM);
2587: }
2588: }
2589: else {
2590:
2591: RectangleEdge domainEdge = Plot.resolveDomainAxisLocation(
2592: getDomainAxisLocation(), this.orientation);
2593: if (this.drawSharedDomainAxis) {
2594: space = getDomainAxis().reserveSpace(g2, this, plotArea,
2595: domainEdge, space);
2596: }
2597:
2598:
2599: for (int i = 0; i < this.domainAxes.size(); i++) {
2600: Axis xAxis = (Axis) this.domainAxes.get(i);
2601: if (xAxis != null) {
2602: RectangleEdge edge = getDomainAxisEdge(i);
2603: space = xAxis.reserveSpace(g2, this, plotArea, edge, space);
2604: }
2605: }
2606: }
2607:
2608: return space;
2609:
2610: }
2611:
2612:
2621: protected AxisSpace calculateRangeAxisSpace(Graphics2D g2,
2622: Rectangle2D plotArea,
2623: AxisSpace space) {
2624:
2625: if (space == null) {
2626: space = new AxisSpace();
2627: }
2628:
2629:
2630: if (this.fixedRangeAxisSpace != null) {
2631: if (this.orientation == PlotOrientation.HORIZONTAL) {
2632: space.ensureAtLeast(this.fixedRangeAxisSpace.getTop(),
2633: RectangleEdge.TOP);
2634: space.ensureAtLeast(this.fixedRangeAxisSpace.getBottom(),
2635: RectangleEdge.BOTTOM);
2636: }
2637: else if (this.orientation == PlotOrientation.VERTICAL) {
2638: space.ensureAtLeast(this.fixedRangeAxisSpace.getLeft(),
2639: RectangleEdge.LEFT);
2640: space.ensureAtLeast(this.fixedRangeAxisSpace.getRight(),
2641: RectangleEdge.RIGHT);
2642: }
2643: }
2644: else {
2645:
2646: for (int i = 0; i < this.rangeAxes.size(); i++) {
2647: Axis yAxis = (Axis) this.rangeAxes.get(i);
2648: if (yAxis != null) {
2649: RectangleEdge edge = getRangeAxisEdge(i);
2650: space = yAxis.reserveSpace(g2, this, plotArea, edge, space);
2651: }
2652: }
2653: }
2654: return space;
2655:
2656: }
2657:
2658:
2666: protected AxisSpace calculateAxisSpace(Graphics2D g2,
2667: Rectangle2D plotArea) {
2668: AxisSpace space = new AxisSpace();
2669: space = calculateRangeAxisSpace(g2, plotArea, space);
2670: space = calculateDomainAxisSpace(g2, plotArea, space);
2671: return space;
2672: }
2673:
2674:
2690: public void draw(Graphics2D g2, Rectangle2D area,
2691: Point2D anchor,
2692: PlotState parentState,
2693: PlotRenderingInfo state) {
2694:
2695:
2696: boolean b1 = (area.getWidth() <= MINIMUM_WIDTH_TO_DRAW);
2697: boolean b2 = (area.getHeight() <= MINIMUM_HEIGHT_TO_DRAW);
2698: if (b1 || b2) {
2699: return;
2700: }
2701:
2702:
2703: if (state == null) {
2704:
2705:
2706:
2707: state = new PlotRenderingInfo(null);
2708: }
2709: state.setPlotArea(area);
2710:
2711:
2712: RectangleInsets insets = getInsets();
2713: insets.trim(area);
2714:
2715:
2716: AxisSpace space = calculateAxisSpace(g2, area);
2717: Rectangle2D dataArea = space.shrink(area, null);
2718: this.axisOffset.trim(dataArea);
2719:
2720: state.setDataArea(dataArea);
2721:
2722:
2723:
2724: if (getRenderer() != null) {
2725: getRenderer().drawBackground(g2, this, dataArea);
2726: }
2727: else {
2728: drawBackground(g2, dataArea);
2729: }
2730:
2731: Map axisStateMap = drawAxes(g2, area, dataArea, state);
2732:
2733:
2734: Shape savedClip = g2.getClip();
2735: g2.clip(dataArea);
2736:
2737: drawDomainGridlines(g2, dataArea);
2738:
2739: AxisState rangeAxisState = (AxisState) axisStateMap.get(getRangeAxis());
2740: if (rangeAxisState == null) {
2741: if (parentState != null) {
2742: rangeAxisState = (AxisState) parentState.getSharedAxisStates()
2743: .get(getRangeAxis());
2744: }
2745: }
2746: if (rangeAxisState != null) {
2747: drawRangeGridlines(g2, dataArea, rangeAxisState.getTicks());
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:
2761:
2762: Composite originalComposite = g2.getComposite();
2763: g2.setComposite(AlphaComposite.getInstance(
2764: AlphaComposite.SRC_OVER, getForegroundAlpha()));
2765:
2766: DatasetRenderingOrder order = getDatasetRenderingOrder();
2767: if (order == DatasetRenderingOrder.FORWARD) {
2768: for (int i = 0; i < this.datasets.size(); i++) {
2769: foundData = render(g2, dataArea, i, state) || foundData;
2770: }
2771: }
2772: else {
2773: for (int i = this.datasets.size() - 1; i >= 0; i--) {
2774: foundData = render(g2, dataArea, i, state) || foundData;
2775: }
2776: }
2777:
2778: for (int i = 0; i < this.renderers.size(); i++) {
2779: drawDomainMarkers(g2, dataArea, i, Layer.FOREGROUND);
2780: }
2781: for (int i = 0; i < this.renderers.size(); i++) {
2782: drawRangeMarkers(g2, dataArea, i, Layer.FOREGROUND);
2783: }
2784:
2785:
2786: drawAnnotations(g2, dataArea);
2787:
2788: g2.setClip(savedClip);
2789: g2.setComposite(originalComposite);
2790:
2791: if (!foundData) {
2792: drawNoDataMessage(g2, dataArea);
2793: }
2794:
2795:
2796: if (isRangeCrosshairVisible()) {
2797:
2798: drawRangeCrosshair(g2, dataArea, getOrientation(),
2799: getRangeCrosshairValue(), getRangeAxis(),
2800: getRangeCrosshairStroke(), getRangeCrosshairPaint());
2801: }
2802:
2803:
2804: if (getRenderer() != null) {
2805: getRenderer().drawOutline(g2, this, dataArea);
2806: }
2807: else {
2808: drawOutline(g2, dataArea);
2809: }
2810:
2811: }
2812:
2813:
2823: public void drawBackground(Graphics2D g2, Rectangle2D area) {
2824: fillBackground(g2, area, this.orientation);
2825: drawBackgroundImage(g2, area);
2826: }
2827:
2828:
2839: protected Map drawAxes(Graphics2D g2,
2840: Rectangle2D plotArea,
2841: Rectangle2D dataArea,
2842: PlotRenderingInfo plotState) {
2843:
2844: AxisCollection axisCollection = new AxisCollection();
2845:
2846:
2847: for (int index = 0; index < this.domainAxes.size(); index++) {
2848: CategoryAxis xAxis = (CategoryAxis) this.domainAxes.get(index);
2849: if (xAxis != null) {
2850: axisCollection.add(xAxis, getDomainAxisEdge(index));
2851: }
2852: }
2853:
2854:
2855: for (int index = 0; index < this.rangeAxes.size(); index++) {
2856: ValueAxis yAxis = (ValueAxis) this.rangeAxes.get(index);
2857: if (yAxis != null) {
2858: axisCollection.add(yAxis, getRangeAxisEdge(index));
2859: }
2860: }
2861:
2862: Map axisStateMap = new HashMap();
2863:
2864:
2865: double cursor = dataArea.getMinY() - this.axisOffset.calculateTopOutset(
2866: dataArea.getHeight());
2867: Iterator iterator = axisCollection.getAxesAtTop().iterator();
2868: while (iterator.hasNext()) {
2869: Axis axis = (Axis) iterator.next();
2870: if (axis != null) {
2871: AxisState axisState = axis.draw(g2, cursor, plotArea, dataArea,
2872: RectangleEdge.TOP, plotState);
2873: cursor = axisState.getCursor();
2874: axisStateMap.put(axis, axisState);
2875: }
2876: }
2877:
2878:
2879: cursor = dataArea.getMaxY()
2880: + this.axisOffset.calculateBottomOutset(dataArea.getHeight());
2881: iterator = axisCollection.getAxesAtBottom().iterator();
2882: while (iterator.hasNext()) {
2883: Axis axis = (Axis) iterator.next();
2884: if (axis != null) {
2885: AxisState axisState = axis.draw(g2, cursor, plotArea, dataArea,
2886: RectangleEdge.BOTTOM, plotState);
2887: cursor = axisState.getCursor();
2888: axisStateMap.put(axis, axisState);
2889: }
2890: }
2891:
2892:
2893: cursor = dataArea.getMinX()
2894: - this.axisOffset.calculateLeftOutset(dataArea.getWidth());
2895: iterator = axisCollection.getAxesAtLeft().iterator();
2896: while (iterator.hasNext()) {
2897: Axis axis = (Axis) iterator.next();
2898: if (axis != null) {
2899: AxisState axisState = axis.draw(g2, cursor, plotArea, dataArea,
2900: RectangleEdge.LEFT, plotState);
2901: cursor = axisState.getCursor();
2902: axisStateMap.put(axis, axisState);
2903: }
2904: }
2905:
2906:
2907: cursor = dataArea.getMaxX()
2908: + this.axisOffset.calculateRightOutset(dataArea.getWidth());
2909: iterator = axisCollection.getAxesAtRight().iterator();
2910: while (iterator.hasNext()) {
2911: Axis axis = (Axis) iterator.next();
2912: if (axis != null) {
2913: AxisState axisState = axis.draw(g2, cursor, plotArea, dataArea,
2914: RectangleEdge.RIGHT, plotState);
2915: cursor = axisState.getCursor();
2916: axisStateMap.put(axis, axisState);
2917: }
2918: }
2919:
2920: return axisStateMap;
2921:
2922: }
2923:
2924:
2935: public boolean render(Graphics2D g2, Rectangle2D dataArea, int index,
2936: PlotRenderingInfo info) {
2937:
2938: boolean foundData = false;
2939: CategoryDataset currentDataset = getDataset(index);
2940: CategoryItemRenderer renderer = getRenderer(index);
2941: CategoryAxis domainAxis = getDomainAxisForDataset(index);
2942: ValueAxis rangeAxis = getRangeAxisForDataset(index);
2943: boolean hasData = !DatasetUtilities.isEmptyOrNull(currentDataset);
2944: if (hasData && renderer != null) {
2945:
2946: foundData = true;
2947: CategoryItemRendererState state = renderer.initialise(g2, dataArea,
2948: this, index, info);
2949: int columnCount = currentDataset.getColumnCount();
2950: int rowCount = currentDataset.getRowCount();
2951: int passCount = renderer.getPassCount();
2952: for (int pass = 0; pass < passCount; pass++) {
2953: if (this.columnRenderingOrder == SortOrder.ASCENDING) {
2954: for (int column = 0; column < columnCount; column++) {
2955: if (this.rowRenderingOrder == SortOrder.ASCENDING) {
2956: for (int row = 0; row < rowCount; row++) {
2957: renderer.drawItem(g2, state, dataArea, this,
2958: domainAxis, rangeAxis, currentDataset,
2959: row, column, pass);
2960: }
2961: }
2962: else {
2963: for (int row = rowCount - 1; row >= 0; row--) {
2964: renderer.drawItem(g2, state, dataArea, this,
2965: domainAxis, rangeAxis, currentDataset,
2966: row, column, pass);
2967: }
2968: }
2969: }
2970: }
2971: else {
2972: for (int column = columnCount - 1; column >= 0; column--) {
2973: if (this.rowRenderingOrder == SortOrder.ASCENDING) {
2974: for (int row = 0; row < rowCount; row++) {
2975: renderer.drawItem(g2, state, dataArea, this,
2976: domainAxis, rangeAxis, currentDataset,
2977: row, column, pass);
2978: }
2979: }
2980: else {
2981: for (int row = rowCount - 1; row >= 0; row--) {
2982: renderer.drawItem(g2, state, dataArea, this,
2983: domainAxis, rangeAxis, currentDataset,
2984: row, column, pass);
2985: }
2986: }
2987: }
2988: }
2989: }
2990: }
2991: return foundData;
2992:
2993: }
2994:
2995:
3003: protected void drawDomainGridlines(Graphics2D g2, Rectangle2D dataArea) {
3004:
3005:
3006: if (isDomainGridlinesVisible()) {
3007: CategoryAnchor anchor = getDomainGridlinePosition();
3008: RectangleEdge domainAxisEdge = getDomainAxisEdge();
3009: Stroke gridStroke = getDomainGridlineStroke();
3010: Paint gridPaint = getDomainGridlinePaint();
3011: if ((gridStroke != null) && (gridPaint != null)) {
3012:
3013: CategoryDataset data = getDataset();
3014: if (data != null) {
3015: CategoryAxis axis = getDomainAxis();
3016: if (axis != null) {
3017: int columnCount = data.getColumnCount();
3018: for (int c = 0; c < columnCount; c++) {
3019: double xx = axis.getCategoryJava2DCoordinate(
3020: anchor, c, columnCount, dataArea,
3021: domainAxisEdge);
3022: CategoryItemRenderer renderer1 = getRenderer();
3023: if (renderer1 != null) {
3024: renderer1.drawDomainGridline(g2, this,
3025: dataArea, xx);
3026: }
3027: }
3028: }
3029: }
3030: }
3031: }
3032: }
3033:
3034:
3043: protected void drawRangeGridlines(Graphics2D g2, Rectangle2D dataArea,
3044: List ticks) {
3045:
3046: if (isRangeGridlinesVisible()) {
3047: Stroke gridStroke = getRangeGridlineStroke();
3048: Paint gridPaint = getRangeGridlinePaint();
3049: if ((gridStroke != null) && (gridPaint != null)) {
3050: ValueAxis axis = getRangeAxis();
3051: if (axis != null) {
3052: Iterator iterator = ticks.iterator();
3053: while (iterator.hasNext()) {
3054: ValueTick tick = (ValueTick) iterator.next();
3055: CategoryItemRenderer renderer1 = getRenderer();
3056: if (renderer1 != null) {
3057: renderer1.drawRangeGridline(g2, this,
3058: getRangeAxis(), dataArea, tick.getValue());
3059: }
3060: }
3061: }
3062: }
3063: }
3064: }
3065:
3066:
3072: protected void drawAnnotations(Graphics2D g2, Rectangle2D dataArea) {
3073:
3074: if (getAnnotations() != null) {
3075: Iterator iterator = getAnnotations().iterator();
3076: while (iterator.hasNext()) {
3077: CategoryAnnotation annotation
3078: = (CategoryAnnotation) iterator.next();
3079: annotation.draw(g2, this, dataArea, getDomainAxis(),
3080: getRangeAxis());
3081: }
3082: }
3083:
3084: }
3085:
3086:
3097: protected void drawDomainMarkers(Graphics2D g2, Rectangle2D dataArea,
3098: int index, Layer layer) {
3099:
3100: CategoryItemRenderer r = getRenderer(index);
3101: if (r == null) {
3102: return;
3103: }
3104:
3105: Collection markers = getDomainMarkers(index, layer);
3106: CategoryAxis axis = getDomainAxisForDataset(index);
3107: if (markers != null && axis != null) {
3108: Iterator iterator = markers.iterator();
3109: while (iterator.hasNext()) {
3110: CategoryMarker marker = (CategoryMarker) iterator.next();
3111: r.drawDomainMarker(g2, this, axis, marker, dataArea);
3112: }
3113: }
3114:
3115: }
3116:
3117:
3128: protected void drawRangeMarkers(Graphics2D g2, Rectangle2D dataArea,
3129: int index, Layer layer) {
3130:
3131: CategoryItemRenderer r = getRenderer(index);
3132: if (r == null) {
3133: return;
3134: }
3135:
3136: Collection markers = getRangeMarkers(index, layer);
3137: ValueAxis axis = getRangeAxisForDataset(index);
3138: if (markers != null && axis != null) {
3139: Iterator iterator = markers.iterator();
3140: while (iterator.hasNext()) {
3141: Marker marker = (Marker) iterator.next();
3142: r.drawRangeMarker(g2, this, axis, marker, dataArea);
3143: }
3144: }
3145:
3146: }
3147:
3148:
3158: protected void drawRangeLine(Graphics2D g2, Rectangle2D dataArea,
3159: double value, Stroke stroke, Paint paint) {
3160:
3161: double java2D = getRangeAxis().valueToJava2D(value, dataArea,
3162: getRangeAxisEdge());
3163: Line2D line = null;
3164: if (this.orientation == PlotOrientation.HORIZONTAL) {
3165: line = new Line2D.Double(java2D, dataArea.getMinY(), java2D,
3166: dataArea.getMaxY());
3167: }
3168: else if (this.orientation == PlotOrientation.VERTICAL) {
3169: line = new Line2D.Double(dataArea.getMinX(), java2D,
3170: dataArea.getMaxX(), java2D);
3171: }
3172: g2.setStroke(stroke);
3173: g2.setPaint(paint);
3174: g2.draw(line);
3175:
3176: }
3177:
3178:
3191: protected void drawRangeCrosshair(Graphics2D g2, Rectangle2D dataArea,
3192: PlotOrientation orientation, double value, ValueAxis axis,
3193: Stroke stroke, Paint paint) {
3194:
3195: if (!axis.getRange().contains(value)) {
3196: return;
3197: }
3198: Line2D line = null;
3199: if (orientation == PlotOrientation.HORIZONTAL) {
3200: double xx = axis.valueToJava2D(value, dataArea,
3201: RectangleEdge.BOTTOM);
3202: line = new Line2D.Double(xx, dataArea.getMinY(), xx,
3203: dataArea.getMaxY());
3204: }
3205: else {
3206: double yy = axis.valueToJava2D(value, dataArea,
3207: RectangleEdge.LEFT);
3208: line = new Line2D.Double(dataArea.getMinX(), yy,
3209: dataArea.getMaxX(), yy);
3210: }
3211: g2.setStroke(stroke);
3212: g2.setPaint(paint);
3213: g2.draw(line);
3214:
3215: }
3216:
3217:
3226: public Range getDataRange(ValueAxis axis) {
3227:
3228: Range result = null;
3229: List mappedDatasets = new ArrayList();
3230:
3231: int rangeIndex = this.rangeAxes.indexOf(axis);
3232: if (rangeIndex >= 0) {
3233: mappedDatasets.addAll(datasetsMappedToRangeAxis(rangeIndex));
3234: }
3235: else if (axis == getRangeAxis()) {
3236: mappedDatasets.addAll(datasetsMappedToRangeAxis(0));
3237: }
3238:
3239:
3240:
3241: Iterator iterator = mappedDatasets.iterator();
3242: while (iterator.hasNext()) {
3243: CategoryDataset d = (CategoryDataset) iterator.next();
3244: CategoryItemRenderer r = getRendererForDataset(d);
3245: if (r != null) {
3246: result = Range.combine(result, r.findRangeBounds(d));
3247: }
3248: }
3249: return result;
3250:
3251: }
3252:
3253:
3263: private List datasetsMappedToDomainAxis(int axisIndex) {
3264: List result = new ArrayList();
3265: for (int datasetIndex = 0; datasetIndex < this.datasets.size();
3266: datasetIndex++) {
3267: Object dataset = this.datasets.get(datasetIndex);
3268: if (dataset != null) {
3269: Integer m = (Integer) this.datasetToDomainAxisMap.get(
3270: datasetIndex);
3271: if (m == null) {
3272:
3273: if (axisIndex == 0) {
3274: result.add(dataset);
3275: }
3276: }
3277: else {
3278: if (m.intValue() == axisIndex) {
3279: result.add(dataset);
3280: }
3281: }
3282: }
3283: }
3284: return result;
3285: }
3286:
3287:
3295: private List datasetsMappedToRangeAxis(int index) {
3296: List result = new ArrayList();
3297: for (int i = 0; i < this.datasets.size(); i++) {
3298: Object dataset = this.datasets.get(i);
3299: if (dataset != null) {
3300: Integer m = (Integer) this.datasetToRangeAxisMap.get(i);
3301: if (m == null) {
3302:
3303: if (index == 0) {
3304: result.add(dataset);
3305: }
3306: }
3307: else {
3308: if (m.intValue() == index) {
3309: result.add(dataset);
3310: }
3311: }
3312: }
3313: }
3314: return result;
3315: }
3316:
3317:
3325: public int getWeight() {
3326: return this.weight;
3327: }
3328:
3329:
3337: public void setWeight(int weight) {
3338: this.weight = weight;
3339: notifyListeners(new PlotChangeEvent(this));
3340: }
3341:
3342:
3349: public AxisSpace getFixedDomainAxisSpace() {
3350: return this.fixedDomainAxisSpace;
3351: }
3352:
3353:
3361: public void setFixedDomainAxisSpace(AxisSpace space) {
3362: setFixedDomainAxisSpace(space, true);
3363: }
3364:
3365:
3376: public void setFixedDomainAxisSpace(AxisSpace space, boolean notify) {
3377: this.fixedDomainAxisSpace = space;
3378: if (notify) {
3379: notifyListeners(new PlotChangeEvent(this));
3380: }
3381: }
3382:
3383:
3390: public AxisSpace getFixedRangeAxisSpace() {
3391: return this.fixedRangeAxisSpace;
3392: }
3393:
3394:
3402: public void setFixedRangeAxisSpace(AxisSpace space) {
3403: setFixedRangeAxisSpace(space, true);
3404: }
3405:
3406:
3417: public void setFixedRangeAxisSpace(AxisSpace space, boolean notify) {
3418: this.fixedRangeAxisSpace = space;
3419: if (notify) {
3420: notifyListeners(new PlotChangeEvent(this));
3421: }
3422: }
3423:
3424:
3431: public List getCategories() {
3432: List result = null;
3433: if (getDataset() != null) {
3434: result = Collections.unmodifiableList(getDataset().getColumnKeys());
3435: }
3436: return result;
3437: }
3438:
3439:
3449: public List getCategoriesForAxis(CategoryAxis axis) {
3450: List result = new ArrayList();
3451: int axisIndex = this.domainAxes.indexOf(axis);
3452: List datasets = datasetsMappedToDomainAxis(axisIndex);
3453: Iterator iterator = datasets.iterator();
3454: while (iterator.hasNext()) {
3455: CategoryDataset dataset = (CategoryDataset) iterator.next();
3456:
3457: for (int i = 0; i < dataset.getColumnCount(); i++) {
3458: Comparable category = dataset.getColumnKey(i);
3459: if (!result.contains(category)) {
3460: result.add(category);
3461: }
3462: }
3463: }
3464: return result;
3465: }
3466:
3467:
3475: public boolean getDrawSharedDomainAxis() {
3476: return this.drawSharedDomainAxis;
3477: }
3478:
3479:
3487: public void setDrawSharedDomainAxis(boolean draw) {
3488: this.drawSharedDomainAxis = draw;
3489: notifyListeners(new PlotChangeEvent(this));
3490: }
3491:
3492:
3500: public boolean isDomainZoomable() {
3501: return false;
3502: }
3503:
3504:
3511: public boolean isRangeZoomable() {
3512: return true;
3513: }
3514:
3515:
3523: public void zoomDomainAxes(double factor, PlotRenderingInfo state,
3524: Point2D source) {
3525:
3526: }
3527:
3528:
3537: public void zoomDomainAxes(double lowerPercent, double upperPercent,
3538: PlotRenderingInfo state, Point2D source) {
3539:
3540: }
3541:
3542:
3555: public void zoomDomainAxes(double factor, PlotRenderingInfo info,
3556: Point2D source, boolean useAnchor) {
3557:
3558: }
3559:
3560:
3567: public void zoomRangeAxes(double factor, PlotRenderingInfo state,
3568: Point2D source) {
3569:
3570: zoomRangeAxes(factor, state, source, false);
3571: }
3572:
3573:
3586: public void zoomRangeAxes(double factor, PlotRenderingInfo info,
3587: Point2D source, boolean useAnchor) {
3588:
3589:
3590: for (int i = 0; i < this.rangeAxes.size(); i++) {
3591: ValueAxis rangeAxis = (ValueAxis) this.rangeAxes.get(i);
3592: if (rangeAxis != null) {
3593: if (useAnchor) {
3594:
3595:
3596: double sourceY = source.getY();
3597: if (this.orientation == PlotOrientation.HORIZONTAL) {
3598: sourceY = source.getX();
3599: }
3600: double anchorY = rangeAxis.java2DToValue(sourceY,
3601: info.getDataArea(), getRangeAxisEdge());
3602: rangeAxis.resizeRange(factor, anchorY);
3603: }
3604: else {
3605: rangeAxis.resizeRange(factor);
3606: }
3607: }
3608: }
3609: }
3610:
3611:
3619: public void zoomRangeAxes(double lowerPercent, double upperPercent,
3620: PlotRenderingInfo state, Point2D source) {
3621: for (int i = 0; i < this.rangeAxes.size(); i++) {
3622: ValueAxis rangeAxis = (ValueAxis) this.rangeAxes.get(i);
3623: if (rangeAxis != null) {
3624: rangeAxis.zoomRange(lowerPercent, upperPercent);
3625: }
3626: }
3627: }
3628:
3629:
3636: public double getAnchorValue() {
3637: return this.anchorValue;
3638: }
3639:
3640:
3648: public void setAnchorValue(double value) {
3649: setAnchorValue(value, true);
3650: }
3651:
3652:
3661: public void setAnchorValue(double value, boolean notify) {
3662: this.anchorValue = value;
3663: if (notify) {
3664: notifyListeners(new PlotChangeEvent(this));
3665: }
3666: }
3667:
3668:
3675: public boolean equals(Object obj) {
3676:
3677: if (obj == this) {
3678: return true;
3679: }
3680: if (!(obj instanceof CategoryPlot)) {
3681: return false;
3682: }
3683: if (!super.equals(obj)) {
3684: return false;
3685: }
3686:
3687: CategoryPlot that = (CategoryPlot) obj;
3688:
3689: if (this.orientation != that.orientation) {
3690: return false;
3691: }
3692: if (!ObjectUtilities.equal(this.axisOffset, that.axisOffset)) {
3693: return false;
3694: }
3695: if (!this.domainAxes.equals(that.domainAxes)) {
3696: return false;
3697: }
3698: if (!this.domainAxisLocations.equals(that.domainAxisLocations)) {
3699: return false;
3700: }
3701: if (this.drawSharedDomainAxis != that.drawSharedDomainAxis) {
3702: return false;
3703: }
3704: if (!this.rangeAxes.equals(that.rangeAxes)) {
3705: return false;
3706: }
3707: if (!this.rangeAxisLocations.equals(that.rangeAxisLocations)) {
3708: return false;
3709: }
3710: if (!ObjectUtilities.equal(this.datasetToDomainAxisMap,
3711: that.datasetToDomainAxisMap)) {
3712: return false;
3713: }
3714: if (!ObjectUtilities.equal(this.datasetToRangeAxisMap,
3715: that.datasetToRangeAxisMap)) {
3716: return false;
3717: }
3718: if (!ObjectUtilities.equal(this.renderers, that.renderers)) {
3719: return false;
3720: }
3721: if (this.renderingOrder != that.renderingOrder) {
3722: return false;
3723: }
3724: if (this.columnRenderingOrder != that.columnRenderingOrder) {
3725: return false;
3726: }
3727: if (this.rowRenderingOrder != that.rowRenderingOrder) {
3728: return false;
3729: }
3730: if (this.domainGridlinesVisible != that.domainGridlinesVisible) {
3731: return false;
3732: }
3733: if (this.domainGridlinePosition != that.domainGridlinePosition) {
3734: return false;
3735: }
3736: if (!ObjectUtilities.equal(this.domainGridlineStroke,
3737: that.domainGridlineStroke)) {
3738: return false;
3739: }
3740: if (!PaintUtilities.equal(this.domainGridlinePaint,
3741: that.domainGridlinePaint)) {
3742: return false;
3743: }
3744: if (this.rangeGridlinesVisible != that.rangeGridlinesVisible) {
3745: return false;
3746: }
3747: if (!ObjectUtilities.equal(this.rangeGridlineStroke,
3748: that.rangeGridlineStroke)) {
3749: return false;
3750: }
3751: if (!PaintUtilities.equal(this.rangeGridlinePaint,
3752: that.rangeGridlinePaint)) {
3753: return false;
3754: }
3755: if (this.anchorValue != that.anchorValue) {
3756: return false;
3757: }
3758: if (this.rangeCrosshairVisible != that.rangeCrosshairVisible) {
3759: return false;
3760: }
3761: if (this.rangeCrosshairValue != that.rangeCrosshairValue) {
3762: return false;
3763: }
3764: if (!ObjectUtilities.equal(this.rangeCrosshairStroke,
3765: that.rangeCrosshairStroke)) {
3766: return false;
3767: }
3768: if (!PaintUtilities.equal(this.rangeCrosshairPaint,
3769: that.rangeCrosshairPaint)) {
3770: return false;
3771: }
3772: if (this.rangeCrosshairLockedOnData
3773: != that.rangeCrosshairLockedOnData) {
3774: return false;
3775: }
3776: if (!ObjectUtilities.equal(this.foregroundRangeMarkers,
3777: that.foregroundRangeMarkers)) {
3778: return false;
3779: }
3780: if (!ObjectUtilities.equal(this.backgroundRangeMarkers,
3781: that.backgroundRangeMarkers)) {
3782: return false;
3783: }
3784: if (!ObjectUtilities.equal(this.annotations, that.annotations)) {
3785: return false;
3786: }
3787: if (this.weight != that.weight) {
3788: return false;
3789: }
3790: if (!ObjectUtilities.equal(this.fixedDomainAxisSpace,
3791: that.fixedDomainAxisSpace)) {
3792: return false;
3793: }
3794: if (!ObjectUtilities.equal(this.fixedRangeAxisSpace,
3795: that.fixedRangeAxisSpace)) {
3796: return false;
3797: }
3798:
3799: return true;
3800:
3801: }
3802:
3803:
3810: public Object clone() throws CloneNotSupportedException {
3811:
3812: CategoryPlot clone = (CategoryPlot) super.clone();
3813:
3814: clone.domainAxes = new ObjectList();
3815: for (int i = 0; i < this.domainAxes.size(); i++) {
3816: CategoryAxis xAxis = (CategoryAxis) this.domainAxes.get(i);
3817: if (xAxis != null) {
3818: CategoryAxis clonedAxis = (CategoryAxis) xAxis.clone();
3819: clone.setDomainAxis(i, clonedAxis);
3820: }
3821: }
3822: clone.domainAxisLocations
3823: = (ObjectList) this.domainAxisLocations.clone();
3824:
3825: clone.rangeAxes = new ObjectList();
3826: for (int i = 0; i < this.rangeAxes.size(); i++) {
3827: ValueAxis yAxis = (ValueAxis) this.rangeAxes.get(i);
3828: if (yAxis != null) {
3829: ValueAxis clonedAxis = (ValueAxis) yAxis.clone();
3830: clone.setRangeAxis(i, clonedAxis);
3831: }
3832: }
3833: clone.rangeAxisLocations = (ObjectList) this.rangeAxisLocations.clone();
3834:
3835: clone.datasets = (ObjectList) this.datasets.clone();
3836: for (int i = 0; i < clone.datasets.size(); i++) {
3837: CategoryDataset dataset = clone.getDataset(i);
3838: if (dataset != null) {
3839: dataset.addChangeListener(clone);
3840: }
3841: }
3842: clone.datasetToDomainAxisMap
3843: = (ObjectList) this.datasetToDomainAxisMap.clone();
3844: clone.datasetToRangeAxisMap
3845: = (ObjectList) this.datasetToRangeAxisMap.clone();
3846: clone.renderers = (ObjectList) this.renderers.clone();
3847: if (this.fixedDomainAxisSpace != null) {
3848: clone.fixedDomainAxisSpace = (AxisSpace) ObjectUtilities.clone(
3849: this.fixedDomainAxisSpace);
3850: }
3851: if (this.fixedRangeAxisSpace != null) {
3852: clone.fixedRangeAxisSpace = (AxisSpace) ObjectUtilities.clone(
3853: this.fixedRangeAxisSpace);
3854: }
3855:
3856: return clone;
3857:
3858: }
3859:
3860:
3867: private void writeObject(ObjectOutputStream stream) throws IOException {
3868: stream.defaultWriteObject();
3869: SerialUtilities.writeStroke(this.domainGridlineStroke, stream);
3870: SerialUtilities.writePaint(this.domainGridlinePaint, stream);
3871: SerialUtilities.writeStroke(this.rangeGridlineStroke, stream);
3872: SerialUtilities.writePaint(this.rangeGridlinePaint, stream);
3873: SerialUtilities.writeStroke(this.rangeCrosshairStroke, stream);
3874: SerialUtilities.writePaint(this.rangeCrosshairPaint, stream);
3875: }
3876:
3877:
3885: private void readObject(ObjectInputStream stream)
3886: throws IOException, ClassNotFoundException {
3887:
3888: stream.defaultReadObject();
3889: this.domainGridlineStroke = SerialUtilities.readStroke(stream);
3890: this.domainGridlinePaint = SerialUtilities.readPaint(stream);
3891: this.rangeGridlineStroke = SerialUtilities.readStroke(stream);
3892: this.rangeGridlinePaint = SerialUtilities.readPaint(stream);
3893: this.rangeCrosshairStroke = SerialUtilities.readStroke(stream);
3894: this.rangeCrosshairPaint = SerialUtilities.readPaint(stream);
3895:
3896: for (int i = 0; i < this.domainAxes.size(); i++) {
3897: CategoryAxis xAxis = (CategoryAxis) this.domainAxes.get(i);
3898: if (xAxis != null) {
3899: xAxis.setPlot(this);
3900: xAxis.addChangeListener(this);
3901: }
3902: }
3903: for (int i = 0; i < this.rangeAxes.size(); i++) {
3904: ValueAxis yAxis = (ValueAxis) this.rangeAxes.get(i);
3905: if (yAxis != null) {
3906: yAxis.setPlot(this);
3907: yAxis.addChangeListener(this);
3908: }
3909: }
3910: int datasetCount = this.datasets.size();
3911: for (int i = 0; i < datasetCount; i++) {
3912: Dataset dataset = (Dataset) this.datasets.get(i);
3913: if (dataset != null) {
3914: dataset.addChangeListener(this);
3915: }
3916: }
3917: int rendererCount = this.renderers.size();
3918: for (int i = 0; i < rendererCount; i++) {
3919: CategoryItemRenderer renderer
3920: = (CategoryItemRenderer) this.renderers.get(i);
3921: if (renderer != null) {
3922: renderer.addChangeListener(this);
3923: }
3924: }
3925:
3926: }
3927:
3928: }