Frames | No Frames |
1: /* =========================================================== 2: * JFreeChart : a free chart library for the Java(tm) platform 3: * =========================================================== 4: * 5: * (C) Copyright 2000-2007, by Object Refinery Limited and Contributors. 6: * 7: * Project Info: http://www.jfree.org/jfreechart/index.html 8: * 9: * This library is free software; you can redistribute it and/or modify it 10: * under the terms of the GNU Lesser General Public License as published by 11: * the Free Software Foundation; either version 2.1 of the License, or 12: * (at your option) any later version. 13: * 14: * This library is distributed in the hope that it will be useful, but 15: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 16: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 17: * License for more details. 18: * 19: * You should have received a copy of the GNU Lesser General Public 20: * License along with this library; if not, write to the Free Software 21: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 22: * USA. 23: * 24: * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 25: * in the United States and other countries.] 26: * 27: * ------------------- 28: * CrosshairState.java 29: * ------------------- 30: * (C) Copyright 2002-2007, by Object Refinery Limited. 31: * 32: * Original Author: David Gilbert (for Object Refinery Limited); 33: * Contributor(s): -; 34: * 35: * Changes 36: * ------- 37: * 24-Jan-2002 : Version 1 (DG); 38: * 05-Mar-2002 : Added Javadoc comments (DG); 39: * 26-Sep-2002 : Fixed errors reported by Checkstyle (DG); 40: * 19-Sep-2003 : Modified crosshair distance calculation (DG); 41: * 04-Dec-2003 : Crosshair anchor point now stored outside chart since it is 42: * dependent on the display target (DG); 43: * 25-Feb-2004 : Replaced CrosshairInfo --> CrosshairState (DG); 44: * ------------- JFREECHART 1.0.x --------------------------------------------- 45: * 13-Oct-2006 : Fixed initialisation of CrosshairState - see bug report 46: * 1565168 (DG); 47: * 06-Feb-2007 : Added new fields and methods to fix bug 1086307 (DG); 48: * 49: */ 50: 51: package org.jfree.chart.plot; 52: 53: import java.awt.geom.Point2D; 54: 55: /** 56: * Maintains state information about crosshairs on a plot between successive 57: * calls to the renderer's draw method. This class is used internally by 58: * JFreeChart - it is not intended for external use. 59: */ 60: public class CrosshairState { 61: 62: /** 63: * A flag that controls whether the distance is calculated in data space 64: * or Java2D space. 65: */ 66: private boolean calculateDistanceInDataSpace = false; 67: 68: /** The x-value (in data space) for the anchor point. */ 69: private double anchorX; 70: 71: /** The y-value (in data space) for the anchor point. */ 72: private double anchorY; 73: 74: /** The anchor point in Java2D space - if null, don't update crosshair. */ 75: private Point2D anchor; 76: 77: /** The x-value for the current crosshair point. */ 78: private double crosshairX; 79: 80: /** The y-value for the current crosshair point. */ 81: private double crosshairY; 82: 83: /** 84: * The index of the domain axis that the crosshair x-value is measured 85: * against. 86: * 87: * @since 1.0.4 88: */ 89: private int domainAxisIndex; 90: 91: /** 92: * The index of the range axis that the crosshair y-value is measured 93: * against. 94: * 95: * @since 1.0.4 96: */ 97: private int rangeAxisIndex; 98: 99: /** 100: * The smallest distance (so far) between the anchor point and a data 101: * point. 102: */ 103: private double distance; 104: 105: /** 106: * Creates a new <code>CrosshairState</code> instance that calculates 107: * distance in Java2D space. 108: */ 109: public CrosshairState() { 110: this(false); 111: } 112: 113: /** 114: * Creates a new <code>CrosshairState</code> instance. 115: * 116: * @param calculateDistanceInDataSpace a flag that controls whether the 117: * distance is calculated in data 118: * space or Java2D space. 119: */ 120: public CrosshairState(boolean calculateDistanceInDataSpace) { 121: this.calculateDistanceInDataSpace = calculateDistanceInDataSpace; 122: } 123: 124: /** 125: * Returns the distance between the anchor point and the current crosshair 126: * point. 127: * 128: * @return The distance. 129: * 130: * @see #setCrosshairDistance(double) 131: * @since 1.0.3 132: */ 133: public double getCrosshairDistance() { 134: return this.distance; 135: } 136: 137: /** 138: * Sets the distance between the anchor point and the current crosshair 139: * point. As each data point is processed, its distance to the anchor 140: * point is compared with this value and, if it is closer, the data point 141: * becomes the new crosshair point. 142: * 143: * @param distance the distance. 144: * 145: * @see #getCrosshairDistance() 146: */ 147: public void setCrosshairDistance(double distance) { 148: this.distance = distance; 149: } 150: 151: /** 152: * Evaluates a data point and if it is the closest to the anchor point it 153: * becomes the new crosshair point. 154: * <P> 155: * To understand this method, you need to know the context in which it will 156: * be called. An instance of this class is passed to an 157: * {@link org.jfree.chart.renderer.xy.XYItemRenderer} as 158: * each data point is plotted. As the point is plotted, it is passed to 159: * this method to see if it should be the new crosshair point. 160: * 161: * @param x x coordinate (measured against the domain axis). 162: * @param y y coordinate (measured against the range axis). 163: * @param transX x translated into Java2D space. 164: * @param transY y translated into Java2D space. 165: * @param orientation the plot orientation. 166: * 167: * @deprecated Use {@link #updateCrosshairPoint(double, double, int, int, 168: * double, double, PlotOrientation)}. See bug report 1086307. 169: */ 170: public void updateCrosshairPoint(double x, double y, 171: double transX, double transY, 172: PlotOrientation orientation) { 173: updateCrosshairPoint(x, y, 0, 0, transX, transY, orientation); 174: } 175: 176: /** 177: * Evaluates a data point and if it is the closest to the anchor point it 178: * becomes the new crosshair point. 179: * <P> 180: * To understand this method, you need to know the context in which it will 181: * be called. An instance of this class is passed to an 182: * {@link org.jfree.chart.renderer.xy.XYItemRenderer} as 183: * each data point is plotted. As the point is plotted, it is passed to 184: * this method to see if it should be the new crosshair point. 185: * 186: * @param x x coordinate (measured against the domain axis). 187: * @param y y coordinate (measured against the range axis). 188: * @param domainAxisIndex the index of the domain axis for this point. 189: * @param rangeAxisIndex the index of the range axis for this point. 190: * @param transX x translated into Java2D space. 191: * @param transY y translated into Java2D space. 192: * @param orientation the plot orientation. 193: * 194: * @since 1.0.4 195: */ 196: public void updateCrosshairPoint(double x, double y, int domainAxisIndex, 197: int rangeAxisIndex, double transX, double transY, 198: PlotOrientation orientation) { 199: 200: if (this.anchor != null) { 201: double d = 0.0; 202: if (this.calculateDistanceInDataSpace) { 203: d = (x - this.anchorX) * (x - this.anchorX) 204: + (y - this.anchorY) * (y - this.anchorY); 205: } 206: else { 207: double xx = this.anchor.getX(); 208: double yy = this.anchor.getY(); 209: if (orientation == PlotOrientation.HORIZONTAL) { 210: double temp = yy; 211: yy = xx; 212: xx = temp; 213: } 214: d = (transX - xx) * (transX - xx) 215: + (transY - yy) * (transY - yy); 216: } 217: 218: if (d < this.distance) { 219: this.crosshairX = x; 220: this.crosshairY = y; 221: this.domainAxisIndex = domainAxisIndex; 222: this.rangeAxisIndex = rangeAxisIndex; 223: this.distance = d; 224: } 225: } 226: 227: } 228: 229: /** 230: * Evaluates an x-value and if it is the closest to the anchor x-value it 231: * becomes the new crosshair value. 232: * <P> 233: * Used in cases where only the x-axis is numerical. 234: * 235: * @param candidateX x position of the candidate for the new crosshair 236: * point. 237: * 238: * @deprecated Use {@link #updateCrosshairX(double, int)}. See bug report 239: * 1086307. 240: */ 241: public void updateCrosshairX(double candidateX) { 242: updateCrosshairX(candidateX, 0); 243: } 244: 245: /** 246: * Evaluates an x-value and if it is the closest to the anchor x-value it 247: * becomes the new crosshair value. 248: * <P> 249: * Used in cases where only the x-axis is numerical. 250: * 251: * @param candidateX x position of the candidate for the new crosshair 252: * point. 253: * @param domainAxisIndex the index of the domain axis for this x-value. 254: * 255: * @since 1.0.4 256: */ 257: public void updateCrosshairX(double candidateX, int domainAxisIndex) { 258: 259: double d = Math.abs(candidateX - this.anchorX); 260: if (d < this.distance) { 261: this.crosshairX = candidateX; 262: this.domainAxisIndex = domainAxisIndex; 263: this.distance = d; 264: } 265: 266: } 267: 268: /** 269: * Evaluates a y-value and if it is the closest to the anchor y-value it 270: * becomes the new crosshair value. 271: * <P> 272: * Used in cases where only the y-axis is numerical. 273: * 274: * @param candidateY y position of the candidate for the new crosshair 275: * point. 276: * 277: * @deprecated Use {@link #updateCrosshairY(double, int)}. See bug report 278: * 1086307. 279: */ 280: public void updateCrosshairY(double candidateY) { 281: updateCrosshairY(candidateY, 0); 282: } 283: 284: /** 285: * Evaluates a y-value and if it is the closest to the anchor y-value it 286: * becomes the new crosshair value. 287: * <P> 288: * Used in cases where only the y-axis is numerical. 289: * 290: * @param candidateY y position of the candidate for the new crosshair 291: * point. 292: * @param rangeAxisIndex the index of the range axis for this y-value. 293: * 294: * @since 1.0.4 295: */ 296: public void updateCrosshairY(double candidateY, int rangeAxisIndex) { 297: double d = Math.abs(candidateY - this.anchorY); 298: if (d < this.distance) { 299: this.crosshairY = candidateY; 300: this.rangeAxisIndex = rangeAxisIndex; 301: this.distance = d; 302: } 303: 304: } 305: 306: /** 307: * Returns the anchor point. 308: * 309: * @return The anchor point. 310: * 311: * @see #setAnchor(Point2D) 312: * @since 1.0.3 313: */ 314: public Point2D getAnchor() { 315: return this.anchor; 316: } 317: 318: /** 319: * Sets the anchor point. This is usually the mouse click point in a chart 320: * panel, and the crosshair point will often be the data item that is 321: * closest to the anchor point. 322: * <br><br> 323: * Note that the x and y coordinates (in data space) are not updated by 324: * this method - the caller is responsible for ensuring that this happens 325: * in sync. 326: * 327: * @param anchor the anchor point (<code>null</code> permitted). 328: * 329: * @see #getAnchor() 330: */ 331: public void setAnchor(Point2D anchor) { 332: this.anchor = anchor; 333: } 334: 335: /** 336: * Returns the x-coordinate (in data space) for the anchor point. 337: * 338: * @return The x-coordinate of the anchor point. 339: * 340: * @since 1.0.3 341: */ 342: public double getAnchorX() { 343: return this.anchorX; 344: } 345: 346: /** 347: * Sets the x-coordinate (in data space) for the anchor point. Note that 348: * this does NOT update the anchor itself - the caller is responsible for 349: * ensuring this is done in sync. 350: * 351: * @param x the x-coordinate. 352: * 353: * @since 1.0.3 354: */ 355: public void setAnchorX(double x) { 356: this.anchorX = x; 357: } 358: 359: /** 360: * Returns the y-coordinate (in data space) for the anchor point. 361: * 362: * @return The y-coordinate of teh anchor point. 363: * 364: * @since 1.0.3 365: */ 366: public double getAnchorY() { 367: return this.anchorY; 368: } 369: 370: /** 371: * Sets the y-coordinate (in data space) for the anchor point. Note that 372: * this does NOT update the anchor itself - the caller is responsible for 373: * ensuring this is done in sync. 374: * 375: * @param y the y-coordinate. 376: * 377: * @since 1.0.3 378: */ 379: public void setAnchorY(double y) { 380: this.anchorY = y; 381: } 382: 383: /** 384: * Get the x-value for the crosshair point. 385: * 386: * @return The x position of the crosshair point. 387: * 388: * @see #setCrosshairX(double) 389: */ 390: public double getCrosshairX() { 391: return this.crosshairX; 392: } 393: 394: /** 395: * Sets the x coordinate for the crosshair. This is the coordinate in data 396: * space measured against the domain axis. 397: * 398: * @param x the coordinate. 399: * 400: * @see #getCrosshairX() 401: * @see #setCrosshairY(double) 402: * @see #updateCrosshairPoint(double, double, double, double, 403: * PlotOrientation) 404: */ 405: public void setCrosshairX(double x) { 406: this.crosshairX = x; 407: } 408: 409: /** 410: * Get the y-value for the crosshair point. This is the coordinate in data 411: * space measured against the range axis. 412: * 413: * @return The y position of the crosshair point. 414: * 415: * @see #setCrosshairY(double) 416: */ 417: public double getCrosshairY() { 418: return this.crosshairY; 419: } 420: 421: /** 422: * Sets the y coordinate for the crosshair. 423: * 424: * @param y the y coordinate. 425: * 426: * @see #getCrosshairY() 427: * @see #setCrosshairX(double) 428: * @see #updateCrosshairPoint(double, double, double, double, 429: * PlotOrientation) 430: */ 431: public void setCrosshairY(double y) { 432: this.crosshairY = y; 433: } 434: 435: /** 436: * Returns the domain axis index for the crosshair x-value. 437: * 438: * @return The domain axis index. 439: * 440: * @since 1.0.4 441: */ 442: public int getDomainAxisIndex() { 443: return this.domainAxisIndex; 444: } 445: 446: /** 447: * Returns the range axis index for the crosshair y-value. 448: * 449: * @return The range axis index. 450: * 451: * @since 1.0.4 452: */ 453: public int getRangeAxisIndex() { 454: return this.rangeAxisIndex; 455: } 456: }