001/* ===========================================================
002 * JFreeChart : a free chart library for the Java(tm) platform
003 * ===========================================================
004 *
005 * (C) Copyright 2000-present, by David Gilbert 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 * ItemLabelPosition.java
029 * ----------------------
030 * (C) Copyright 2003-present, by David Gilbert and Contributors.
031 *
032 * Original Author:  David Gilbert;
033 * Contributor(s):   Yuri Blankenstein;
034 *                   Tracy Hiltbrand (equals/hashCode comply with EqualsVerifier);
035 *
036 */
037
038package org.jfree.chart.labels;
039
040import java.io.Serializable;
041import java.util.Objects;
042import org.jfree.chart.ui.TextAnchor;
043import org.jfree.chart.util.Args;
044
045/**
046 * The attributes that control the position of the label for each data item on
047 * a chart.  Instances of this class are immutable.
048 */
049public class ItemLabelPosition implements Serializable {
050
051    /** For serialization. */
052    private static final long serialVersionUID = 5845390630157034499L;
053
054    /** The item label anchor point. */
055    private ItemLabelAnchor itemLabelAnchor;
056
057    /** The text anchor. */
058    private TextAnchor textAnchor;
059
060    /** The rotation anchor. */
061    private TextAnchor rotationAnchor;
062
063    /** The rotation angle. */
064    private double angle;
065    
066    /** The item label clip type. */
067    private ItemLabelClip itemLabelClip;
068
069    /**
070     * Creates a new position record with default settings.
071     */
072    public ItemLabelPosition() {
073        this(ItemLabelAnchor.OUTSIDE12, TextAnchor.BOTTOM_CENTER,
074                TextAnchor.CENTER, 0.0);
075    }
076
077    /**
078     * Creates a new position record (with zero rotation).
079     *
080     * @param itemLabelAnchor  the item label anchor ({@code null} not
081     *                         permitted).
082     * @param textAnchor  the text anchor ({@code null} not permitted).
083     */
084    public ItemLabelPosition(ItemLabelAnchor itemLabelAnchor,
085                             TextAnchor textAnchor) {
086        this(itemLabelAnchor, textAnchor, TextAnchor.CENTER, 0.0);
087    }
088
089    /**
090     * Creates a new position record. The item label anchor is a point relative
091     * to the data item (dot, bar or other visual item) on a chart. The item
092     * label is aligned by aligning the text anchor with the item label anchor.
093     *
094     * @param itemLabelAnchor the item label anchor ({@code null} not
095     *                        permitted).
096     * @param textAnchor      the text anchor ({@code null} not permitted).
097     * @param itemLabelClip   The clip type for the label ({@code null} not
098     *                        permitted. Only used when
099     *                        {@link ItemLabelAnchor#isInternal()} returns
100     *                        {@code true}, if {@code false} {@code labelClip}
101     *                        is always considered to be
102     *                        {@link ItemLabelClip#NONE})
103     */
104    public ItemLabelPosition(ItemLabelAnchor itemLabelAnchor,
105            TextAnchor textAnchor, ItemLabelClip itemLabelClip) {
106        this(itemLabelAnchor, textAnchor, TextAnchor.CENTER, 0.0,
107                itemLabelClip);
108    }
109    
110    /**
111     * Creates a new position record.  The item label anchor is a point
112     * relative to the data item (dot, bar or other visual item) on a chart.
113     * The item label is aligned by aligning the text anchor with the
114     * item label anchor.
115     *
116     * @param itemLabelAnchor  the item label anchor ({@code null} not
117     *                         permitted).
118     * @param textAnchor  the text anchor ({@code null} not permitted).
119     * @param rotationAnchor  the rotation anchor ({@code null} not
120     *                        permitted).
121     * @param angle  the rotation angle (in radians).
122     */
123    public ItemLabelPosition(ItemLabelAnchor itemLabelAnchor,
124            TextAnchor textAnchor, TextAnchor rotationAnchor, double angle) {
125        this(itemLabelAnchor, textAnchor, rotationAnchor, angle,
126                ItemLabelClip.FIT);
127
128    }
129
130    /**
131     * Creates a new position record. The item label anchor is a point relative
132     * to the data item (dot, bar or other visual item) on a chart. The item
133     * label is aligned by aligning the text anchor with the item label anchor.
134     *
135     * @param itemLabelAnchor the item label anchor ({@code null} not
136     *                        permitted).
137     * @param textAnchor      the text anchor ({@code null} not permitted).
138     * @param rotationAnchor  the rotation anchor ({@code null} not permitted).
139     * @param angle           the rotation angle (in radians).
140     * @param itemLabelClip   The clip type for the label ({@code null} not
141     *                        permitted. Only used when
142     *                        {@link ItemLabelAnchor#isInternal()} returns
143     *                        {@code true}, if {@code false} {@code labelClip}
144     *                        is always considered to be
145     *                        {@link ItemLabelClip#NONE})
146     */
147    public ItemLabelPosition(ItemLabelAnchor itemLabelAnchor,
148            TextAnchor textAnchor, TextAnchor rotationAnchor, double angle,
149            ItemLabelClip itemLabelClip) {
150
151        Args.nullNotPermitted(itemLabelAnchor, "itemLabelAnchor");
152        Args.nullNotPermitted(textAnchor, "textAnchor");
153        Args.nullNotPermitted(rotationAnchor, "rotationAnchor");
154        Args.nullNotPermitted(itemLabelClip, "labelClip");
155        this.itemLabelAnchor = itemLabelAnchor;
156        this.textAnchor = textAnchor;
157        this.rotationAnchor = rotationAnchor;
158        this.angle = angle;
159        this.itemLabelClip = itemLabelClip;
160    }
161
162    /**
163     * Returns the item label anchor.
164     *
165     * @return The item label anchor (never {@code null}).
166     */
167    public ItemLabelAnchor getItemLabelAnchor() {
168        return this.itemLabelAnchor;
169    }
170
171    /**
172     * Returns the text anchor.
173     *
174     * @return The text anchor (never {@code null}).
175     */
176    public TextAnchor getTextAnchor() {
177        return this.textAnchor;
178    }
179
180    /**
181     * Returns the rotation anchor point.
182     *
183     * @return The rotation anchor point (never {@code null}).
184     */
185    public TextAnchor getRotationAnchor() {
186        return this.rotationAnchor;
187    }
188
189    /**
190     * Returns the angle of rotation for the label.
191     *
192     * @return The angle (in radians).
193     */
194    public double getAngle() {
195        return this.angle;
196    }
197    
198    /**
199     * Returns the clip type for the label.
200     * 
201     * @return The clip type for the label.
202     */
203    public ItemLabelClip getItemLabelClip() {
204                return this.itemLabelClip;
205        }
206
207    /**
208     * Tests this object for equality with an arbitrary object.
209     *
210     * @param obj  the object ({@code null} permitted).
211     *
212     * @return A boolean.
213     */
214    @Override
215    public boolean equals(Object obj) {
216        if (obj == this) {
217            return true;
218        }
219        if (!(obj instanceof ItemLabelPosition)) {
220            return false;
221        }
222        ItemLabelPosition that = (ItemLabelPosition) obj;
223        if (!Objects.equals(this.itemLabelAnchor, that.itemLabelAnchor)) {
224            return false;
225        }
226        if (!Objects.equals(this.textAnchor, that.textAnchor)) {
227            return false;
228        }
229        if (!Objects.equals(this.rotationAnchor, that.rotationAnchor)) {
230            return false;
231        }
232        if (Double.doubleToLongBits(this.angle) != Double.doubleToLongBits(that.angle)) {
233            return false;
234        }
235        if (!Objects.equals(this.itemLabelClip, that.itemLabelClip)) {
236            return false;
237        }
238        return true;
239    }
240
241    @Override
242    public int hashCode() {
243        int hash = 5;
244        hash = 97 * hash + Objects.hashCode(this.itemLabelAnchor);
245        hash = 97 * hash + Objects.hashCode(this.textAnchor);
246        hash = 97 * hash + Objects.hashCode(this.rotationAnchor);
247        hash = 97 * hash + (int) (Double.doubleToLongBits(this.angle) ^ (Double.doubleToLongBits(this.angle) >>> 32));
248        hash = 97 * hash + Objects.hashCode(this.itemLabelClip);
249                return hash;
250    }
251}