001    /* ===========================================================
002     * JFreeChart : a free chart library for the Java(tm) platform
003     * ===========================================================
004     *
005     * (C) Copyright 2000-2007, 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     * BubbleXYItemLabelGenerator.java
029     * -------------------------------
030     * (C) Copyright 2005-2007, by Object Refinery Limited.
031     *
032     * Original Author:  David Gilbert (for Object Refinery Limited);
033     * Contributor(s):   -;
034     *
035     * Changes
036     * -------
037     * 13-Dec-2005 : Version 1, based on StandardXYZToolTipGenerator (DG);
038     * 26-Jan-2006 : Renamed StandardXYZItemLabelGenerator 
039     *               --> BubbleXYItemLabelGenerator (DG);
040     * 23-Nov-2007 : Implemented hashCode() (DG);
041     *
042     */
043    
044    package org.jfree.chart.labels;
045    
046    import java.io.Serializable;
047    import java.text.DateFormat;
048    import java.text.MessageFormat;
049    import java.text.NumberFormat;
050    
051    import org.jfree.chart.HashUtilities;
052    import org.jfree.chart.renderer.xy.XYBubbleRenderer;
053    import org.jfree.data.xy.XYDataset;
054    import org.jfree.data.xy.XYZDataset;
055    import org.jfree.util.ObjectUtilities;
056    
057    /**
058     * An item label generator defined for use with the {@link XYBubbleRenderer}
059     * class, or any other class that uses an {@link XYZDataset}.
060     * 
061     * @since 1.0.1
062     */
063    public class BubbleXYItemLabelGenerator extends AbstractXYItemLabelGenerator
064            implements XYItemLabelGenerator, Serializable {
065        
066        /** For serialization. */
067        static final long serialVersionUID = -8458568928021240922L;
068    
069        /** The default item label format. */
070        public static final String DEFAULT_FORMAT_STRING = "{3}";
071    
072        /** 
073         * A number formatter for the z value - if this is <code>null</code>, then 
074         * zDateFormat must be non-null. 
075         */
076        private NumberFormat zFormat;
077        
078        /** 
079         * A date formatter for the z-value - if this is null, then zFormat must be 
080         * non-null. 
081         */
082        private DateFormat zDateFormat;
083    
084        /**
085         * Creates a new tool tip generator using default number formatters for the
086         * x, y and z-values.
087         */
088        public BubbleXYItemLabelGenerator() {
089            this(DEFAULT_FORMAT_STRING, NumberFormat.getNumberInstance(),
090                    NumberFormat.getNumberInstance(), 
091                    NumberFormat.getNumberInstance());
092        }
093    
094        /**
095         * Constructs a new tool tip generator using the specified number 
096         * formatters.
097         *
098         * @param formatString  the format string.
099         * @param xFormat  the format object for the x values (<code>null</code> 
100         *                 not permitted).
101         * @param yFormat  the format object for the y values (<code>null</code> 
102         *                 not permitted).
103         * @param zFormat  the format object for the z values (<code>null</code> 
104         *                 not permitted).
105         */
106        public BubbleXYItemLabelGenerator(String formatString, 
107                NumberFormat xFormat, NumberFormat yFormat, NumberFormat zFormat) {
108            super(formatString, xFormat, yFormat);
109            if (zFormat == null) {
110                throw new IllegalArgumentException("Null 'zFormat' argument.");   
111            }
112            this.zFormat = zFormat;
113        }
114    
115        /**
116         * Constructs a new item label generator using the specified date 
117         * formatters.
118         *
119         * @param formatString  the format string.
120         * @param xFormat  the format object for the x values (<code>null</code> 
121         *                 not permitted).
122         * @param yFormat  the format object for the y values (<code>null</code> 
123         *                 not permitted).
124         * @param zFormat  the format object for the z values (<code>null</code> 
125         *                 not permitted).
126         */
127        public BubbleXYItemLabelGenerator(String formatString, 
128                DateFormat xFormat, DateFormat yFormat, DateFormat zFormat) {
129            super(formatString, xFormat, yFormat);
130            if (zFormat == null) {
131                throw new IllegalArgumentException("Null 'zFormat' argument.");   
132            }
133            this.zDateFormat = zFormat;
134        }
135        
136        /**
137         * Returns the number formatter for the z-values.
138         *
139         * @return The number formatter (possibly <code>null</code>).
140         */
141        public NumberFormat getZFormat() {
142            return this.zFormat;
143        }
144        
145        /**
146         * Returns the date formatter for the z-values.
147         *
148         * @return The date formatter (possibly <code>null</code>).
149         */
150        public DateFormat getZDateFormat() {
151            return this.zDateFormat;   
152        }
153    
154        /**
155         * Generates an item label for a particular item within a series.
156         *
157         * @param dataset  the dataset (<code>null</code> not permitted).
158         * @param series  the series index (zero-based).
159         * @param item  the item index (zero-based).
160         *
161         * @return The item label (possibly <code>null</code>).
162         */
163        public String generateLabel(XYDataset dataset, int series, int item) {
164            return generateLabelString(dataset, series, item);
165        }
166        
167        /**
168         * Generates a label string for an item in the dataset.
169         *
170         * @param dataset  the dataset (<code>null</code> not permitted).
171         * @param series  the series (zero-based index).
172         * @param item  the item (zero-based index).
173         *
174         * @return The label (possibly <code>null</code>).
175         */
176        public String generateLabelString(XYDataset dataset, int series, int item) {
177            String result = null;    
178            Object[] items = null;
179            if (dataset instanceof XYZDataset) {
180                items = createItemArray((XYZDataset) dataset, series, item);
181            }
182            else {
183                items = createItemArray(dataset, series, item);
184            }
185            result = MessageFormat.format(getFormatString(), items);
186            return result;
187        }
188    
189        /**
190         * Creates the array of items that can be passed to the 
191         * {@link MessageFormat} class for creating labels.
192         *
193         * @param dataset  the dataset (<code>null</code> not permitted).
194         * @param series  the series (zero-based index).
195         * @param item  the item (zero-based index).
196         *
197         * @return The items (never <code>null</code>).
198         */
199        protected Object[] createItemArray(XYZDataset dataset, 
200                                           int series, int item) {
201    
202            Object[] result = new Object[4];
203            result[0] = dataset.getSeriesKey(series).toString();
204     
205            Number x = dataset.getX(series, item);
206            DateFormat xf = getXDateFormat();
207            if (xf != null) {
208                result[1] = xf.format(x);   
209            }
210            else {
211                result[1] = getXFormat().format(x);
212            }
213            
214            Number y = dataset.getY(series, item);
215            DateFormat yf = getYDateFormat();
216            if (yf != null) {
217                result[2] = yf.format(y);
218            }
219            else {
220                result[2] = getYFormat().format(y);
221            }
222            
223            Number z = dataset.getZ(series, item);
224            if (this.zDateFormat != null) {
225                result[3] = this.zDateFormat.format(z);   
226            }
227            else {
228                result[3] = this.zFormat.format(z);   
229            }
230            
231            return result;
232            
233        }
234    
235        /**
236         * Tests this object for equality with an arbitrary object.
237         *
238         * @param obj  the other object (<code>null</code> permitted).
239         *
240         * @return A boolean.
241         */
242        public boolean equals(Object obj) {
243            if (obj == this) {
244                return true;
245            }
246            if (!(obj instanceof BubbleXYItemLabelGenerator)) {
247                return false;
248            }
249            if (!super.equals(obj)) {
250                return false;
251            }
252            BubbleXYItemLabelGenerator that = (BubbleXYItemLabelGenerator) obj;
253            if (!ObjectUtilities.equal(this.zFormat, that.zFormat)) {
254                return false;
255            }
256            if (!ObjectUtilities.equal(this.zDateFormat, that.zDateFormat)) {
257                return false;
258            }
259            return true;
260        }
261        
262        /**
263         * Returns a hash code for this instance.
264         * 
265         * @return A hash code.
266         */
267        public int hashCode() {
268            int h = super.hashCode();
269            h = HashUtilities.hashCode(h, this.zFormat);
270            h = HashUtilities.hashCode(h, this.zDateFormat);
271            return h;
272        }
273    
274    }