    001    /* ===========================================================
    002     * JFreeChart : a free chart library for the Java(tm) platform
    003     * ===========================================================
    004     *
    005     * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
    006     *
    007     * Project Info:  http://www.jfree.org/jfreechart/index.html
    008     *
    009     * This library is free software; you can redistribute it and/or modify it
    010     * under the terms of the GNU Lesser General Public License as published by
    011     * the Free Software Foundation; either version 2.1 of the License, or
    012     * (at your option) any later version.
    013     *
    014     * This library is distributed in the hope that it will be useful, but
    015     * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
    016     * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
    017     * License for more details.
    018     *
    019     * You should have received a copy of the GNU Lesser General Public
    020     * License along with this library; if not, write to the Free Software
    021     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
    022     * USA.
    023     *
    024     * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
    025     * in the United States and other countries.]
    026     *
    027     * -------------------
    028     * CrosshairState.java
    029     * -------------------
    030     * (C) Copyright 2002-2004, by Object Refinery Limited.
    031     *
    032     * Original Author:  David Gilbert (for Object Refinery Limited);
    033     * Contributor(s):   -;
    034     *
    035     * $Id: CrosshairState.java,v 1.3.2.1 2005/10/25 20:52:07 mungady Exp $
    036     *
    037     * Changes
    038     * -------
    039     * 24-Jan-2002 : Version 1 (DG);
    040     * 05-Mar-2002 : Added Javadoc comments (DG);
    041     * 26-Sep-2002 : Fixed errors reported by Checkstyle (DG);
    042     * 19-Sep-2003 : Modified crosshair distance calculation (DG);
    043     * 04-Dec-2003 : Crosshair anchor point now stored outside chart since it is
    044     *               dependent on the display target (DG);
    045     * 25-Feb-2004 : Replaced CrosshairInfo --> CrosshairState (DG);
    046     *
    047     */
    048
    049    package org.jfree.chart.plot;
    050
    051    import java.awt.geom.Point2D;
    052
    053    /**
    054     * Maintains state information about crosshairs on a plot.
    055     *
    056     */
    057    public class CrosshairState {
    058
    059        /**
    060         * A flag that controls whether the distance is calculated in data space
    061         * or Java2D space.
    062         */
    063        private boolean calculateDistanceInDataSpace = false;
    064
    065        /** The x-value (in data space) for the anchor point. */
    066        private double anchorX;
    067
    068        /** The y-value (in data space) for the anchor point. */
    069        private double anchorY;
    070
    071        /** The anchor point in Java2D space - if null, don't update crosshair. */
    072        private Point2D anchor;
    073
    074        /** The x-value for the crosshair point. */
    075        private double crosshairX;
    076
    077        /** The y-value for the crosshair point. */
    078        private double crosshairY;
    079
    080        /**
    081         * The smallest distance so far between the anchor point and a data point.
    082         */
    083        private double distance;
    084
    085        /**
    086         * Default constructor.
    087         */
    088        public CrosshairState() {
    089            this(false);
    090        }
    091
    092        /**
    093         * Creates a new info object.
    094         *
    095         * @param calculateDistanceInDataSpace  a flag that controls whether the
    096         *                                      distance is calculated in data
    097         *                                      space or Java2D space.
    098         */
    099        public CrosshairState(boolean calculateDistanceInDataSpace) {
    100            this.calculateDistanceInDataSpace = calculateDistanceInDataSpace;
    101        }
    102
    103        /**
    104         * Sets the distance between the anchor point and the current crosshair
    105         * point.  As each data point is processed, its distance to the anchor
    106         * point is compared with this value and, if it is closer, the data point
    107         * becomes the new crosshair point.
    108         *
    109         * @param distance  the distance.
    110         */
    111        public void setCrosshairDistance(double distance) {
    112            this.distance = distance;
    113        }
    114
    115        /**
    116         * Evaluates a data point and if it is the closest to the anchor point it
    117         * becomes the new crosshair point.
    118         * <P>
    119         * To understand this method, you need to know the context in which it will
    120         * be called.  An instance of this class is passed to an
    121         * {@link org.jfree.chart.renderer.xy.XYItemRenderer} as
    122         * each data point is plotted.  As the point is plotted, it is passed to
    123         * this method to see if it should be the new crosshair point.
    124         *
    125         * @param x  x coordinate (measured against the domain axis).
    126         * @param y  y coordinate (measured against the range axis).
    127         * @param transX  x translated into Java2D space.
    128         * @param transY  y translated into Java2D space.
    129         * @param orientation  the plot orientation.
    130         */
    131        public void updateCrosshairPoint(double x, double y,
    132                                         double transX, double transY,
    133                                         PlotOrientation orientation) {
    134
    135            if (this.anchor != null) {
    136                double d = 0.0;
    137                if (this.calculateDistanceInDataSpace) {
    138                    d = (x - this.anchorX) * (x - this.anchorX)
    139                      + (y - this.anchorY) * (y - this.anchorY);
    140                }
    141                else {
    142                    double xx = this.anchor.getX();
    143                    double yy = this.anchor.getY();
    144                    if (orientation == PlotOrientation.HORIZONTAL) {
    145                        double temp = yy;
    146                        yy = xx;
    147                        xx = temp;
    148                    }
    149                    d = (transX - xx) * (transX - xx)
    150                        + (transY - yy) * (transY - yy);
    151                }
    152
    153                if (d < this.distance) {
    154                    this.crosshairX = x;
    155                    this.crosshairY = y;
    156                    this.distance = d;
    157                }
    158            }
    159
    160        }
    161
    162        /**
    163         * Evaluates an x-value and if it is the closest to the anchor point it
    164         * becomes the new crosshair point.
    165         * <P>
    166         * Used in cases where only the x-axis is numerical.
    167         *
    168         * @param candidateX  x position of the candidate for the new crosshair
    169         *                    point.
    170         */
    171        public void updateCrosshairX(double candidateX) {
    172
    173            double d = Math.abs(candidateX - this.anchorX);
    174            if (d < this.distance) {
    175                this.crosshairX = candidateX;
    176                this.distance = d;
    177            }
    178
    179        }
    180
    181        /**
    182         * Evaluates a y-value and if it is the closest to the anchor point it
    183         * becomes the new crosshair point.
    184         * <P>
    185         * Used in cases where only the y-axis is numerical.
    186         *
    187         * @param candidateY  y position of the candidate for the new crosshair
    188         *                    point.
    189         */
    190        public void updateCrosshairY(double candidateY) {
    191
    192            double d = Math.abs(candidateY - this.anchorY);
    193            if (d < this.distance) {
    194                this.crosshairY = candidateY;
    195                this.distance = d;
    196            }
    197
    198        }
    199
    200        /**
    201         * Sets the anchor point.  This is usually the mouse click point in a chart
    202         * panel, and the crosshair point will often be the data item that is
    203         * closest to the anchor point.
    204         *
    205         * @param anchor  the anchor point.
    206         */
    207        public void setAnchor(Point2D anchor) {
    208            this.anchor = anchor;
    209        }
    210
    211        /**
    212         * Get the x-value for the crosshair point.
    213         *
    214         * @return The x position of the crosshair point.
    215         */
    216        public double getCrosshairX() {
    217            return this.crosshairX;
    218        }
    219
    220        /**
    221         * Sets the x coordinate for the crosshair.  This is the coordinate in data
    222         * space measured against the domain axis.
    223         *
    224         * @param x the coordinate.
    225         */
    226        public void setCrosshairX(double x) {
    227            this.crosshairX = x;
    228        }
    229
    230        /**
    231         * Get the y-value for the crosshair point.  This is the coordinate in data
    232         * space measured against the range axis.
    233         *
    234         * @return The y position of the crosshair point.
    235         */
    236        public double getCrosshairY() {
    237            return this.crosshairY;
    238        }
    239
    240        /**
    241         * Sets the y coordinate for the crosshair.
    242         *
    243         * @param y  the y coordinate.
    244         */
    245        public void setCrosshairY(double y) {
    246            this.crosshairY = y;
    247        }
    248
    249    }