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