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