1 57 58 package org.jfree.chart.renderer; 59 60 import java.awt.Font ; 61 import java.awt.FontMetrics ; 62 import java.awt.Graphics2D ; 63 import java.awt.Paint ; 64 import java.awt.Shape ; 65 import java.awt.Stroke ; 66 import java.awt.font.FontRenderContext ; 67 import java.awt.font.LineMetrics ; 68 import java.awt.geom.Line2D ; 69 import java.awt.geom.Rectangle2D ; 70 import java.io.Serializable ; 71 72 import org.jfree.chart.LegendItem; 73 import org.jfree.chart.Marker; 74 import org.jfree.chart.MarkerLabelPosition; 75 import org.jfree.chart.axis.ValueAxis; 76 import org.jfree.chart.labels.XYToolTipGenerator; 77 import org.jfree.chart.plot.DrawingSupplier; 78 import org.jfree.chart.plot.Plot; 79 import org.jfree.chart.plot.PlotOrientation; 80 import org.jfree.chart.plot.PlotRenderingInfo; 81 import org.jfree.chart.plot.XYPlot; 82 import org.jfree.chart.urls.XYURLGenerator; 83 import org.jfree.data.Range; 84 import org.jfree.data.XYDataset; 85 import org.jfree.util.ObjectUtils; 86 import org.jfree.util.PublicCloneable; 87 88 93 public abstract class AbstractXYItemRenderer extends AbstractRenderer implements XYItemRenderer, 94 Cloneable , 95 Serializable { 96 97 98 private XYPlot plot; 99 100 101 private XYToolTipGenerator toolTipGenerator; 102 103 104 private XYURLGenerator urlGenerator; 105 106 109 protected AbstractXYItemRenderer() { 110 this.toolTipGenerator = null; 111 this.urlGenerator = null; 112 } 113 114 123 protected AbstractXYItemRenderer(XYToolTipGenerator toolTipGenerator) { 124 this(toolTipGenerator, null); 125 } 126 127 136 protected AbstractXYItemRenderer(XYURLGenerator urlGenerator) { 137 this(null, urlGenerator); 138 } 139 140 150 protected AbstractXYItemRenderer(XYToolTipGenerator toolTipGenerator, 151 XYURLGenerator urlGenerator) { 152 153 this.toolTipGenerator = toolTipGenerator; 154 this.urlGenerator = urlGenerator; 155 156 } 157 158 164 public int getPassCount() { 165 return 1; 166 } 167 168 173 public XYPlot getPlot() { 174 return this.plot; 175 } 176 177 182 public void setPlot(XYPlot plot) { 183 this.plot = plot; 184 } 185 186 201 public XYItemRendererState initialise(Graphics2D g2, 202 Rectangle2D dataArea, 203 XYPlot plot, 204 XYDataset data, 205 PlotRenderingInfo info) { 206 207 XYItemRendererState state = new XYItemRendererState(info); 208 return state; 209 210 } 211 212 217 public XYToolTipGenerator getToolTipGenerator() { 218 return this.toolTipGenerator; 219 } 220 221 226 public void setToolTipGenerator(XYToolTipGenerator generator) { 227 228 Object oldValue = this.toolTipGenerator; 229 this.toolTipGenerator = generator; 230 firePropertyChanged("renderer.ToolTipGenerator", oldValue, generator); 231 232 } 233 234 239 public XYURLGenerator getURLGenerator() { 240 return this.urlGenerator; 241 } 242 243 248 public void setURLGenerator(XYURLGenerator urlGenerator) { 249 250 Object oldValue = this.urlGenerator; 251 this.urlGenerator = urlGenerator; 252 firePropertyChanged("renderer.URLGenerator", oldValue, urlGenerator); 253 254 } 255 256 267 public RangeType getRangeType() { 268 return RangeType.STANDARD; 269 } 270 271 279 public LegendItem getLegendItem(int datasetIndex, int series) { 280 281 LegendItem result = null; 282 283 XYPlot plot = getPlot(); 284 if (plot != null) { 285 XYDataset dataset; 286 if (datasetIndex == 0) { 287 dataset = plot.getDataset(); 288 } 289 else { 290 dataset = plot.getSecondaryDataset(datasetIndex - 1); 291 } 292 293 if (dataset != null) { 294 String label = dataset.getSeriesName(series); 295 String description = label; 296 Shape shape = getSeriesShape(series); 297 Paint paint = getSeriesPaint(series); 298 Paint outlinePaint = getSeriesOutlinePaint(series); 299 Stroke stroke = getSeriesStroke(series); 300 301 result = new LegendItem(label, description, 302 shape, paint, outlinePaint, stroke); 303 } 304 305 } 306 307 return result; 308 309 } 310 311 322 public void fillDomainGridBand(Graphics2D g2, 323 XYPlot plot, 324 ValueAxis axis, 325 Rectangle2D dataArea, 326 double start, double end) { 327 328 double x1 = axis.translateValueToJava2D(start, dataArea, plot.getDomainAxisEdge()); 329 double x2 = axis.translateValueToJava2D(end, dataArea, plot.getDomainAxisEdge()); 330 Rectangle2D band = new Rectangle2D.Double (x1, dataArea.getMinY(), 332 x2 - x1, dataArea.getMaxY() - dataArea.getMinY()); 333 Paint paint = plot.getDomainTickBandPaint(); 334 335 if (paint != null) { 336 g2.setPaint(paint); 337 g2.fill(band); 338 } 339 340 } 341 342 353 public void fillRangeGridBand(Graphics2D g2, 354 XYPlot plot, 355 ValueAxis axis, 356 Rectangle2D dataArea, 357 double start, double end) { 358 359 double y1 = axis.translateValueToJava2D(start, dataArea, plot.getRangeAxisEdge()); 360 double y2 = axis.translateValueToJava2D(end, dataArea, plot.getRangeAxisEdge()); 361 Rectangle2D band = new Rectangle2D.Double (dataArea.getMinX(), y2, 363 dataArea.getWidth(), y1 - y2); 364 Paint paint = plot.getRangeTickBandPaint(); 365 366 if (paint != null) { 367 g2.setPaint(paint); 368 g2.fill(band); 369 } 370 371 } 372 373 383 public void drawDomainGridLine(Graphics2D g2, 384 XYPlot plot, 385 ValueAxis axis, 386 Rectangle2D dataArea, 387 double value) { 388 389 Range range = axis.getRange(); 390 if (!range.contains(value)) { 391 return; 392 } 393 394 PlotOrientation orientation = plot.getOrientation(); 395 double v = axis.translateValueToJava2D(value, dataArea, plot.getDomainAxisEdge()); 396 Line2D line = null; 397 if (orientation == PlotOrientation.HORIZONTAL) { 398 line = new Line2D.Double (dataArea.getMinX(), v, dataArea.getMaxX(), v); 399 } 400 else if (orientation == PlotOrientation.VERTICAL) { 401 line = new Line2D.Double (v, dataArea.getMinY(), v, dataArea.getMaxY()); 402 } 403 404 Paint paint = plot.getDomainGridlinePaint(); 405 Stroke stroke = plot.getDomainGridlineStroke(); 406 g2.setPaint(paint != null ? paint : Plot.DEFAULT_OUTLINE_PAINT); 407 g2.setStroke(stroke != null ? stroke : Plot.DEFAULT_OUTLINE_STROKE); 408 g2.draw(line); 409 410 } 411 412 422 public void drawRangeGridLine(Graphics2D g2, 423 XYPlot plot, 424 ValueAxis axis, 425 Rectangle2D dataArea, 426 double value) { 427 428 Range range = axis.getRange(); 429 if (!range.contains(value)) { 430 return; 431 } 432 433 PlotOrientation orientation = plot.getOrientation(); 434 Line2D line = null; 435 double v = axis.translateValueToJava2D(value, dataArea, plot.getRangeAxisEdge()); 436 if (orientation == PlotOrientation.HORIZONTAL) { 437 line = new Line2D.Double (v, dataArea.getMinY(), v, dataArea.getMaxY()); 438 } 439 else if (orientation == PlotOrientation.VERTICAL) { 440 line = new Line2D.Double (dataArea.getMinX(), v, dataArea.getMaxX(), v); 441 } 442 443 Paint paint = plot.getRangeGridlinePaint(); 444 Stroke stroke = plot.getRangeGridlineStroke(); 445 g2.setPaint(paint != null ? paint : Plot.DEFAULT_OUTLINE_PAINT); 446 g2.setStroke(stroke != null ? stroke : Plot.DEFAULT_OUTLINE_STROKE); 447 g2.draw(line); 448 449 } 450 451 460 public void drawDomainMarker(Graphics2D g2, 461 XYPlot plot, 462 ValueAxis domainAxis, 463 Marker marker, 464 Rectangle2D dataArea) { 465 466 double value = marker.getValue(); 467 Range range = domainAxis.getRange(); 468 if (!range.contains(value)) { 469 return; 470 } 471 472 double v = domainAxis.translateValueToJava2D(marker.getValue(), dataArea, 473 plot.getDomainAxisEdge()); 474 475 PlotOrientation orientation = plot.getOrientation(); 476 Line2D line = null; 477 if (orientation == PlotOrientation.HORIZONTAL) { 478 line = new Line2D.Double (dataArea.getMinX(), v, dataArea.getMaxX(), v); 479 } 480 else if (orientation == PlotOrientation.VERTICAL) { 481 line = new Line2D.Double (v, dataArea.getMinY(), v, dataArea.getMaxY()); 482 } 483 Paint paint = marker.getOutlinePaint(); 484 Stroke stroke = marker.getOutlineStroke(); 485 g2.setPaint(paint != null ? paint : Plot.DEFAULT_OUTLINE_PAINT); 486 g2.setStroke(stroke != null ? stroke : Plot.DEFAULT_OUTLINE_STROKE); 487 g2.draw(line); 488 489 String label = marker.getLabel(); 490 MarkerLabelPosition position = marker.getLabelPosition(); 491 if (label != null) { 492 Font labelFont = marker.getLabelFont(); 493 g2.setFont(labelFont); 494 g2.setPaint(marker.getLabelPaint()); 495 double[] coordinates = calculateDomainMarkerTextPosition(g2, orientation, dataArea, 496 v, label, labelFont, 497 position); 498 g2.drawString(label, (int) coordinates[0], (int) coordinates[1]); 499 } 500 501 } 502 503 516 private double[] calculateDomainMarkerTextPosition(Graphics2D g2, 517 PlotOrientation orientation, 518 Rectangle2D dataArea, 519 double coordinate, 520 String label, 521 Font font, 522 MarkerLabelPosition position) { 523 524 double[] result = new double[2]; 525 FontRenderContext frc = g2.getFontRenderContext(); 526 FontMetrics fm = g2.getFontMetrics(); 527 LineMetrics metrics = font.getLineMetrics(label, frc); 528 Rectangle2D bounds = fm.getStringBounds(label, g2); 529 if (orientation == PlotOrientation.HORIZONTAL) { 530 if (position == MarkerLabelPosition.TOP_LEFT) { 531 result[0] = dataArea.getMinX() + 2.0; 532 result[1] = coordinate - metrics.getDescent() - metrics.getLeading(); 533 } 534 else if (position == MarkerLabelPosition.TOP_RIGHT) { 535 result[0] = dataArea.getMaxX() - bounds.getWidth() - 2.0; 536 result[1] = coordinate - metrics.getDescent() - metrics.getLeading(); 537 } 538 else if (position == MarkerLabelPosition.BOTTOM_LEFT) { 539 result[0] = dataArea.getMinX() + 2.0; 540 result[1] = coordinate + bounds.getHeight(); 541 } 542 else if (position == MarkerLabelPosition.BOTTOM_RIGHT) { 543 result[0] = dataArea.getMaxX() - bounds.getWidth() - 2.0; 544 result[1] = coordinate + bounds.getHeight(); 545 } 546 } 547 else if (orientation == PlotOrientation.VERTICAL) { 548 if (position == MarkerLabelPosition.TOP_LEFT) { 549 result[0] = coordinate - bounds.getWidth() - 2.0; 550 result[1] = dataArea.getMinY() + bounds.getHeight(); 551 } 552 else if (position == MarkerLabelPosition.TOP_RIGHT) { 553 result[0] = coordinate + 2.0; 554 result[1] = dataArea.getMinY() + bounds.getHeight(); 555 } 556 else if (position == MarkerLabelPosition.BOTTOM_LEFT) { 557 result[0] = coordinate - bounds.getWidth() - 2.0; 558 result[1] = dataArea.getMaxY() - metrics.getDescent() - metrics.getLeading(); 559 } 560 else if (position == MarkerLabelPosition.BOTTOM_RIGHT) { 561 result[0] = coordinate + 2.0; 562 result[1] = dataArea.getMaxY() - metrics.getDescent() - metrics.getLeading(); 563 } 564 } 565 return result; 566 567 } 568 569 578 public void drawRangeMarker(Graphics2D g2, 579 XYPlot plot, 580 ValueAxis rangeAxis, 581 Marker marker, 582 Rectangle2D dataArea) { 583 584 double value = marker.getValue(); 585 Range range = rangeAxis.getRange(); 586 if (!range.contains(value)) { 587 return; 588 } 589 590 double v = rangeAxis.translateValueToJava2D(marker.getValue(), dataArea, 591 plot.getRangeAxisEdge()); 592 PlotOrientation orientation = plot.getOrientation(); 593 Line2D line = null; 594 if (orientation == PlotOrientation.HORIZONTAL) { 595 line = new Line2D.Double (v, dataArea.getMinY(), v, dataArea.getMaxY()); 596 } 597 else if (orientation == PlotOrientation.VERTICAL) { 598 line = new Line2D.Double (dataArea.getMinX(), v, dataArea.getMaxX(), v); 599 } 600 Paint paint = marker.getOutlinePaint(); 601 Stroke stroke = marker.getOutlineStroke(); 602 g2.setPaint(paint != null ? paint : Plot.DEFAULT_OUTLINE_PAINT); 603 g2.setStroke(stroke != null ? stroke : Plot.DEFAULT_OUTLINE_STROKE); 604 g2.draw(line); 605 606 String label = marker.getLabel(); 607 MarkerLabelPosition position = marker.getLabelPosition(); 608 if (label != null) { 609 Font labelFont = marker.getLabelFont(); 610 g2.setFont(labelFont); 611 g2.setPaint(marker.getLabelPaint()); 612 double[] coordinates = calculateRangeMarkerTextPosition(g2, orientation, dataArea, 613 v, label, labelFont, 614 position); 615 g2.drawString(label, (int) coordinates[0], (int) coordinates[1]); 616 } 617 618 } 619 620 633 private double[] calculateRangeMarkerTextPosition(Graphics2D g2, 634 PlotOrientation orientation, 635 Rectangle2D dataArea, 636 double coordinate, 637 String label, 638 Font font, 639 MarkerLabelPosition position) { 640 641 double[] result = new double[2]; 642 FontRenderContext frc = g2.getFontRenderContext(); 643 FontMetrics fm = g2.getFontMetrics(); 644 LineMetrics metrics = font.getLineMetrics(label, frc); 645 Rectangle2D bounds = fm.getStringBounds(label, g2); 646 if (orientation == PlotOrientation.HORIZONTAL) { 647 if (position == MarkerLabelPosition.TOP_LEFT) { 648 result[0] = coordinate - bounds.getWidth() - 2.0; 649 result[1] = dataArea.getMinY() + bounds.getHeight(); 650 } 651 else if (position == MarkerLabelPosition.TOP_RIGHT) { 652 result[0] = coordinate + 2.0; 653 result[1] = dataArea.getMinY() + bounds.getHeight(); 654 } 655 else if (position == MarkerLabelPosition.BOTTOM_LEFT) { 656 result[0] = coordinate - bounds.getWidth() - 2.0; 657 result[1] = dataArea.getMaxY() - metrics.getDescent() - metrics.getLeading(); 658 } 659 else if (position == MarkerLabelPosition.BOTTOM_RIGHT) { 660 result[0] = coordinate + 2.0; 661 result[1] = dataArea.getMaxY() - metrics.getDescent() - metrics.getLeading(); 662 } 663 } 664 else if (orientation == PlotOrientation.VERTICAL) { 665 if (position == MarkerLabelPosition.TOP_LEFT) { 666 result[0] = dataArea.getMinX() + 2.0; 667 result[1] = coordinate - metrics.getDescent() - metrics.getLeading(); 668 } 669 else if (position == MarkerLabelPosition.TOP_RIGHT) { 670 result[0] = dataArea.getMaxX() - bounds.getWidth() - 2.0; 671 result[1] = coordinate - metrics.getDescent() - metrics.getLeading(); 672 } 673 else if (position == MarkerLabelPosition.BOTTOM_LEFT) { 674 result[0] = dataArea.getMinX() + 2.0; 675 result[1] = coordinate + bounds.getHeight(); 676 } 677 else if (position == MarkerLabelPosition.BOTTOM_RIGHT) { 678 result[0] = dataArea.getMaxX() - bounds.getWidth() - 2.0; 679 result[1] = coordinate + bounds.getHeight(); 680 } 681 } 682 return result; 683 684 } 685 686 693 protected Object clone() throws CloneNotSupportedException { 694 AbstractXYItemRenderer clone = (AbstractXYItemRenderer) super.clone(); 695 if (this.toolTipGenerator != null && this.toolTipGenerator instanceof PublicCloneable) { 697 PublicCloneable pc = (PublicCloneable) this.toolTipGenerator; 698 clone.toolTipGenerator = (XYToolTipGenerator) pc.clone(); 699 } 700 return clone; 701 } 702 703 710 public boolean equals(Object obj) { 711 712 if (obj == null) { 713 return false; 714 } 715 716 if (obj == this) { 717 return true; 718 } 719 720 if (obj instanceof AbstractXYItemRenderer) { 721 AbstractXYItemRenderer renderer = (AbstractXYItemRenderer) obj; 722 if (super.equals(obj)) { 723 boolean b0 = ObjectUtils.equal(this.toolTipGenerator, renderer.toolTipGenerator); 724 boolean b1 = ObjectUtils.equal(this.urlGenerator, renderer.urlGenerator); 725 return b0 && b1; 726 } 727 else { 728 return false; 729 } 730 } 731 732 return false; 733 734 } 735 736 741 public DrawingSupplier getDrawingSupplier() { 742 DrawingSupplier result = null; 743 XYPlot p = getPlot(); 744 if (p != null) { 745 result = p.getDrawingSupplier(); 746 } 747 return result; 748 } 749 750 } 751 | Popular Tags |