001    /* ===========================================================
002     * JFreeChart : a free chart library for the Java(tm) platform
003     * ===========================================================
004     *
005     * (C) Copyright 2000-2008, 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     * CategoryCrosshairState.java
029     * ---------------------------
030     * (C) Copyright 2008, by Object Refinery Limited and Contributors.
031     *
032     * Original Author:  David Gilbert (for Object Refinery Limited);
033     * Contributor(s):   -;
034     *
035     * Changes
036     * -------
037     * 26-Jun-2008 : Version 1 (DG);
038     *
039     */
040    
041    package org.jfree.chart.plot;
042    
043    import java.awt.geom.Point2D;
044    
045    import org.jfree.chart.renderer.category.CategoryItemRenderer;
046    
047    /**
048     * Represents state information for the crosshairs in a {@link CategoryPlot}.
049     * An instance of this class is created at the start of the rendering process,
050     * and updated as each data item is rendered.  At the end of the rendering
051     * process, this class holds the row key, column key and value for the
052     * crosshair location.
053     *
054     * @since 1.0.11
055     */
056    public class CategoryCrosshairState extends CrosshairState {
057    
058        /**
059         * The row key for the crosshair point.
060         */
061        private Comparable rowKey;
062    
063        /**
064         * The column key for the crosshair point.
065         */
066        private Comparable columnKey;
067    
068        /**
069         * Creates a new instance.
070         */
071        public CategoryCrosshairState() {
072            this.rowKey = null;
073            this.columnKey = null;
074        }
075    
076        /**
077         * Returns the row key.
078         *
079         * @return The row key.
080         */
081        public Comparable getRowKey() {
082            return this.rowKey;
083        }
084    
085        /**
086         * Sets the row key.
087         *
088         * @param key  the row key.
089         */
090        public void setRowKey(Comparable key) {
091            this.rowKey = key;
092        }
093    
094        /**
095         * Returns the column key.
096         *
097         * @return The column key.
098         */
099        public Comparable getColumnKey() {
100            return this.columnKey;
101        }
102    
103        /**
104         * Sets the column key.
105         *
106         * @param key  the key.
107         */
108        public void setColumnKey(Comparable key) {
109            this.columnKey = key;
110        }
111    
112        /**
113         * Evaluates a data point from a {@link CategoryItemRenderer} and if it is
114         * the closest to the anchor point it becomes the new crosshair point.
115         *
116         * @param rowKey  the row key.
117         * @param columnKey  the column key.
118         * @param value  y coordinate (measured against the range axis).
119         * @param datasetIndex  the dataset index for this point.
120         * @param transX  x translated into Java2D space.
121         * @param transY  y translated into Java2D space.
122         * @param orientation  the plot orientation.
123         */
124        public void updateCrosshairPoint(Comparable rowKey, Comparable columnKey,
125                double value, int datasetIndex, double transX, double transY,
126                PlotOrientation orientation) {
127    
128            Point2D anchor = getAnchor();
129            if (anchor != null) {
130                double xx = anchor.getX();
131                double yy = anchor.getY();
132                if (orientation == PlotOrientation.HORIZONTAL) {
133                    double temp = yy;
134                    yy = xx;
135                    xx = temp;
136                }
137                double d = (transX - xx) * (transX - xx)
138                        + (transY - yy) * (transY - yy);
139    
140                if (d < getCrosshairDistance()) {
141                    this.rowKey = rowKey;
142                    this.columnKey = columnKey;
143                    setCrosshairY(value);
144                    setDatasetIndex(datasetIndex);
145                    setCrosshairDistance(d);
146                }
147            }
148    
149        }
150    
151        /**
152         * Updates only the crosshair row and column keys (this is for the case
153         * where the range crosshair does NOT lock onto the nearest data value).
154         *
155         * @param rowKey  the row key.
156         * @param columnKey  the column key.
157         * @param datasetIndex  the dataset axis index.
158         * @param transX  the translated x-value.
159         * @param orientation  the plot orientation.
160         */
161        public void updateCrosshairX(Comparable rowKey, Comparable columnKey,
162                int datasetIndex, double transX, PlotOrientation orientation) {
163    
164            Point2D anchor = getAnchor();
165            if (anchor != null) {
166                double anchorX = anchor.getX();
167                if (orientation == PlotOrientation.HORIZONTAL) {
168                    anchorX = anchor.getY();
169                }
170                double d = Math.abs(transX - anchorX);
171                if (d < getCrosshairDistance()) {
172                    this.rowKey = rowKey;
173                    this.columnKey = columnKey;
174                    setDatasetIndex(datasetIndex);
175                    setCrosshairDistance(d);
176                }
177            }
178    
179        }
180    
181    }