| 1 90 91 package org.jfree.chart.renderer.category; 92 93 import java.awt.AlphaComposite ; 94 import java.awt.Composite ; 95 import java.awt.Font ; 96 import java.awt.GradientPaint ; 97 import java.awt.Graphics2D ; 98 import java.awt.Paint ; 99 import java.awt.Shape ; 100 import java.awt.Stroke ; 101 import java.awt.geom.Line2D ; 102 import java.awt.geom.Point2D ; 103 import java.awt.geom.Rectangle2D ; 104 import java.io.Serializable ; 105 106 import org.jfree.chart.LegendItem; 107 import org.jfree.chart.LegendItemCollection; 108 import org.jfree.chart.axis.CategoryAxis; 109 import org.jfree.chart.axis.ValueAxis; 110 import org.jfree.chart.entity.CategoryItemEntity; 111 import org.jfree.chart.entity.EntityCollection; 112 import org.jfree.chart.event.RendererChangeEvent; 113 import org.jfree.chart.labels.CategoryItemLabelGenerator; 114 import org.jfree.chart.labels.CategorySeriesLabelGenerator; 115 import org.jfree.chart.labels.CategoryToolTipGenerator; 116 import org.jfree.chart.labels.ItemLabelPosition; 117 import org.jfree.chart.labels.StandardCategorySeriesLabelGenerator; 118 import org.jfree.chart.plot.CategoryMarker; 119 import org.jfree.chart.plot.CategoryPlot; 120 import org.jfree.chart.plot.DrawingSupplier; 121 import org.jfree.chart.plot.IntervalMarker; 122 import org.jfree.chart.plot.Marker; 123 import org.jfree.chart.plot.PlotOrientation; 124 import org.jfree.chart.plot.PlotRenderingInfo; 125 import org.jfree.chart.plot.ValueMarker; 126 import org.jfree.chart.renderer.AbstractRenderer; 127 import org.jfree.chart.urls.CategoryURLGenerator; 128 import org.jfree.data.Range; 129 import org.jfree.data.category.CategoryDataset; 130 import org.jfree.data.general.DatasetUtilities; 131 import org.jfree.text.TextUtilities; 132 import org.jfree.ui.GradientPaintTransformer; 133 import org.jfree.ui.LengthAdjustmentType; 134 import org.jfree.ui.RectangleAnchor; 135 import org.jfree.ui.RectangleInsets; 136 import org.jfree.util.ObjectList; 137 import org.jfree.util.ObjectUtilities; 138 import org.jfree.util.PublicCloneable; 139 140 146 public abstract class AbstractCategoryItemRenderer extends AbstractRenderer 147 implements CategoryItemRenderer, Cloneable , PublicCloneable, Serializable { 148 149 150 private static final long serialVersionUID = 1247553218442497391L; 151 152 153 private CategoryPlot plot; 154 155 156 private CategoryItemLabelGenerator itemLabelGenerator; 157 158 159 private ObjectList itemLabelGeneratorList; 160 161 162 private CategoryItemLabelGenerator baseItemLabelGenerator; 163 164 165 private CategoryToolTipGenerator toolTipGenerator; 166 167 168 private ObjectList toolTipGeneratorList; 169 170 171 private CategoryToolTipGenerator baseToolTipGenerator; 172 173 174 private CategoryURLGenerator itemURLGenerator; 175 176 177 private ObjectList itemURLGeneratorList; 178 179 180 private CategoryURLGenerator baseItemURLGenerator; 181 182 183 private CategorySeriesLabelGenerator legendItemLabelGenerator; 184 185 186 private CategorySeriesLabelGenerator legendItemToolTipGenerator; 187 188 189 private CategorySeriesLabelGenerator legendItemURLGenerator; 190 191 192 private transient int rowCount; 193 194 195 private transient int columnCount; 196 197 204 protected AbstractCategoryItemRenderer() { 205 this.itemLabelGenerator = null; 206 this.itemLabelGeneratorList = new ObjectList(); 207 this.toolTipGenerator = null; 208 this.toolTipGeneratorList = new ObjectList(); 209 this.itemURLGenerator = null; 210 this.itemURLGeneratorList = new ObjectList(); 211 this.legendItemLabelGenerator 212 = new StandardCategorySeriesLabelGenerator(); 213 } 214 215 222 public int getPassCount() { 223 return 1; 224 } 225 226 233 public CategoryPlot getPlot() { 234 return this.plot; 235 } 236 237 244 public void setPlot(CategoryPlot plot) { 245 if (plot == null) { 246 throw new IllegalArgumentException ("Null 'plot' argument."); 247 } 248 this.plot = plot; 249 } 250 251 253 264 public CategoryItemLabelGenerator getItemLabelGenerator(int row, 265 int column) { 266 return getSeriesItemLabelGenerator(row); 267 } 268 269 276 public CategoryItemLabelGenerator getSeriesItemLabelGenerator(int series) { 277 278 if (this.itemLabelGenerator != null) { 280 return this.itemLabelGenerator; 281 } 282 283 CategoryItemLabelGenerator generator = (CategoryItemLabelGenerator) 285 this.itemLabelGeneratorList.get(series); 286 if (generator == null) { 287 generator = this.baseItemLabelGenerator; 288 } 289 return generator; 290 291 } 292 293 299 public void setItemLabelGenerator(CategoryItemLabelGenerator generator) { 300 this.itemLabelGenerator = generator; 301 notifyListeners(new RendererChangeEvent(this)); 302 } 303 304 311 public void setSeriesItemLabelGenerator(int series, 312 CategoryItemLabelGenerator generator) { 313 this.itemLabelGeneratorList.set(series, generator); 314 notifyListeners(new RendererChangeEvent(this)); 315 } 316 317 322 public CategoryItemLabelGenerator getBaseItemLabelGenerator() { 323 return this.baseItemLabelGenerator; 324 } 325 326 332 public void setBaseItemLabelGenerator(CategoryItemLabelGenerator generator) 333 { 334 this.baseItemLabelGenerator = generator; 335 notifyListeners(new RendererChangeEvent(this)); 336 } 337 338 340 352 public CategoryToolTipGenerator getToolTipGenerator(int row, int column) { 353 354 CategoryToolTipGenerator result = null; 355 if (this.toolTipGenerator != null) { 356 result = this.toolTipGenerator; 357 } 358 else { 359 result = getSeriesToolTipGenerator(row); 360 if (result == null) { 361 result = this.baseToolTipGenerator; 362 } 363 } 364 return result; 365 } 366 367 373 public CategoryToolTipGenerator getToolTipGenerator() { 374 return this.toolTipGenerator; 375 } 376 377 384 public void setToolTipGenerator(CategoryToolTipGenerator generator) { 385 this.toolTipGenerator = generator; 386 notifyListeners(new RendererChangeEvent(this)); 387 } 388 389 397 public CategoryToolTipGenerator getSeriesToolTipGenerator(int series) { 398 return (CategoryToolTipGenerator) this.toolTipGeneratorList.get(series); 399 } 400 401 409 public void setSeriesToolTipGenerator(int series, 410 CategoryToolTipGenerator generator) { 411 this.toolTipGeneratorList.set(series, generator); 412 notifyListeners(new RendererChangeEvent(this)); 413 } 414 415 420 public CategoryToolTipGenerator getBaseToolTipGenerator() { 421 return this.baseToolTipGenerator; 422 } 423 424 431 public void setBaseToolTipGenerator(CategoryToolTipGenerator generator) { 432 this.baseToolTipGenerator = generator; 433 notifyListeners(new RendererChangeEvent(this)); 434 } 435 436 438 448 public CategoryURLGenerator getItemURLGenerator(int row, int column) { 449 return getSeriesItemURLGenerator(row); 450 } 451 452 459 public CategoryURLGenerator getSeriesItemURLGenerator(int series) { 460 461 if (this.itemURLGenerator != null) { 463 return this.itemURLGenerator; 464 } 465 466 CategoryURLGenerator generator 468 = (CategoryURLGenerator) this.itemURLGeneratorList.get(series); 469 if (generator == null) { 470 generator = this.baseItemURLGenerator; 471 } 472 return generator; 473 474 } 475 476 481 public void setItemURLGenerator(CategoryURLGenerator generator) { 482 this.itemURLGenerator = generator; 483 } 484 485 491 public void setSeriesItemURLGenerator(int series, 492 CategoryURLGenerator generator) { 493 this.itemURLGeneratorList.set(series, generator); 494 } 495 496 501 public CategoryURLGenerator getBaseItemURLGenerator() { 502 return this.baseItemURLGenerator; 503 } 504 505 510 public void setBaseItemURLGenerator(CategoryURLGenerator generator) { 511 this.baseItemURLGenerator = generator; 512 } 513 514 520 public int getRowCount() { 521 return this.rowCount; 522 } 523 524 530 public int getColumnCount() { 531 return this.columnCount; 532 } 533 534 555 public CategoryItemRendererState initialise(Graphics2D g2, 556 Rectangle2D dataArea, 557 CategoryPlot plot, 558 int rendererIndex, 559 PlotRenderingInfo info) { 560 561 setPlot(plot); 562 CategoryDataset data = plot.getDataset(rendererIndex); 563 if (data != null) { 564 this.rowCount = data.getRowCount(); 565 this.columnCount = data.getColumnCount(); 566 } 567 else { 568 this.rowCount = 0; 569 this.columnCount = 0; 570 } 571 return new CategoryItemRendererState(info); 572 573 } 574 575 584 public Range findRangeBounds(CategoryDataset dataset) { 585 return DatasetUtilities.findRangeBounds(dataset); 586 } 587 588 597 public void drawBackground(Graphics2D g2, 598 CategoryPlot plot, 599 Rectangle2D dataArea) { 600 601 plot.drawBackground(g2, dataArea); 602 603 } 604 605 614 public void drawOutline(Graphics2D g2, 615 CategoryPlot plot, 616 Rectangle2D dataArea) { 617 618 plot.drawOutline(g2, dataArea); 619 620 } 621 622 635 public void drawDomainGridline(Graphics2D g2, 636 CategoryPlot plot, 637 Rectangle2D dataArea, 638 double value) { 639 640 Line2D line = null; 641 PlotOrientation orientation = plot.getOrientation(); 642 643 if (orientation == PlotOrientation.HORIZONTAL) { 644 line = new Line2D.Double (dataArea.getMinX(), value, 645 dataArea.getMaxX(), value); 646 } 647 else if (orientation == PlotOrientation.VERTICAL) { 648 line = new Line2D.Double (value, dataArea.getMinY(), value, 649 dataArea.getMaxY()); 650 } 651 652 Paint paint = plot.getDomainGridlinePaint(); 653 if (paint == null) { 654 paint = CategoryPlot.DEFAULT_GRIDLINE_PAINT; 655 } 656 g2.setPaint(paint); 657 658 Stroke stroke = plot.getDomainGridlineStroke(); 659 if (stroke == null) { 660 stroke = CategoryPlot.DEFAULT_GRIDLINE_STROKE; 661 } 662 g2.setStroke(stroke); 663 664 g2.draw(line); 665 666 } 667 668 679 public void drawRangeGridline(Graphics2D g2, 680 CategoryPlot plot, 681 ValueAxis axis, 682 Rectangle2D dataArea, 683 double value) { 684 685 Range range = axis.getRange(); 686 if (!range.contains(value)) { 687 return; 688 } 689 690 PlotOrientation orientation = plot.getOrientation(); 691 double v = axis.valueToJava2D(value, dataArea, plot.getRangeAxisEdge()); 692 Line2D line = null; 693 if (orientation == PlotOrientation.HORIZONTAL) { 694 line = new Line2D.Double (v, dataArea.getMinY(), v, 695 dataArea.getMaxY()); 696 } 697 else if (orientation == PlotOrientation.VERTICAL) { 698 line = new Line2D.Double (dataArea.getMinX(), v, 699 dataArea.getMaxX(), v); 700 } 701 702 Paint paint = plot.getRangeGridlinePaint(); 703 if (paint == null) { 704 paint = CategoryPlot.DEFAULT_GRIDLINE_PAINT; 705 } 706 g2.setPaint(paint); 707 708 Stroke stroke = plot.getRangeGridlineStroke(); 709 if (stroke == null) { 710 stroke = CategoryPlot.DEFAULT_GRIDLINE_STROKE; 711 } 712 g2.setStroke(stroke); 713 714 g2.draw(line); 715 716 } 717 718 727 public void drawDomainMarker(Graphics2D g2, 728 CategoryPlot plot, 729 CategoryAxis axis, 730 CategoryMarker marker, 731 Rectangle2D dataArea) { 732 733 Comparable category = marker.getKey(); 734 CategoryDataset dataset = plot.getDataset(plot.getIndexOf(this)); 735 int columnIndex = dataset.getColumnIndex(category); 736 if (columnIndex < 0) { 737 return; 738 } 739 740 final Composite savedComposite = g2.getComposite(); 741 g2.setComposite(AlphaComposite.getInstance( 742 AlphaComposite.SRC_OVER, marker.getAlpha())); 743 744 PlotOrientation orientation = plot.getOrientation(); 745 Rectangle2D bounds = null; 746 if (marker.getDrawAsLine()) { 747 double v = axis.getCategoryMiddle(columnIndex, 748 dataset.getColumnCount(), dataArea, 749 plot.getDomainAxisEdge()); 750 Line2D line = null; 751 if (orientation == PlotOrientation.HORIZONTAL) { 752 line = new Line2D.Double (dataArea.getMinX(), v, 753 dataArea.getMaxX(), v); 754 } 755 else if (orientation == PlotOrientation.VERTICAL) { 756 line = new Line2D.Double (v, dataArea.getMinY(), v, 757 dataArea.getMaxY()); 758 } 759 g2.setPaint(marker.getPaint()); 760 g2.setStroke(marker.getStroke()); 761 g2.draw(line); 762 bounds = line.getBounds2D(); 763 } 764 else { 765 double v0 = axis.getCategoryStart(columnIndex, 766 dataset.getColumnCount(), dataArea, 767 plot.getDomainAxisEdge()); 768 double v1 = axis.getCategoryEnd(columnIndex, 769 dataset.getColumnCount(), dataArea, 770 plot.getDomainAxisEdge()); 771 Rectangle2D area = null; 772 if (orientation == PlotOrientation.HORIZONTAL) { 773 area = new Rectangle2D.Double (dataArea.getMinX(), v0, 774 dataArea.getWidth(), (v1 - v0)); 775 } 776 else if (orientation == PlotOrientation.VERTICAL) { 777 area = new Rectangle2D.Double (v0, dataArea.getMinY(), 778 (v1 - v0), dataArea.getHeight()); 779 } 780 g2.setPaint(marker.getPaint()); 781 g2.fill(area); 782 bounds = area; 783 } 784 785 String label = marker.getLabel(); 786 RectangleAnchor anchor = marker.getLabelAnchor(); 787 if (label != null) { 788 Font labelFont = marker.getLabelFont(); 789 g2.setFont(labelFont); 790 g2.setPaint(marker.getLabelPaint()); 791 Point2D coordinates = calculateDomainMarkerTextAnchorPoint( 792 g2, orientation, dataArea, bounds, marker.getLabelOffset(), 793 marker.getLabelOffsetType(), anchor); 794 TextUtilities.drawAlignedString(label, g2, 795 (float) coordinates.getX(), (float) coordinates.getY(), 796 marker.getLabelTextAnchor()); 797 } 798 g2.setComposite(savedComposite); 799 } 800 801 810 public void drawRangeMarker(Graphics2D g2, 811 CategoryPlot plot, 812 ValueAxis axis, 813 Marker marker, 814 Rectangle2D dataArea) { 815 816 if (marker instanceof ValueMarker) { 817 ValueMarker vm = (ValueMarker) marker; 818 double value = vm.getValue(); 819 Range range = axis.getRange(); 820 821 if (!range.contains(value)) { 822 return; 823 } 824 825 final Composite savedComposite = g2.getComposite(); 826 g2.setComposite(AlphaComposite.getInstance( 827 AlphaComposite.SRC_OVER, marker.getAlpha())); 828 829 PlotOrientation orientation = plot.getOrientation(); 830 double v = axis.valueToJava2D(value, dataArea, 831 plot.getRangeAxisEdge()); 832 Line2D line = null; 833 if (orientation == PlotOrientation.HORIZONTAL) { 834 line = new Line2D.Double (v, dataArea.getMinY(), v, 835 dataArea.getMaxY()); 836 } 837 else if (orientation == PlotOrientation.VERTICAL) { 838 line = new Line2D.Double (dataArea.getMinX(), v, 839 dataArea.getMaxX(), v); 840 } 841 842 g2.setPaint(marker.getPaint()); 843 g2.setStroke(marker.getStroke()); 844 g2.draw(line); 845 846 String label = marker.getLabel(); 847 RectangleAnchor anchor = marker.getLabelAnchor(); 848 if (label != null) { 849 Font labelFont = marker.getLabelFont(); 850 g2.setFont(labelFont); 851 g2.setPaint(marker.getLabelPaint()); 852 Point2D coordinates = calculateRangeMarkerTextAnchorPoint( 853 g2, orientation, dataArea, line.getBounds2D(), 854 marker.getLabelOffset(), LengthAdjustmentType.EXPAND, 855 anchor); 856 TextUtilities.drawAlignedString(label, g2, 857 (float) coordinates.getX(), (float) coordinates.getY(), 858 marker.getLabelTextAnchor()); 859 |