1 64 65 package org.jfree.chart.plot; 66 67 import java.awt.AlphaComposite ; 68 import java.awt.Composite ; 69 import java.awt.Graphics2D ; 70 import java.awt.Paint ; 71 import java.awt.RenderingHints ; 72 import java.awt.Shape ; 73 import java.awt.Stroke ; 74 import java.awt.geom.Ellipse2D ; 75 import java.awt.geom.GeneralPath ; 76 import java.awt.geom.Line2D ; 77 import java.awt.geom.Point2D ; 78 import java.awt.geom.Rectangle2D ; 79 import java.awt.geom.RectangularShape ; 80 import java.beans.PropertyChangeEvent ; 81 import java.beans.PropertyChangeListener ; 82 import java.io.Serializable ; 83 import java.util.Iterator ; 84 import java.util.List ; 85 import java.util.ResourceBundle ; 86 87 import org.jfree.chart.ClipPath; 88 import org.jfree.chart.annotations.XYAnnotation; 89 import org.jfree.chart.axis.AxisSpace; 90 import org.jfree.chart.axis.ColorBar; 91 import org.jfree.chart.axis.NumberAxis; 92 import org.jfree.chart.axis.ValueAxis; 93 import org.jfree.chart.entity.ContourEntity; 94 import org.jfree.chart.entity.EntityCollection; 95 import org.jfree.chart.event.AxisChangeEvent; 96 import org.jfree.chart.event.PlotChangeEvent; 97 import org.jfree.chart.labels.ContourToolTipGenerator; 98 import org.jfree.chart.labels.StandardContourToolTipGenerator; 99 import org.jfree.chart.urls.XYURLGenerator; 100 import org.jfree.data.Range; 101 import org.jfree.data.contour.ContourDataset; 102 import org.jfree.data.general.DatasetChangeEvent; 103 import org.jfree.data.general.DatasetUtilities; 104 import org.jfree.ui.RectangleEdge; 105 import org.jfree.ui.RectangleInsets; 106 import org.jfree.util.ObjectUtilities; 107 108 113 public class ContourPlot extends Plot implements ContourValuePlot, 114 ValueAxisPlot, 115 PropertyChangeListener , 116 Serializable , 117 Cloneable { 118 119 120 private static final long serialVersionUID = 7861072556590502247L; 121 122 123 protected static final RectangleInsets DEFAULT_INSETS 124 = new RectangleInsets(2.0, 2.0, 100.0, 10.0); 125 126 127 private ValueAxis domainAxis; 128 129 130 private ValueAxis rangeAxis; 131 132 133 private ContourDataset dataset; 134 135 136 private ColorBar colorBar = null; 137 138 139 private RectangleEdge colorBarLocation; 140 141 142 private boolean domainCrosshairVisible; 143 144 145 private double domainCrosshairValue; 146 147 148 private transient Stroke domainCrosshairStroke; 149 150 151 private transient Paint domainCrosshairPaint; 152 153 157 private boolean domainCrosshairLockedOnData = true; 158 159 160 private boolean rangeCrosshairVisible; 161 162 163 private double rangeCrosshairValue; 164 165 166 private transient Stroke rangeCrosshairStroke; 167 168 169 private transient Paint rangeCrosshairPaint; 170 171 175 private boolean rangeCrosshairLockedOnData = true; 176 177 178 private List domainMarkers; 179 180 181 private List rangeMarkers; 182 183 184 private List annotations; 185 186 187 private ContourToolTipGenerator toolTipGenerator; 188 189 190 private XYURLGenerator urlGenerator; 191 192 196 private boolean renderAsPoints = false; 197 198 202 private double ptSizePct = 0.05; 203 204 205 private transient ClipPath clipPath = null; 206 207 208 private transient Paint missingPaint = null; 209 210 211 protected static ResourceBundle localizationResources = 212 ResourceBundle.getBundle("org.jfree.chart.plot.LocalizationBundle"); 213 214 223 public ContourPlot(ContourDataset dataset, 224 ValueAxis domainAxis, ValueAxis rangeAxis, 225 ColorBar colorBar) { 226 227 super(); 228 229 this.dataset = dataset; 230 if (dataset != null) { 231 dataset.addChangeListener(this); 232 } 233 234 this.domainAxis = domainAxis; 235 if (domainAxis != null) { 236 domainAxis.setPlot(this); 237 domainAxis.addChangeListener(this); 238 } 239 240 this.rangeAxis = rangeAxis; 241 if (rangeAxis != null) { 242 rangeAxis.setPlot(this); 243 rangeAxis.addChangeListener(this); 244 } 245 246 this.colorBar = colorBar; 247 if (colorBar != null) { 248 colorBar.getAxis().setPlot(this); 249 colorBar.getAxis().addChangeListener(this); 250 colorBar.configure(this); 251 } 252 this.colorBarLocation = RectangleEdge.LEFT; 253 254 this.toolTipGenerator = new StandardContourToolTipGenerator(); 255 256 } 257 258 263 public RectangleEdge getColorBarLocation() { 264 return this.colorBarLocation; 265 } 266 267 273 public void setColorBarLocation(RectangleEdge edge) { 274 this.colorBarLocation = edge; 275 notifyListeners(new PlotChangeEvent(this)); 276 } 277 278 283 public ContourDataset getDataset() { 284 return this.dataset; 285 } 286 287 293 public void setDataset(ContourDataset dataset) { 294 295 ContourDataset existing = this.dataset; 298 if (existing != null) { 299 existing.removeChangeListener(this); 300 } 301 302 this.dataset = dataset; 304 if (dataset != null) { 305 setDatasetGroup(dataset.getGroup()); 306 dataset.addChangeListener(this); 307 } 308 309 DatasetChangeEvent event = new DatasetChangeEvent(this, dataset); 311 datasetChanged(event); 312 313 } 314 315 320 public ValueAxis getDomainAxis() { 321 322 ValueAxis result = this.domainAxis; 323 324 return result; 325 326 } 327 328 334 public void setDomainAxis(ValueAxis axis) { 335 336 if (isCompatibleDomainAxis(axis)) { 337 338 if (axis != null) { 339 axis.setPlot(this); 340 axis.addChangeListener(this); 341 } 342 343 if (this.domainAxis != null) { 345 this.domainAxis.removeChangeListener(this); 346 } 347 348 this.domainAxis = axis; 349 notifyListeners(new PlotChangeEvent(this)); 350 351 } 352 353 } 354 355 360 public ValueAxis getRangeAxis() { 361 362 ValueAxis result = this.rangeAxis; 363 364 return result; 365 366 } 367 368 376 public void setRangeAxis(ValueAxis axis) { 377 378 if (axis != null) { 379 axis.setPlot(this); 380 axis.addChangeListener(this); 381 } 382 383 if (this.rangeAxis != null) { 385 this.rangeAxis.removeChangeListener(this); 386 } 387 388 this.rangeAxis = axis; 389 notifyListeners(new PlotChangeEvent(this)); 390 391 } 392 393 398 public void setColorBarAxis(ColorBar axis) { 399 400 this.colorBar = axis; 401 notifyListeners(new PlotChangeEvent(this)); 402 403 } 404 405 413 public void addDomainMarker(Marker marker) { 414 415 if (this.domainMarkers == null) { 416 this.domainMarkers = new java.util.ArrayList (); 417 } 418 this.domainMarkers.add(marker); 419 notifyListeners(new PlotChangeEvent(this)); 420 421 } 422 423 426 public void clearDomainMarkers() { 427 if (this.domainMarkers != null) { 428 this.domainMarkers.clear(); 429 notifyListeners(new PlotChangeEvent(this)); 430 } 431 } 432 433 441 public void addRangeMarker(Marker marker) { 442 443 if (this.rangeMarkers == null) { 444 this.rangeMarkers = new java.util.ArrayList (); 445 } 446 this.rangeMarkers.add(marker); 447 notifyListeners(new PlotChangeEvent(this)); 448 449 } 450 451 454 public void clearRangeMarkers() { 455 if (this.rangeMarkers != null) { 456 this.rangeMarkers.clear(); 457 notifyListeners(new PlotChangeEvent(this)); 458 } 459 } 460 461 466 public void addAnnotation(XYAnnotation annotation) { 467 468 if (this.annotations == null) { 469 this.annotations = new java.util.ArrayList (); 470 } 471 this.annotations.add(annotation); 472 notifyListeners(new PlotChangeEvent(this)); 473 474 } 475 476 479 public void clearAnnotations() { 480 if (this.annotations != null) { 481 this.annotations.clear(); 482 notifyListeners(new PlotChangeEvent(this)); 483 } 484 } 485 486 494 public boolean isCompatibleDomainAxis(ValueAxis axis) { 495 496 return true; 497 498 } 499 500 516 public void draw(Graphics2D g2, Rectangle2D area, Point2D anchor, 517 PlotState parentState, 518 PlotRenderingInfo info) { 519 520 boolean b1 = (area.getWidth() <= MINIMUM_WIDTH_TO_DRAW); 522 boolean b2 = (area.getHeight() <= MINIMUM_HEIGHT_TO_DRAW); 523 if (b1 || b2) { 524 return; 525 } 526 527 if (info != null) { 529 info.setPlotArea(area); 530 } 531 532 RectangleInsets insets = getInsets(); 534 insets.trim(area); 535 536 AxisSpace space = new AxisSpace(); 537 538 space = this.domainAxis.reserveSpace( 539 g2, this, area, RectangleEdge.BOTTOM, space 540 ); 541 space = this.rangeAxis.reserveSpace( 542 g2, this, area, RectangleEdge.LEFT, space 543 ); 544 545 Rectangle2D estimatedDataArea = space.shrink(area, null); 546 547 AxisSpace space2 = new AxisSpace(); 548 space2 = this.colorBar.reserveSpace( 549 g2, this, area, estimatedDataArea, this.colorBarLocation, 550 space2 551 ); 552 Rectangle2D adjustedPlotArea = space2.shrink(area, null); 553 554 Rectangle2D dataArea = space.shrink(adjustedPlotArea, null); 555 556 Rectangle2D colorBarArea = space2.reserved( 557 area, this.colorBarLocation 558 ); 559 560 if (getDataAreaRatio() != 0.0) { double ratio = getDataAreaRatio(); 563 Rectangle2D tmpDataArea = (Rectangle2D ) dataArea.clone(); 564 double h = tmpDataArea.getHeight(); 565 double w = tmpDataArea.getWidth(); 566 567 if (ratio > 0) { if (w * ratio <= h) { 569 h = ratio * w; 570 } 571 else { 572 w = h / ratio; 573 } 574 } 575 else { ratio *= -1.0; 577 double xLength = getDomainAxis().getRange().getLength(); 578 double yLength = getRangeAxis().getRange().getLength(); 579 double unitRatio = yLength / xLength; 580 581 ratio = unitRatio * ratio; 582 583 if (w * ratio <= h) { 584 h = ratio * w; 585 } 586 else { 587 w = h / ratio; 588 } 589 } 590 591 dataArea.setRect( 592 tmpDataArea.getX() + tmpDataArea.getWidth() / 2 - w / 2, 593 tmpDataArea.getY(), w, h 594 ); 595 } 596 597 if (info != null) { 598 info.setDataArea(dataArea); 599 } 600 601 CrosshairState crosshairState = new CrosshairState(); 602 crosshairState.setCrosshairDistance(Double.POSITIVE_INFINITY); 603 604 drawBackground(g2, dataArea); 606 607 double cursor = dataArea.getMaxY(); 608 if (this.domainAxis != null) { 609 this.domainAxis.draw( 610 g2, cursor, adjustedPlotArea, dataArea, RectangleEdge.BOTTOM, 611 info 612 ); 613 } 614 615 if (this.rangeAxis != null) { 616 cursor = dataArea.getMinX(); 617 this.rangeAxis.draw( 618 g2, cursor, adjustedPlotArea, dataArea, RectangleEdge.LEFT, info 619 ); 620 } 621 622 if (this.colorBar != null) { 623 cursor = 0.0; 624 cursor = this.colorBar.draw( 625 g2, cursor, adjustedPlotArea, dataArea, colorBarArea, 626 this.colorBarLocation 627 ); 628 } 629 Shape originalClip = g2.getClip(); 630 Composite originalComposite = g2.getComposite(); 631 632 g2.clip(dataArea); 633 g2.setComposite(AlphaComposite.getInstance( 634 AlphaComposite.SRC_OVER, getForegroundAlpha()) 635 ); 636 render(g2, dataArea, info, crosshairState); 637 638 if (this.domainMarkers != null) { 639 Iterator iterator = this.domainMarkers.iterator(); 640 while (iterator.hasNext()) { 641 Marker marker = (Marker) iterator.next(); 642 drawDomainMarker(g2, this, getDomainAxis(), marker, dataArea); 643 } 644 } 645 646 if (this.rangeMarkers != null) { 647 Iterator iterator = this.rangeMarkers.iterator(); 648 while (iterator.hasNext()) { 649 Marker marker = (Marker) iterator.next(); 650 drawRangeMarker(g2, this, getRangeAxis(), marker, dataArea); 651 } 652 } 653 654 657 671 g2.setClip(originalClip); 672 g2.setComposite(originalComposite); 673 drawOutline(g2, dataArea); 674 675 } 676 677 689 public void render(Graphics2D g2, Rectangle2D dataArea, 690 PlotRenderingInfo info, CrosshairState crosshairState) { 691 692 ContourDataset data = getDataset(); 695 if (data != null) { 696 697 ColorBar zAxis = getColorBar(); 698 699 if (this.clipPath != null) { 700 GeneralPath clipper = getClipPath().draw( 701 g2, dataArea, this.domainAxis, this.rangeAxis 702 ); 703 if (this.clipPath.isClip()) { 704 g2.clip(clipper); 705 } 706 } 707 708 if (this.renderAsPoints) { 709 pointRenderer(g2, dataArea, info, this, 710 this.domainAxis, this.rangeAxis, zAxis, 711 data, crosshairState); 712 } 713 else { 714 contourRenderer(g2, dataArea, info, this, 715 this.domainAxis, this.rangeAxis, zAxis, 716 data, crosshairState); 717 } 718 719 setDomainCrosshairValue(crosshairState.getCrosshairX(), false); 721 if (isDomainCrosshairVisible()) { 722 drawVerticalLine(g2, dataArea, 723 getDomainCrosshairValue(), 724 getDomainCrosshairStroke(), 725 getDomainCrosshairPaint()); 726 } 727 728 setRangeCrosshairValue(crosshairState.getCrosshairY(), false); 730 if (isRangeCrosshairVisible()) { 731 drawHorizontalLine(g2, dataArea, 732 getRangeCrosshairValue(), 733 getRangeCrosshairStroke(), 734 getRangeCrosshairPaint()); 735 } 736 737 } 738 else if (this.clipPath != null) { 739 getClipPath().draw(g2, dataArea, this.domainAxis, this.rangeAxis); 740 } 741 742 } 743 744 758 public void contourRenderer(Graphics2D g2, 759 Rectangle2D dataArea, 760 PlotRenderingInfo info, 761 ContourPlot plot, 762 ValueAxis horizontalAxis, 763 ValueAxis verticalAxis, 764 ColorBar colorBar, 765 ContourDataset data, 766 CrosshairState crosshairState) { 767 768 Rectangle2D.Double entityArea = null; 770 EntityCollection entities = null; 771 if (info != null) { 772 entities = info.getOwner().getEntityCollection(); 773 } 774 775 Rectangle2D.Double rect = null; 776 rect = new Rectangle2D.Double (); 777 778 Object antiAlias = g2.getRenderingHint(RenderingHints.KEY_ANTIALIASING); 780 g2.setRenderingHint( 781 RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF 782 ); 783 784 Number [] xNumber = data.getXValues(); 786 Number [] yNumber = data.getYValues(); 787 Number [] zNumber = data.getZValues(); 788 789 double[] x = new double[xNumber.length]; 790 double[] y = new double[yNumber.length]; 791 792 for (int i = 0; i < x.length; i++) { 793 x[i] = xNumber[i].doubleValue(); 794 y[i] = yNumber[i].doubleValue(); 795 } 796 797 int[] xIndex = data.indexX(); 798 int[] indexX = data.getXIndices(); 799 boolean vertInverted = ((NumberAxis) verticalAxis).isInverted(); 800 boolean horizInverted = false; 801 if (horizontalAxis instanceof NumberAxis) { 802 horizInverted = ((NumberAxis) horizontalAxis).isInverted(); 803 } 804 double transX = 0.0; 805 double transXm1 = 0.0; 806 double transXp1 = 0.0; 807 double transDXm1 = 0.0; 808 double transDXp1 = 0.0; 809 double transDX = 0.0; 810 double transY = 0.0; 811 double transYm1 = 0.0; 812 double transYp1 = 0.0; 813 double transDYm1 = 0.0; 814 double transDYp1 = 0.0; 815 double transDY = 0.0; 816 int iMax = xIndex[xIndex.length - 1]; 817 for (int k = 0; k < x.length; k++) { 818 int i = xIndex[k]; 819 if (indexX[i] == k) { if (i == 0) { 821 transX = horizontalAxis.valueToJava2D( 822 x[k], dataArea, RectangleEdge.BOTTOM 823 ); 824 transXm1 = transX; 825 transXp1 = horizontalAxis.valueToJava2D( 826 x[indexX[i + 1]], dataArea, RectangleEdge.BOTTOM 827 ); 828 transDXm1 = Math.abs(0.5 * (transX - transXm1)); 829 transDXp1 = Math.abs(0.5 * (transX - transXp1)); 830 } 831 else if (i == iMax) { 832 transX = horizontalAxis.valueToJava2D( 833 x[k], dataArea, RectangleEdge.BOTTOM 834 ); 835 transXm1 = horizontalAxis.valueToJava2D( 836 x[indexX[i - 1]], dataArea, RectangleEdge.BOTTOM 837 ); 838 transXp1 = transX; 839 transDXm1 = Math.abs(0.5 * (transX - transXm1)); 840 transDXp1 = Math.abs(0.5 * (transX - transXp1)); 841 } 842 else { 843 transX = horizontalAxis.valueToJava2D( 844 x[k], dataArea, RectangleEdge.BOTTOM 845 ); 846 transXp1 = horizontalAxis.valueToJava2D( 847 x[indexX[i + 1]], dataArea, RectangleEdge.BOTTOM 848 ); 849 transDXm1 = transDXp1; 850 transDXp1 = Math.abs(0.5 * (transX - transXp1)); 851 } 852 853 if (horizInverted) { 854 transX -= transDXp1; 855 } 856 else { 857 transX -= transDXm1; 858 } 859 860 transDX = transDXm1 + transDXp1; 861 862 transY = verticalAxis.valueToJava2D( 863 y[k], dataArea, RectangleEdge.LEFT 864 ); 865 transYm1 = transY; 866 if (k + 1 == y.length) { 867 continue; 868 } 869 transYp1 = verticalAxis.valueToJava2D( 870 y[k + 1], dataArea, RectangleEdge.LEFT 871 ); 872 transDYm1 = Math.abs(0.5 * (transY - transYm1)); 873 transDYp1 = Math.abs(0.5 * (transY - transYp1)); 874 } 875 else if ((i < indexX.length - 1 876 && indexX[i + 1] - 1 == k) || k == x.length - 1) { 877 transY = verticalAxis.valueToJava2D( 879 y[k], dataArea, RectangleEdge.LEFT 880 ); 881 transYm1 = verticalAxis.valueToJava2D( 882 y[k - 1], dataArea, RectangleEdge.LEFT 883 ); 884 transYp1 = transY; 885 transDYm1 = Math.abs(0.5 * (transY - transYm1)); 886 transDYp1 = Math.abs(0.5 * (transY - transYp1)); 887 } 888 else { 889 transY = verticalAxis.valueToJava2D( 890 y[k], dataArea, RectangleEdge.LEFT 891 ); 892 transYp1 = verticalAxis.valueToJava2D( 893 y[k + 1], dataArea, RectangleEdge.LEFT 894 ); 895 transDYm1 = transDYp1; 896 transDYp1 = Math.abs(0.5 * (transY - transYp1)); 897 } 898 if (vertInverted) { 899 transY -= transDYm1; 900 } 901 else { 902 transY -= transDYp1; 903 } 904 905 transDY = transDYm1 + transDYp1; 906 907 rect.setRect(transX, transY, transDX, transDY); 908 if (zNumber[k] != null) { 909 g2.setPaint(colorBar.getPaint(zNumber[k].doubleValue())); 910 g2.fill(rect); 911 } 912 else if (this.missingPaint != null) { 913 g2.setPaint(this.missingPaint); 914 g2.fill(rect); 915 } 916 917 entityArea = rect; 918 919 if (entities != null) { 921 String tip = ""; 922 if (getToolTipGenerator() != null) { 923 tip = this.toolTipGenerator.generateToolTip(data, k); 924 } 925 String url = null; 928 ContourEntity entity = new ContourEntity( 934 (Rectangle2D.Double ) entityArea.clone(), tip, url 935 ); 936 entity.setIndex(k); 937 entities.add(entity); 938 } 940 941 if (plot.isDomainCrosshairLockedOnData()) { 943 if (plot.isRangeCrosshairLockedOnData()) { 944 crosshairState.updateCrosshairPoint( 946 x[k], y[k], transX, transY, PlotOrientation.VERTICAL 947 ); 948 } 949 else { 950 crosshairState.updateCrosshairX(transX); 952 } 953 } 954 else { 955 if (plot.isRangeCrosshairLockedOnData()) { 956 crosshairState.updateCrosshairY(transY); 958 } 959 } 960 } 961 962 g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, antiAlias); 963 964 return; 965 966 } 967 968 982 public void pointRenderer(Graphics2D g2, 983 Rectangle2D dataArea, 984 PlotRenderingInfo info, 985 ContourPlot plot, 986 ValueAxis domainAxis, 987 ValueAxis rangeAxis, 988 ColorBar colorBar, 989 ContourDataset data, 990 CrosshairState crosshairState) { 991 992 RectangularShape entityArea = null; 994 EntityCollection entities = null; 995 if (info != null) { 996 entities = info.getOwner().getEntityCollection(); 997 } 998 999 RectangularShape rect = new Ellipse2D.Double (); 1002 1003 1004 Object antiAlias = g2.getRenderingHint(RenderingHints.KEY_ANTIALIASING); 1006 g2.setRenderingHint( 1007 RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF 1008 ); 1009 1010 Number [] xNumber = data.getXValues(); 1013 Number [] yNumber = data.getYValues(); 1014 Number [] zNumber = data.getZValues(); 1015 1016 double[] x = new double[xNumber.length]; 1017 double[] y = new double[yNumber.length]; 1018 1019 for (int i = 0; i < x.length; i++) { 1020 x[i] = xNumber[i].doubleValue(); 1021 y[i] = yNumber[i].doubleValue(); 1022 } 1023 1024 double transX = 0.0; 1025 double transDX = 0.0; 1026 double transY = 0.0; 1027 double transDY = 0.0; 1028 double size = dataArea.getWidth() * this.ptSizePct; 1029 for (int k = 0; k < x.length; k++) { 1030 1031 transX = domainAxis.valueToJava2D( 1032 x[k], dataArea, RectangleEdge.BOTTOM 1033 ) - 0.5 * size; 1034 transY = rangeAxis.valueToJava2D(y[k], dataArea, RectangleEdge.LEFT) 1035 - 0.5 * size; 1036 transDX = size; 1037 transDY = size; 1038 1039 rect.setFrame(transX, transY, transDX, transDY); 1040 1041 if (zNumber[k] != null) { 1042 g2.setPaint(colorBar.getPaint(zNumber[k].doubleValue())); 1043 g2.fill(rect); 1044 } 1045 else if (this.missingPaint != null) { 1046 g2.setPaint(this.missingPaint); 1047 g2.fill(rect); 1048 } 1049 1050 1051 entityArea = rect; 1052 1053 if (entities != null) { 1055 String tip = null; 1056 if (getToolTipGenerator() != null) { 1057 tip = this.toolTipGenerator.generateToolTip(data, k); 1058 } 1059 String url = null; 1060 ContourEntity entity = new ContourEntity( 1066 (RectangularShape ) entityArea.clone(), tip, url 1067 ); 1068 entity.setIndex(k); 1069 entities.add(entity); 1070 } 1071 1072 if (plot.isDomainCrosshairLockedOnData()) { 1074 if (plot.isRangeCrosshairLockedOnData()) { 1075 crosshairState.updateCrosshairPoint( 1077 x[k], y[k], transX, transY, PlotOrientation.VERTICAL 1078 ); 1079 } 1080 else { 1081 crosshairState.updateCrosshairX(transX); 1083 } 1084 } 1085 else { 1086 if (plot.isRangeCrosshairLockedOnData()) { 1087 crosshairState.updateCrosshairY(transY); 1089 } 1090 } 1091 } 1092 1093 1094 g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, antiAlias); 1095 1096 return; 1097 1098 } 1099 1100 1109 protected void drawVerticalLine(Graphics2D g2, Rectangle2D dataArea, 1110 double value, Stroke stroke, Paint paint) { 1111 1112 double xx = getDomainAxis().valueToJava2D( 1113 value, dataArea, RectangleEdge.BOTTOM 1114 ); 1115 Line2D line = new Line2D.Double ( 1116 xx, dataArea.getMinY(), xx, dataArea.getMaxY() 1117 ); 1118 g2.setStroke(stroke); 1119 g2.setPaint(paint); 1120 g2.draw(line); 1121 1122 } 1123 1124 1133 protected void drawHorizontalLine(Graphics2D g2, Rectangle2D dataArea, 1134 double value, Stroke stroke, 1135 Paint paint) { 1136 1137 double yy = getRangeAxis().valueToJava2D( 1138 value, dataArea, RectangleEdge.LEFT 1139 ); 1140 Line2D line = new Line2D.Double ( 1141 dataArea.getMinX(), yy, dataArea.getMaxX(), yy 1142 ); 1143 g2.setStroke(stroke); 1144 g2.setPaint(paint); 1145 g2.draw(line); 1146 1147 } 1148 1149 1156 public void handleClick(int x, int y, PlotRenderingInfo info) { 1157 1158 1179 } 1180 1181 1186 public void zoom(double percent) { 1187 1188 if (percent > 0) { 1189 1193 } 1197 else { 1198 getRangeAxis().setAutoRange(true); 1199 getDomainAxis().setAutoRange(true); 1200 } 1201 1202 } 1203 1204 1209 public String getPlotType() { 1210 return localizationResources.getString("Contour_Plot"); 1211 } 1212 1213 1220 public Range getDataRange(ValueAxis axis) { 1221 1222 if (this.dataset == null) { 1223 return null; 1224 } 1225 1226 Range result = null; 1227 1228 if (axis == getDomainAxis()) { 1229 result = DatasetUtilities.findDomainBounds(this.dataset); 1230 } 1231 else if (axis == getRangeAxis()) { 1232 result = DatasetUtilities.findRangeBounds(this.dataset); 1233 } 1234 1235 return result; 1236 1237 } 1238 1239 1244 public Range getContourDataRange() { 1245 1246 Range result = null; 1247 1248 ContourDataset data = getDataset(); 1249 1250 if (data != null) { 1251 Range h = getDomainAxis().getRange(); 1252 Range v = getRangeAxis().getRange(); 1253 result = this.visibleRange(data, h, v); 1254 } 1255 1256 return result; 1257 } 1258 1259 1266 public void propertyChange(PropertyChangeEvent event) { 1267 notifyListeners(new PlotChangeEvent(this)); 1268 } 1269 1270 1278 public void datasetChanged(DatasetChangeEvent event) { 1279 if (this.domainAxis != null) { 1280 this.domainAxis.configure(); 1281 } 1282 if (this.rangeAxis != null) { 1283 this.rangeAxis.configure(); 1284 } 1285 if (this.colorBar != null) { 1286 this.colorBar.configure(this); 1287 } 1288 super.datasetChanged(event); 1289 } 1290 1291 1296 public ColorBar getColorBar() { 1297 return this.colorBar; 1298 } 1299 1300 1305 public boolean isDomainCrosshairVisible() { 1306 return this.domainCrosshairVisible; 1307 } 1308 1309 1314 public void setDomainCrosshairVisible(boolean flag) { 1315 1316 if (this.domainCrosshairVisible != flag) { 1317 this.domainCrosshairVisible = flag; 1318 notifyListeners(new PlotChangeEvent(this)); 1319 } 1320 1321 } 1322 1323 1329 public boolean isDomainCrosshairLockedOnData() { 1330 return this.domainCrosshairLockedOnData; 1331 } 1332 1333 1339 public void setDomainCrosshairLockedOnData(boolean flag) { 1340 if (this.domainCrosshairLockedOnData != flag) { 1341 this.domainCrosshairLockedOnData = flag; 1342 notifyListeners(new PlotChangeEvent(this)); 1343 } 1344 } 1345 1346 1351 public double getDomainCrosshairValue() { 1352 return this.domainCrosshairValue; 1353 } 1354 1355 1363 public void setDomainCrosshairValue(double value) { 1364 1365 setDomainCrosshairValue(value, true); 1366 1367 } 1368 1369 1379 public void setDomainCrosshairValue(double value, boolean notify) { 1380 1381 this.domainCrosshairValue = value; 1382 if (isDomainCrosshairVisible() && notify) { 1383 notifyListeners(new PlotChangeEvent(this)); 1384 } 1385 1386 } 1387 1388 1393 public Stroke getDomainCrosshairStroke() { 1394 return this.domainCrosshairStroke; 1395 } 1396 1397 1403 public void setDomainCrosshairStroke(Stroke stroke) { 1404 this.domainCrosshairStroke = stroke; 1405 notifyListeners(new PlotChangeEvent(this)); 1406 } 1407 1408 1413 public Paint getDomainCrosshairPaint() { 1414 return this.domainCrosshairPaint; 1415 } 1416 1417 1423 public void setDomainCrosshairPaint(Paint paint) { 1424 this.domainCrosshairPaint = paint; 1425 notifyListeners(new PlotChangeEvent(this)); 1426 } 1427 1428 1433 public boolean isRangeCrosshairVisible() { 1434 return this.rangeCrosshairVisible; 1435 } 1436 1437 1442 public void setRangeCrosshairVisible(boolean flag) { 1443 1444 if (this.rangeCrosshairVisible != flag) { 1445 this.rangeCrosshairVisible = flag; 1446 notifyListeners(new PlotChangeEvent(this)); 1447 } 1448 1449 } 1450 1451 1457 public boolean isRangeCrosshairLockedOnData() { 1458 return this.rangeCrosshairLockedOnData; 1459 } 1460 1461 1467 public void setRangeCrosshairLockedOnData(boolean flag) { 1468 1469 if (this.rangeCrosshairLockedOnData != flag) { 1470 this.rangeCrosshairLockedOnData = flag; 1471 notifyListeners(new PlotChangeEvent(this)); 1472 } 1473 1474 } 1475 1476 1481 public double getRangeCrosshairValue() { 1482 return this.rangeCrosshairValue; 1483 } 1484 1485 1493 public void setRangeCrosshairValue(double value) { 1494 1495 setRangeCrosshairValue(value, true); 1496 1497 } 1498 1499 1509 public void setRangeCrosshairValue(double value, boolean notify) { 1510 1511 this.rangeCrosshairValue = value; 1512 if (isRangeCrosshairVisible() && notify) { 1513 notifyListeners(new PlotChangeEvent(this)); 1514 } 1515 1516 } 1517 1518 1523 public Stroke getRangeCrosshairStroke() { 1524 return this.rangeCrosshairStroke; 1525 } 1526 1527 1533 public void setRangeCrosshairStroke(Stroke stroke) { 1534 this.rangeCrosshairStroke = stroke; 1535 notifyListeners(new PlotChangeEvent(this)); 1536 } 1537 1538 1543 public Paint getRangeCrosshairPaint() { 1544 return this.rangeCrosshairPaint; 1545 } 1546 1547 1553 public void setRangeCrosshairPaint(Paint paint) { 1554 this.rangeCrosshairPaint = paint; 1555 notifyListeners(new PlotChangeEvent(this)); 1556 } 1557 1558 1563 public ContourToolTipGenerator getToolTipGenerator() { 1564 return this.toolTipGenerator; 1565 } 1566 1567 1572 public void setToolTipGenerator(ContourToolTipGenerator generator) { 1573 1574 this.toolTipGenerator = generator; 1576 1577 } 1578 1579 1584 public XYURLGenerator getURLGenerator() { 1585 return this.urlGenerator; 1586 } 1587 1588 1593 public void setURLGenerator(XYURLGenerator urlGenerator) { 1594 1595 this.urlGenerator = urlGenerator; 1597 1598 } 1599 1600 1609 public void drawDomainMarker(Graphics2D g2, 1610 ContourPlot plot, 1611 ValueAxis domainAxis, 1612 Marker marker, 1613 Rectangle2D dataArea) { 1614 1615 if (marker instanceof ValueMarker) { 1616 ValueMarker vm = (ValueMarker) marker; 1617 double value = vm.getValue(); 1618 Range range = domainAxis.getRange(); 1619 if (!range.contains(value)) { 1620 return; 1621 } 1622 1623 double x = domainAxis.valueToJava2D( 1624 value, dataArea, RectangleEdge.BOTTOM 1625 ); 1626 Line2D line = new Line2D.Double ( 1627 x, dataArea.getMinY(), x, dataArea.getMaxY() 1628 ); 1629 Paint paint = marker.getOutlinePaint(); 1630 Stroke stroke = marker.getOutlineStroke(); 1631 g2.setPaint(paint != null ? paint : Plot.DEFAULT_OUTLINE_PAINT); 1632 g2.setStroke(stroke != null ? stroke : Plot.DEFAULT_OUTLINE_STROKE); 1633 g2.draw(line); 1634 } 1635 1636 } 1637 1638 1647 public void drawRangeMarker(Graphics2D g2, 1648 ContourPlot plot, 1649 ValueAxis rangeAxis, 1650 Marker marker, 1651 Rectangle2D dataArea) { 1652 1653 if (marker instanceof ValueMarker) { 1654 ValueMarker vm = (ValueMarker) marker; 1655 double value = vm.getValue(); 1656 Range range = rangeAxis.getRange(); 1657 if (!range.contains(value)) { 1658 return; 1659 } 1660 1661 double y = rangeAxis.valueToJava2D( 1662 value, dataArea, RectangleEdge.LEFT 1663 ); 1664 Line2D line = new Line2D.Double ( 1665 dataArea.getMinX(), y, dataArea.getMaxX(), y 1666 ); 1667 Paint paint = marker.getOutlinePaint(); 1668 Stroke stroke = marker.getOutlineStroke(); 1669 g2.setPaint(paint != null ? paint : Plot.DEFAULT_OUTLINE_PAINT); 1670 g2.setStroke(stroke != null ? stroke : Plot.DEFAULT_OUTLINE_STROKE); 1671 g2.draw(line); 1672 } 1673 1674 } 1675 1676 1680 public ClipPath getClipPath() { 1681 return this.clipPath; 1682 } 1683 1684 1688 public void setClipPath(ClipPath clipPath) { 1689 this.clipPath = clipPath; 1690 } 1691 1692 1696 public double getPtSizePct() { 1697 return this.ptSizePct; 1698 } 1699 1700 1704 public boolean isRenderAsPoints() { 1705 return this.renderAsPoints; 1706 } 1707 1708 1712 public void setPtSizePct(double ptSizePct) { 1713 this.ptSizePct = ptSizePct; 1714 } 1715 1716 1720 public void setRenderAsPoints(boolean renderAsPoints) { 1721 this.renderAsPoints = renderAsPoints; 1722 } 1723 1724 1729 public void axisChanged(AxisChangeEvent event) { 1730 Object source = event.getSource(); 1731 if (source.equals(this.rangeAxis) || source.equals(this.domainAxis)) { 1732 ColorBar cba = this.colorBar; 1733 if (this.colorBar.getAxis().isAutoRange()) { 1734 cba.getAxis().configure(); 1735 } 1736 1737 } 1738 super.axisChanged(event); 1739 } 1740 1741 1750 public Range visibleRange(ContourDataset data, Range x, Range y) { 1751 Range range = null; 1752 range = data.getZValueRange(x, y); 1753 return range; 1754 } 1755 1756 1760 public Paint getMissingPaint() { 1761 return this.missingPaint; 1762 } 1763 1764 1769 public void setMissingPaint(Paint paint) { 1770 this.missingPaint = paint; 1771 } 1772 1773 1781 public void zoomDomainAxes(double x, double y, double factor) { 1782 } 1784 1785 1793 public void zoomDomainAxes(double x, double y, double lowerPercent, 1794 double upperPercent) { 1795 } 1797 1798 1805 public void zoomRangeAxes(double x, double y, double factor) { 1806 } 1808 1809 1817 public void zoomRangeAxes(double x, double y, double lowerPercent, 1818 double upperPercent) { 1819 } 1821 1822 1827 public boolean isDomainZoomable() { 1828 return false; 1829 } 1830 1831 1836 public boolean isRangeZoomable() { 1837 return false; 1838 } 1839 1840 1844 public Object clone() throws CloneNotSupportedException { 1845 ContourPlot clone = (ContourPlot) super.clone(); 1846 1847 if (this.domainAxis != null) { 1848 clone.domainAxis = (ValueAxis) this.domainAxis.clone(); 1849 clone.domainAxis.setPlot(clone); 1850 clone.domainAxis.addChangeListener(clone); 1851 } 1852 if (this.rangeAxis != null) { 1853 clone.rangeAxis = (ValueAxis) this.rangeAxis.clone(); 1854 clone.rangeAxis.setPlot(clone); 1855 clone.rangeAxis.addChangeListener(clone); 1856 } 1857 1858 if (clone.dataset != null) { 1859 clone.dataset.addChangeListener(clone); 1860 } 1861 1862 if (this.colorBar != null) { 1863 clone.colorBar = (ColorBar) this.colorBar.clone(); 1864 } 1865 1866 clone.domainMarkers = (List ) ObjectUtilities.deepClone( 1867 this.domainMarkers 1868 ); 1869 clone.rangeMarkers = (List ) ObjectUtilities.deepClone( 1870 this.rangeMarkers 1871 ); 1872 clone.annotations = (List ) ObjectUtilities.deepClone(this.annotations); 1873 1874 if (this.clipPath != null) { 1875 clone.clipPath = (ClipPath) this.clipPath.clone(); 1876 } 1877 1878 return clone; 1879 } 1880 1881} 1882 | Popular Tags |