1 95 96 package org.jfree.chart.renderer.xy; 97 98 import java.awt.AlphaComposite ; 99 import java.awt.Composite ; 100 import java.awt.Font ; 101 import java.awt.GradientPaint ; 102 import java.awt.Graphics2D ; 103 import java.awt.Paint ; 104 import java.awt.Shape ; 105 import java.awt.Stroke ; 106 import java.awt.geom.Ellipse2D ; 107 import java.awt.geom.Line2D ; 108 import java.awt.geom.Point2D ; 109 import java.awt.geom.Rectangle2D ; 110 import java.io.Serializable ; 111 import java.util.Iterator ; 112 import java.util.List ; 113 114 import org.jfree.chart.LegendItem; 115 import org.jfree.chart.LegendItemCollection; 116 import org.jfree.chart.annotations.XYAnnotation; 117 import org.jfree.chart.axis.ValueAxis; 118 import org.jfree.chart.entity.EntityCollection; 119 import org.jfree.chart.entity.XYItemEntity; 120 import org.jfree.chart.event.RendererChangeEvent; 121 import org.jfree.chart.labels.ItemLabelPosition; 122 import org.jfree.chart.labels.StandardXYSeriesLabelGenerator; 123 import org.jfree.chart.labels.XYItemLabelGenerator; 124 import org.jfree.chart.labels.XYSeriesLabelGenerator; 125 import org.jfree.chart.labels.XYToolTipGenerator; 126 import org.jfree.chart.plot.CrosshairState; 127 import org.jfree.chart.plot.DrawingSupplier; 128 import org.jfree.chart.plot.IntervalMarker; 129 import org.jfree.chart.plot.Marker; 130 import org.jfree.chart.plot.Plot; 131 import org.jfree.chart.plot.PlotOrientation; 132 import org.jfree.chart.plot.PlotRenderingInfo; 133 import org.jfree.chart.plot.ValueMarker; 134 import org.jfree.chart.plot.XYPlot; 135 import org.jfree.chart.renderer.AbstractRenderer; 136 import org.jfree.chart.urls.XYURLGenerator; 137 import org.jfree.data.Range; 138 import org.jfree.data.general.DatasetUtilities; 139 import org.jfree.data.xy.XYDataset; 140 import org.jfree.text.TextUtilities; 141 import org.jfree.ui.GradientPaintTransformer; 142 import org.jfree.ui.Layer; 143 import org.jfree.ui.LengthAdjustmentType; 144 import org.jfree.ui.RectangleAnchor; 145 import org.jfree.ui.RectangleInsets; 146 import org.jfree.util.ObjectList; 147 import org.jfree.util.ObjectUtilities; 148 import org.jfree.util.PublicCloneable; 149 150 154 public abstract class AbstractXYItemRenderer extends AbstractRenderer 155 implements XYItemRenderer, 156 Cloneable , 157 Serializable { 158 159 160 private static final long serialVersionUID = 8019124836026607990L; 161 162 163 private XYPlot plot; 164 165 166 private XYItemLabelGenerator itemLabelGenerator; 167 168 169 private ObjectList itemLabelGeneratorList; 170 171 172 private XYItemLabelGenerator baseItemLabelGenerator; 173 174 175 private XYToolTipGenerator toolTipGenerator; 176 177 178 private ObjectList toolTipGeneratorList; 179 180 181 private XYToolTipGenerator baseToolTipGenerator; 182 183 184 private XYURLGenerator urlGenerator; 185 186 190 private List backgroundAnnotations; 191 192 196 private List foregroundAnnotations; 197 198 private int defaultEntityRadius; 199 200 private XYSeriesLabelGenerator legendItemLabelGenerator; 201 202 private XYSeriesLabelGenerator legendItemToolTipGenerator; 203 204 private XYSeriesLabelGenerator legendItemURLGenerator; 205 206 210 protected AbstractXYItemRenderer() { 211 this.itemLabelGenerator = null; 212 this.itemLabelGeneratorList = new ObjectList(); 213 this.toolTipGenerator = null; 214 this.toolTipGeneratorList = new ObjectList(); 215 this.urlGenerator = null; 216 this.backgroundAnnotations = new java.util.ArrayList (); 217 this.foregroundAnnotations = new java.util.ArrayList (); 218 this.defaultEntityRadius = 3; 219 this.legendItemLabelGenerator 220 = new StandardXYSeriesLabelGenerator("{0}"); 221 } 222 223 230 public int getPassCount() { 231 return 1; 232 } 233 234 239 public XYPlot getPlot() { 240 return this.plot; 241 } 242 243 248 public void setPlot(XYPlot plot) { 249 this.plot = plot; 250 } 251 252 269 public XYItemRendererState initialise(Graphics2D g2, 270 Rectangle2D dataArea, 271 XYPlot plot, 272 XYDataset data, 273 PlotRenderingInfo info) { 274 275 XYItemRendererState state = new XYItemRendererState(info); 276 return state; 277 278 } 279 280 282 293 public XYItemLabelGenerator getItemLabelGenerator(int row, int column) { 294 return getSeriesItemLabelGenerator(row); 295 } 296 297 304 public XYItemLabelGenerator getSeriesItemLabelGenerator(int series) { 305 306 if (this.itemLabelGenerator != null) { 308 return this.itemLabelGenerator; 309 } 310 311 XYItemLabelGenerator generator 313 = (XYItemLabelGenerator) this.itemLabelGeneratorList.get(series); 314 if (generator == null) { 315 generator = this.baseItemLabelGenerator; 316 } 317 return generator; 318 319 } 320 321 327 public void setItemLabelGenerator(XYItemLabelGenerator generator) { 328 this.itemLabelGenerator = generator; 329 notifyListeners(new RendererChangeEvent(this)); 330 } 331 332 339 public void setSeriesItemLabelGenerator(int series, 340 XYItemLabelGenerator generator) { 341 this.itemLabelGeneratorList.set(series, generator); 342 notifyListeners(new RendererChangeEvent(this)); 343 } 344 345 350 public XYItemLabelGenerator getBaseItemLabelGenerator() { 351 return this.baseItemLabelGenerator; 352 } 353 354 360 public void setBaseItemLabelGenerator(XYItemLabelGenerator generator) { 361 this.baseItemLabelGenerator = generator; 362 notifyListeners(new RendererChangeEvent(this)); 363 } 364 365 367 378 public XYToolTipGenerator getToolTipGenerator(int row, int column) { 379 return getSeriesToolTipGenerator(row); 380 } 381 382 389 public XYToolTipGenerator getSeriesToolTipGenerator(int series) { 390 391 if (this.toolTipGenerator != null) { 393 return this.toolTipGenerator; 394 } 395 396 XYToolTipGenerator generator 398 = (XYToolTipGenerator) this.toolTipGeneratorList.get(series); 399 if (generator == null) { 400 generator = this.baseToolTipGenerator; 401 } 402 return generator; 403 404 } 405 406 412 public void setToolTipGenerator(XYToolTipGenerator generator) { 413 this.toolTipGenerator = generator; 414 notifyListeners(new RendererChangeEvent(this)); 415 } 416 417 424 public void setSeriesToolTipGenerator(int series, 425 XYToolTipGenerator generator) { 426 this.toolTipGeneratorList.set(series, generator); 427 notifyListeners(new RendererChangeEvent(this)); 428 } 429 430 435 public XYToolTipGenerator getBaseToolTipGenerator() { 436 return this.baseToolTipGenerator; 437 } 438 439 445 public void setBaseToolTipGenerator(XYToolTipGenerator generator) { 446 this.baseToolTipGenerator = generator; 447 notifyListeners(new RendererChangeEvent(this)); 448 } 449 450 452 457 public XYURLGenerator getURLGenerator() { 458 return this.urlGenerator; 459 } 460 461 466 public void setURLGenerator(XYURLGenerator urlGenerator) { 467 this.urlGenerator = urlGenerator; 468 notifyListeners(new RendererChangeEvent(this)); 469 } 470 471 478 public void addAnnotation(XYAnnotation annotation) { 479 addAnnotation(annotation, Layer.FOREGROUND); 481 } 482 483 489 public void addAnnotation(XYAnnotation annotation, Layer layer) { 490 if (annotation == null) { 491 throw new IllegalArgumentException ("Null 'annotation' argument."); 492 } 493 if (layer.equals(Layer.FOREGROUND)) { 494 this.foregroundAnnotations.add(annotation); 495 notifyListeners(new RendererChangeEvent(this)); 496 } 497 else if (layer.equals(Layer.BACKGROUND)) { 498 this.backgroundAnnotations.add(annotation); 499 notifyListeners(new RendererChangeEvent(this)); 500 } 501 else { 502 throw new RuntimeException ("Unknown layer."); 504 } 505 } 506 516 public boolean removeAnnotation(XYAnnotation annotation) { 517 boolean removed = this.foregroundAnnotations.remove(annotation); 518 removed = removed & this.backgroundAnnotations.remove(annotation); 519 notifyListeners(new RendererChangeEvent(this)); 520 return removed; 521 } 522 523 527 public void removeAnnotations() { 528 this.foregroundAnnotations.clear(); 529 this.backgroundAnnotations.clear(); 530 notifyListeners(new RendererChangeEvent(this)); 531 } 532 533 539 public int getDefaultEntityRadius() { 540 return this.defaultEntityRadius; 541 } 542 543 549 public void setDefaultEntityRadius(int radius) { 550 this.defaultEntityRadius = radius; 551 } 552 553 558 public XYSeriesLabelGenerator getLegendItemLabelGenerator() { 559 return this.legendItemLabelGenerator; 560 } 561 562 567 public void setLegendItemLabelGenerator(XYSeriesLabelGenerator generator) { 568 if (generator == null) { 569 throw new IllegalArgumentException ("Null 'generator' argument."); 570 } 571 this.legendItemLabelGenerator = generator; 572 } 573 574 579 public XYSeriesLabelGenerator getLegendItemToolTipGenerator() { 580 return this.legendItemToolTipGenerator; 581 } 582 583 588 public void setLegendItemToolTipGenerator(XYSeriesLabelGenerator generator) 589 { 590 this.legendItemToolTipGenerator = generator; 591 } 592 593 598 public XYSeriesLabelGenerator getLegendItemURLGenerator() { 599 return this.legendItemURLGenerator; 600 } 601 602 607 public void setLegendItemURLGenerator(XYSeriesLabelGenerator generator) 608 { 609 this.legendItemURLGenerator = generator; 610 } 611 612 621 public Range findDomainBounds(XYDataset dataset) { 622 if (dataset != null) { 623 return DatasetUtilities.findDomainBounds(dataset, false); 624 } 625 else { 626 return null; 627 } 628 } 629 630 639 public Range findRangeBounds(XYDataset dataset) { 640 if (dataset != null) { 641 return DatasetUtilities.findRangeBounds(dataset, false); 642 } 643 else { 644 return null; 645 } 646 } 647 648 654 public LegendItemCollection getLegendItems() { 655 if (this.plot == null) { 656 return new LegendItemCollection(); 657 } 658 LegendItemCollection result = new LegendItemCollection(); 659 int index = this.plot.getIndexOf(this); 660 XYDataset dataset = this.plot.getDataset(index); 661 if (dataset != null) { 662 int seriesCount = dataset.getSeriesCount(); 663 for (int i = 0; i < seriesCount; i++) { 664 if (isSeriesVisibleInLegend(i)) { 665 LegendItem item = getLegendItem(index, i); 666 if (item != null) { 667 result.add(item); 668 } 669 } 670 } 671 672 } 673 return result; 674 } 675 676 685 public LegendItem getLegendItem(int datasetIndex, int series) { 686 LegendItem result = null; 687 XYPlot xyplot = getPlot(); 688 if (xyplot != null) { 689 XYDataset dataset = xyplot.getDataset(datasetIndex); 690 if (dataset != null) { 691 String label = this.legendItemLabelGenerator.generateLabel( 692 dataset, series); 693 String description = label; 694 String toolTipText = null; 695 if (getLegendItemToolTipGenerator() != null) { 696 toolTipText = getLegendItemToolTipGenerator().generateLabel( 697 dataset, series); 698 } 699 String urlText = null; 700 if (getLegendItemURLGenerator() != null) { 701 urlText = getLegendItemURLGenerator().generateLabel( 702 dataset, series); 703 } 704 Shape shape = getSeriesShape(series); 705 Paint paint = getSeriesPaint(series); 706 Paint outlinePaint = getSeriesOutlinePaint(series); 707 Stroke outlineStroke = getSeriesOutlineStroke(series); 708 result = new LegendItem(label, description, toolTipText, 709 urlText, shape, paint, outlineStroke, outlinePaint); 710 result.setSeriesIndex(series); 711 result.setDatasetIndex(datasetIndex); 712 } 713 } 714 return result; 715 } 716 717 728 public void fillDomainGridBand(Graphics2D g2, 729 XYPlot plot, 730 ValueAxis axis, 731 Rectangle2D dataArea, 732 double start, double end) { 733 734 double x1 = axis.valueToJava2D(start, dataArea, 735 plot.getDomainAxisEdge()); 736 double x2 = axis.valueToJava2D(end, dataArea, 737 plot.getDomainAxisEdge()); 738 Rectangle2D band = new Rectangle2D.Double (x1, dataArea.getMinY(), 741 x2 - x1, dataArea.getMaxY() - dataArea.getMinY()); 742 Paint paint = plot.getDomainTickBandPaint(); 743 744 if (paint != null) { 745 g2.setPaint(paint); 746 g2.fill(band); 747 } 748 749 } 750 751 762 public void fillRangeGridBand(Graphics2D g2, 763 XYPlot plot, 764 ValueAxis axis, 765 Rectangle2D dataArea, 766 double start, double end) { 767 768 double y1 = axis.valueToJava2D(start, dataArea, 769 plot.getRangeAxisEdge()); 770 double y2 = axis.valueToJava2D(end, dataArea, plot.getRangeAxisEdge()); 771 Rectangle2D band = new Rectangle2D.Double (dataArea.getMinX(), y2, 774 dataArea.getWidth(), y1 - y2); 775 Paint paint = plot.getRangeTickBandPaint(); 776 777 if (paint != null) { 778 g2.setPaint(paint); 779 g2.fill(band); 780 } 781 782 } 783 784 794 public void drawDomainGridLine(Graphics2D g2, 795 XYPlot plot, 796 ValueAxis axis, 797 Rectangle2D dataArea, 798 double value) { 799 800 Range range = axis.getRange(); 801 if (!range.contains(value)) { 802 return; 803 } 804 805 PlotOrientation orientation = plot.getOrientation(); 806 double v = axis.valueToJava2D(value, dataArea, 807 plot.getDomainAxisEdge()); 808 Line2D line = null; 809 if (orientation == PlotOrientation.HORIZONTAL) { 810 line = new Line2D.Double (dataArea.getMinX(), v, 811 dataArea.getMaxX(), v); 812 } 813 else if (orientation == PlotOrientation.VERTICAL) { 814 line = new Line2D.Double (v, dataArea.getMinY(), v, 815 dataArea.getMaxY()); 816 } 817 818 Paint paint = plot.getDomainGridlinePaint(); 819 Stroke stroke = plot.getDomainGridlineStroke(); 820 g2.setPaint(paint != null ? paint : Plot.DEFAULT_OUTLINE_PAINT); 821 g2.setStroke(stroke != null ? stroke : Plot.DEFAULT_OUTLINE_STROKE); 822 g2.draw(line); 823 824 } 825 826 838 public void drawRangeLine(Graphics2D g2, 839 XYPlot plot, 840 ValueAxis axis, 841 Rectangle2D dataArea, 842 double value, 843 Paint paint, 844 Stroke stroke) { 845 846 Range range = axis.getRange(); 847 if (!range.contains(value)) { 848 return; 849 } 850 851 PlotOrientation orientation = plot.getOrientation(); 852 Line2D line = null; 853 double v = axis.valueToJava2D(value, dataArea, plot.getRangeAxisEdge()); 854 if (orientation == PlotOrientation.HORIZONTAL) { 855 line = new Line2D.Double (v, dataArea.getMinY(), v, 856 dataArea.getMaxY()); 857 } 858 else if (orientation == PlotOrientation.VERTICAL) { 859 line = new Line2D.Double (dataArea.getMinX(), v, 860 dataArea.getMaxX(), v); 861 } 862 863 g2.setPaint(paint); 864 g2.setStroke(stroke); 865 g2.draw(line); 866 867 } 868 869 878 public void drawDomainMarker(Graphics2D g2, 879 XYPlot plot, 880 ValueAxis domainAxis, 881 Marker marker, 882 Rectangle2D dataArea) { 883 884 if (marker instanceof ValueMarker) { 885 ValueMarker vm = (ValueMarker) marker; 886 double value = vm.getValue(); 887 Range range = domainAxis.getRange(); 888 if (!range.contains(value)) { 889 return; 890 } 891 892 double v = domainAxis.valueToJava2D(value, dataArea, 893 plot.getDomainAxisEdge()); 894 895 PlotOrientation orientation = plot.getOrientation(); 896 Line2D line = null; 897 if (orientation == PlotOrientation.HORIZONTAL) { 898 line = new Line2D.Double (dataArea.getMinX(), v, 899 dataArea.getMaxX(), v); 900 } 901 else if (orientation == PlotOrientation.VERTICAL) { 902 line = new Line2D.Double (v, dataArea.getMinY(), v, 903 dataArea.getMaxY()); 904 } 905 906 final Composite originalComposite = g2.getComposite(); 907 g2.setComposite(AlphaComposite.getInstance( 908 AlphaComposite.SRC_OVER, marker.getAlpha())); 909 g2.setPaint(marker.getPaint()); 910 g2.setStroke(marker.getStroke()); 911 g2.draw(line); 912 913 String label = marker.getLabel(); 914 RectangleAnchor anchor = marker.getLabelAnchor(); 915 if (label != null) { 916 Font labelFont = marker.getLabelFont(); 917 g2.setFont(labelFont); 918 g2.setPaint(marker.getLabelPaint()); 919 Point2D coordinates = calculateDomainMarkerTextAnchorPoint( 920 g2, orientation, dataArea, line.getBounds2D(), 921 marker.getLabelOffset(), 922 LengthAdjustmentType.EXPAND, anchor); 923 TextUtilities.drawAlignedString(label, g2, 924 (float) coordinates.getX(), (float) coordinates.getY(), 925 marker.getLabelTextAnchor()); 926 } 927 g2.setComposite(originalComposite); 928 } 929 else if (marker instanceof IntervalMarker) { 930 IntervalMarker im = (IntervalMarker) marker; 931 double start = im.getStartValue(); 932 double end = im.getEndValue(); 933 Range range = domainAxis.getRange(); 934 if (!(range.intersects(start, end))) { 935 return; 936 } 937 938 double start2d = domainAxis.valueToJava2D(start, dataArea, 939 plot.getDomainAxisEdge()); 940 double end2d = domainAxis.valueToJava2D(end, dataArea, 941 plot.getDomainAxisEdge()); 942 943 PlotOrientation orientation = plot.getOrientation(); 944 Rectangle2D rect = null; 945 if (orientation == PlotOrientation.HORIZONTAL) { 946 rect = new Rectangle2D.Double (dataArea.getMinX(), 947 Math.min(start2d, end2d), dataArea.getWidth(), 948 Math.abs(end2d - start2d)); 949 } 950 else if (orientation == PlotOrientation.VERTICAL) { 951 rect = new Rectangle2D.Double (Math.min(start2d, end2d), 952 dataArea.getMinY(), Math.abs(end2d - start2d), 953 dataArea.getHeight()); 954 } 955 956 final Composite originalComposite = g2.getComposite(); 957 g2.setComposite(AlphaComposite.getInstance( 958 AlphaComposite.SRC_OVER, marker.getAlpha())); 959 Paint p = marker.getPaint(); 960 if (p instanceof GradientPaint ) { 961 GradientPaint gp = (GradientPaint ) p; 962 GradientPaintTransformer t = im.getGradientPaintTransformer(); 963 if (t != null) { 964 gp = t.transform(gp, rect); 965 } 966 g2.setPaint(gp); 967 } 968 else { 969 g2.setPaint(p); 970 } 971 g2.fill(rect); 972 973 if (im.getOutlinePaint() != null && im.getOutlineStroke() != null) { 975 double x0 = rect.getMinX(); 976 double x1 = rect.getMaxX(); 977 double y0 = rect.getMinY(); 978 double y1 = rect.getMaxY(); 979 if (orientation == PlotOrientation.VERTICAL) { 980 Line2D line = new Line2D.Double (x0, y0, x0, y1); 981 g2.setPaint(im.getOutlinePaint()); 982 g2.setStroke(im.getOutlineStroke()); 983 g2.draw(line); 984 line.setLine(x1, y0, x1, y1); 985 g2.draw(line); 986 } 987 else { Line2D line = new Line2D.Double (x0, y0, x1, y0); 989 g2.setPaint(im.getOutlinePaint()); 990 g2.setStroke(im.getOutlineStroke()); 991 g2.draw(line); 992 line.setLine(x0, y1, x1, y1); 993 g2.draw(line); 994 } 995 } 996 997 String label = marker.getLabel(); 998 RectangleAnchor anchor = marker.getLabelAnchor(); 999 if (label != null) { 1000 Font labelFont = marker.getLabelFont(); 1001 g2.setFont(labelFont); 1002 g2.setPaint(marker.getLabelPaint()); 1003 Point2D coordinates = calculateDomainMarkerTextAnchorPoint( 1004 g2, orientation, dataArea, rect, 1005 marker.getLabelOffset(), marker.getLabelOffsetType(), 1006 anchor); 1007 TextUtilities.drawAlignedString(label, g2, 1008 (float) coordinates.getX(), (float) coordinates.getY(), 1009 marker.getLabelTextAnchor()); 1010 } 1011 g2.setComposite(originalComposite); 1012 1013 } 1014 1015 } 1016 1017 1030 protected Point2D calculateDomainMarkerTextAnchorPoint(Graphics2D g2, 1031 PlotOrientation orientation, 1032 Rectangle2D dataArea, 1033 Rectangle2D markerArea, 1034 RectangleInsets markerOffset, 1035 LengthAdjustmentType labelOffsetType, 1036 RectangleAnchor anchor) { 1037 1038 Rectangle2D anchorRect = null; 1039 if (orientation == PlotOrientation.HORIZONTAL) { 1040 anchorRect = markerOffset.createAdjustedRectangle(markerArea, 1041 LengthAdjustmentType.CONTRACT, labelOffsetType); 1042 } 1043 else if (orientation == PlotOrientation.VERTICAL) { 1044 anchorRect = markerOffset.createAdjustedRectangle(markerArea, 1045 labelOffsetType, LengthAdjustmentType.CONTRACT); 1046 } 1047 return RectangleAnchor.coordinates(anchorRect, anchor); 1048 1049 } 1050 1051 1060 public void drawRangeMarker(Graphics2D g2, 1061 XYPlot plot, 1062 ValueAxis rangeAxis, 1063 Marker marker, 1064 Rectangle2D dataArea) { 1065 1066 if (marker instanceof ValueMarker) { 1067 ValueMarker vm = (ValueMarker) marker; 1068 double value = vm.getValue(); 1069 Range range = rangeAxis.getRange(); 1070 if (!range.contains(value)) { 1071 return; 1072 } 1073 1074 double v = rangeAxis.valueToJava2D(value, dataArea, 1075 plot.getRangeAxisEdge()); 1076 PlotOrientation orientation = plot.getOrientation(); 1077 Line2D line = null; 1078 if (orientation == PlotOrientation.HORIZONTAL) { 1079 line = new Line2D.Double (v, dataArea.getMinY(), v, 1080 dataArea.getMaxY()); 1081 } 1082 else if (orientation == PlotOrientation.VERTICAL) { 1083 line = new Line2D.Double (dataArea.getMinX(), v, 1084 dataArea.getMaxX(), v); 1085 } 1086 1087 final Composite originalComposite = g2.getComposite(); 1088 g2.setComposite(AlphaComposite.getInstance( 1089 AlphaComposite.SRC_OVER, marker.getAlpha())); 1090 g2.setPaint(marker.getPaint()); 1091 g2.setStroke(marker.getStroke()); 1092 g2.draw(line); 1093 1094 String label = marker.getLabel(); 1095 RectangleAnchor anchor = marker.getLabelAnchor(); 1096 if (label != null) { 1097 Font labelFont = marker.getLabelFont(); 1098 g2.setFont(labelFont); 1099 g2.setPaint(marker.getLabelPaint()); 1100 Point2D coordinates = calculateRangeMarkerTextAnchorPoint( 1101 g2, orientation, dataArea, line.getBounds2D(), 1102 marker.getLabelOffset(), 1103 LengthAdjustmentType.EXPAND, anchor); 1104 TextUtilities.drawAlignedString(label, g2, 1105 (float) coordinates.getX(), (float) coordinates.getY(), 1106 marker.getLabelTextAnchor()); 1107 } 1108 g2.setComposite(originalComposite); 1109 } 1110 else if (marker instanceof IntervalMarker) { 1111 1112 IntervalMarker im = (IntervalMarker) marker; 1113 double start = im.getStartValue(); 1114 double end = im.getEndValue(); 1115 Range range = rangeAxis.getRange(); 1116 if (!(range.intersects(start, end))) { 1117 return; 1118 } 1119 1120 double start2d = rangeAxis.valueToJava2D(start, dataArea, 1121 plot.getRangeAxisEdge()); 1122 double end2d = rangeAxis.valueToJava2D(end, dataArea, 1123 plot.getRangeAxisEdge()); 1124 1125 PlotOrientation orientation = plot.getOrientation(); 1126 Rectangle2D rect = null; 1127 if (orientation == PlotOrientation.HORIZONTAL) { 1128 rect = new Rectangle2D.Double (Math.min(start2d, end2d), 1129 dataArea.getMinY(), Math.abs(end2d - start2d), 1130 dataArea.getHeight()); 1131 } 1132 else if (orientation == PlotOrientation.VERTICAL) { 1133 rect = new Rectangle2D.Double (dataArea.getMinX(), 1134 Math.min(start2d, end2d), dataArea.getWidth(), 1135 Math.abs(end2d - start2d)); 1136 } 1137 1138 final Composite originalComposite = g2.getComposite(); 1139 g2.setComposite(AlphaComposite.getInstance( 1140 AlphaComposite.SRC_OVER, marker.getAlpha())); 1141 Paint p = marker.getPaint(); 1142 if (p instanceof GradientPaint ) { 1143 GradientPaint gp = (GradientPaint ) p; 1144 GradientPaintTransformer t = im.getGradientPaintTransformer(); 1145 if (t != null) { 1146 gp = t.transform(gp, rect); 1147 } 1148 g2.setPaint(gp); 1149 } 1150 else { 1151 g2.setPaint(p); 1152 } 1153 g2.fill(rect); 1154 1155 if (im.getOutlinePaint() != null && im.getOutlineStroke() != null) { 1157 double x0 = rect.getMinX(); 1158 double x1 = rect.getMaxX(); 1159 double y0 = rect.getMinY(); 1160 double y1 = rect.getMaxY(); 1161 if (orientation == PlotOrientation.VERTICAL) { 1162 Line2D line = new Line2D.Double (x0, y0, x0, y1); 1163 g2.setPaint(im.getOutlinePaint()); 1164 g2.setStroke(im.getOutlineStroke()); 1165 g2.draw(line); 1166 line.setLine(x1, y0, x1, y1); 1167 g2.draw(line); 1168 } 1169 else { Line2D line = new Line2D.Double (x0, y0, x1, y0); 1171 g2.setPaint(im.getOutlinePaint()); 1172 g2.setStroke(im.getOutlineStroke()); 1173 g2.draw(line); 1174 line.setLine(x0, y1, x1, y1); 1175 g2.draw(line); 1176 } 1177 } 1178 1179 String label = marker.getLabel(); 1180 RectangleAnchor anchor = marker.getLabelAnchor(); 1181 if (label != null) { 1182 Font labelFont = marker.getLabelFont(); 1183 g2.setFont(labelFont); 1184 g2.setPaint(marker.getLabelPaint()); 1185 Point2D coordinates = calculateRangeMarkerTextAnchorPoint( 1186 g2, orientation, dataArea, rect, 1187 marker.getLabelOffset(), marker.getLabelOffsetType(), 1188 anchor); 1189 TextUtilities.drawAlignedString(label, g2, 1190 (float) coordinates.getX(), (float) coordinates.getY(), 1191 marker.getLabelTextAnchor()); 1192 } 1193 g2.setComposite(originalComposite); 1194 } 1195 } 1196 1197 1209 private Point2D calculateRangeMarkerTextAnchorPoint(Graphics2D g2, 1210 PlotOrientation orientation, 1211 Rectangle2D dataArea, 1212 Rectangle2D markerArea, 1213 RectangleInsets markerOffset, 1214 LengthAdjustmentType labelOffsetForRange, 1215 RectangleAnchor anchor) { 1216 1217 Rectangle2D anchorRect = null; 1218 if (orientation == PlotOrientation.HORIZONTAL) { 1219 anchorRect = markerOffset.createAdjustedRectangle(markerArea, 1220 labelOffsetForRange, LengthAdjustmentType.CONTRACT); 1221 } 1222 else if (orientation == PlotOrientation.VERTICAL) { 1223 anchorRect = markerOffset.createAdjustedRectangle(markerArea, 1224 LengthAdjustmentType.CONTRACT, labelOffsetForRange); 1225 } 1226 return RectangleAnchor.coordinates(anchorRect, anchor); 1227 1228 } 1229 1230 1238 protected Object clone() throws CloneNotSupportedException { 1239 AbstractXYItemRenderer clone = (AbstractXYItemRenderer) super.clone(); 1240 if (this.itemLabelGenerator != null 1242 && this.itemLabelGenerator instanceof PublicCloneable) { 1243 PublicCloneable pc = (PublicCloneable) this.itemLabelGenerator; 1244 clone.itemLabelGenerator = (XYItemLabelGenerator) pc.clone(); 1245 } 1246 return clone; 1247 } 1248 1249 1256 public boolean equals(Object obj) { 1257 1258 if (obj == null) { 1259 return false; 1260 } 1261 if (obj == this) { 1262 return true; 1263 } 1264 if (!(obj instanceof AbstractXYItemRenderer)) { 1265 return false; 1266 } 1267 AbstractXYItemRenderer renderer = (AbstractXYItemRenderer) obj; 1268 if (!super.equals(obj)) { 1269 return false; 1270 } 1271 if (!ObjectUtilities.equal(this.itemLabelGenerator, 1272 renderer.itemLabelGenerator)) { 1273 return false; 1274 } 1275 if (!ObjectUtilities.equal(this.urlGenerator, renderer.urlGenerator)) { 1276 return false; 1277 } 1278 return true; 1279 } 1280 1281 1286 public DrawingSupplier getDrawingSupplier() { 1287 DrawingSupplier result = null; 1288 XYPlot p = getPlot(); 1289 if (p != null) { 1290 result = p.getDrawingSupplier(); 1291 } 1292 return result; 1293 } 1294 1295 1309 protected void updateCrosshairValues(CrosshairState crosshairState, 1310 double x, double y, double transX, 1311 double transY, 1312 PlotOrientation orientation) { 1313 1314 if (orientation == null) { 1315 throw new IllegalArgumentException ("Null 'orientation' argument."); 1316 } 1317 1318 if (crosshairState != null) { 1319 if (this.plot.isDomainCrosshairLockedOnData()) { 1321 if (this.plot.isRangeCrosshairLockedOnData()) { 1322 crosshairState.updateCrosshairPoint(x, y, transX, transY, 1324 orientation); 1325 } 1326 else { 1327 crosshairState.updateCrosshairX(x); 1329 } 1330 } 1331 else { 1332 if (this.plot.isRangeCrosshairLockedOnData()) { 1333 crosshairState.updateCrosshairY(y); 1335 } 1336 } 1337 } 1338 1339 } 1340 1341 1354 protected void drawItemLabel(Graphics2D g2, PlotOrientation orientation, 1355 XYDataset dataset, int series, int item, double x, double y, 1356 boolean negative) { 1357 1358 XYItemLabelGenerator generator = getItemLabelGenerator(series, item); 1359 if (generator != null) { 1360 Font labelFont = getItemLabelFont(series, item); 1361 Paint paint = getItemLabelPaint(series, item); 1362 g2.setFont(labelFont); 1363 g2.setPaint(paint); 1364 String label = generator.generateLabel(dataset, series, item); 1365 1366 ItemLabelPosition position = null; 1368 if (!negative) { 1369 position = getPositiveItemLabelPosition(series, item); 1370 } 1371 else { 1372 position = getNegativeItemLabelPosition(series, item); 1373 } 1374 1375 Point2D anchorPoint = calculateLabelAnchorPoint( 1377 position.getItemLabelAnchor(), x, y, orientation); 1378 TextUtilities.drawRotatedString(label, g2, 1379 (float) anchorPoint.getX(), (float) anchorPoint.getY(), 1380 position.getTextAnchor(), position.getAngle(), 1381 position.getRotationAnchor()); 1382 } 1383 1384 } 1385 1386 1396 public void drawAnnotations(Graphics2D g2, 1397 Rectangle2D dataArea, 1398 ValueAxis domainAxis, 1399 ValueAxis rangeAxis, 1400 Layer layer, 1401 PlotRenderingInfo info) { 1402 1403 Iterator iterator = null; 1404 if (layer.equals(Layer.FOREGROUND)) { 1405 iterator = this.foregroundAnnotations.iterator(); 1406 } 1407 else if (layer.equals(Layer.BACKGROUND)) { 1408 iterator = this.backgroundAnnotations.iterator(); 1409 } 1410 else { 1411 throw new RuntimeException ("Unknown layer."); 1413 } 1414 while (iterator.hasNext()) { 1415 XYAnnotation annotation = (XYAnnotation) iterator.next(); 1416 annotation.draw(g2, this.plot, dataArea, domainAxis, rangeAxis, 1417 0, info); 1418 } 1419 1420 } 1421 1422 1434 protected void addEntity(EntityCollection entities, Shape area, 1435 XYDataset dataset, int series, int item, 1436 double entityX, double entityY) { 1437 if (!getItemCreateEntity(series, item)) { 1438 return; 1439 } 1440 if (area == null) { 1441 area = new Ellipse2D.Double (entityX - this.defaultEntityRadius, 1442 entityY - this.defaultEntityRadius, 1443 this.defaultEntityRadius * 2, this.defaultEntityRadius * 2); 1444 } 1445 String tip = null; 1446 XYToolTipGenerator generator = getToolTipGenerator(series, item); 1447 if (generator != null) { 1448 tip = generator.generateToolTip(dataset, series, item); 1449 } 1450 String url = null; 1451 if (getURLGenerator() != null) { 1452 url = getURLGenerator().generateURL(dataset, series, item); 1453 } 1454 XYItemEntity entity = new XYItemEntity(area, dataset, series, item, 1455 tip, url); 1456 entities.add(entity); 1457 } 1458 1459} 1460 | Popular Tags |