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 * StandardXYZToolTipGenerator.java
029 * --------------------------------
030 * (C) Copyright 2004-present, by David Gilbert.
031 *
032 * Original Author:  David Gilbert;
033 * Contributor(s):   -;
034 *
035 */
036
037package org.jfree.chart.labels;
038
039import java.io.Serializable;
040import java.text.DateFormat;
041import java.text.MessageFormat;
042import java.text.NumberFormat;
043import java.util.Objects;
044import org.jfree.chart.util.Args;
045
046import org.jfree.data.xy.XYDataset;
047import org.jfree.data.xy.XYZDataset;
048
049/**
050 * A standard item label generator for use with {@link XYZDataset} data.  Each
051 * value can be formatted as a number or as a date.
052 */
053public class StandardXYZToolTipGenerator extends StandardXYToolTipGenerator
054        implements XYZToolTipGenerator, Serializable {
055
056    /** For serialization. */
057    private static final long serialVersionUID = -2961577421889473503L;
058
059    /** The default tooltip format. */
060    public static final String DEFAULT_TOOL_TIP_FORMAT = "{0}: ({1}, {2}, {3})";
061
062    /**
063     * A number formatter for the z value - if this is null, then zDateFormat
064     * must be non-null.
065     */
066    private NumberFormat zFormat;
067
068    /**
069     * A date formatter for the z-value - if this is null, then zFormat must be
070     * non-null.
071     */
072    private DateFormat zDateFormat;
073
074    /**
075     * Creates a new tool tip generator using default number formatters for the
076     * x, y and z-values.
077     */
078    public StandardXYZToolTipGenerator() {
079        this(
080            DEFAULT_TOOL_TIP_FORMAT,
081            NumberFormat.getNumberInstance(),
082            NumberFormat.getNumberInstance(),
083            NumberFormat.getNumberInstance()
084        );
085    }
086
087    /**
088     * Constructs a new tool tip generator using the specified number
089     * formatters.
090     *
091     * @param formatString  the format string.
092     * @param xFormat  the format object for the x values ({@code null}
093     *                 not permitted).
094     * @param yFormat  the format object for the y values ({@code null}
095     *                 not permitted).
096     * @param zFormat  the format object for the z values ({@code null}
097     *                 not permitted).
098     */
099    public StandardXYZToolTipGenerator(String formatString, 
100            NumberFormat xFormat, NumberFormat yFormat, NumberFormat zFormat) {
101        super(formatString, xFormat, yFormat);
102        Args.nullNotPermitted(zFormat, "zFormat");
103        this.zFormat = zFormat;
104    }
105
106    /**
107     * Constructs a new tool tip generator using the specified date formatters.
108     *
109     * @param formatString  the format string.
110     * @param xFormat  the format object for the x values ({@code null}
111     *                 not permitted).
112     * @param yFormat  the format object for the y values ({@code null}
113     *                 not permitted).
114     * @param zFormat  the format object for the z values ({@code null}
115     *                 not permitted).
116     */
117    public StandardXYZToolTipGenerator(String formatString, DateFormat xFormat,
118            DateFormat yFormat, DateFormat zFormat) {
119        super(formatString, xFormat, yFormat);
120        Args.nullNotPermitted(zFormat, "zFormat");
121        this.zDateFormat = zFormat;
122    }
123
124    // TODO:  add constructors for combinations of number and date formatters.
125
126    /**
127     * Returns the number formatter for the z-values.
128     *
129     * @return The number formatter (possibly {@code null}).
130     */
131    public NumberFormat getZFormat() {
132        return this.zFormat;
133    }
134
135    /**
136     * Returns the date formatter for the z-values.
137     *
138     * @return The date formatter (possibly {@code null}).
139     */
140    public DateFormat getZDateFormat() {
141        return this.zDateFormat;
142    }
143
144    /**
145     * Generates a tool tip text item for a particular item within a series.
146     *
147     * @param dataset  the dataset ({@code null} not permitted).
148     * @param series  the series index (zero-based).
149     * @param item  the item index (zero-based).
150     *
151     * @return The tooltip text (possibly {@code null}).
152     */
153    @Override
154    public String generateToolTip(XYZDataset dataset, int series, int item) {
155        return generateLabelString(dataset, series, item);
156    }
157
158    /**
159     * Generates a label string for an item in the dataset.
160     *
161     * @param dataset  the dataset ({@code null} not permitted).
162     * @param series  the series (zero-based index).
163     * @param item  the item (zero-based index).
164     *
165     * @return The label (possibly {@code null}).
166     */
167    @Override
168    public String generateLabelString(XYDataset dataset, int series, int item) {
169        String result;
170        Object[] items = createItemArray((XYZDataset) dataset, series, item);
171        result = MessageFormat.format(getFormatString(), items);
172        return result;
173    }
174
175    /**
176     * Creates the array of items that can be passed to the
177     * {@link MessageFormat} class for creating labels.
178     *
179     * @param dataset  the dataset ({@code null} not permitted).
180     * @param series  the series (zero-based index).
181     * @param item  the item (zero-based index).
182     *
183     * @return The items (never {@code null}).
184     */
185    protected Object[] createItemArray(XYZDataset dataset,
186                                       int series, int item) {
187
188        Object[] result = new Object[4];
189        result[0] = dataset.getSeriesKey(series).toString();
190
191        Number x = dataset.getX(series, item);
192        DateFormat xf = getXDateFormat();
193        if (xf != null) {
194            result[1] = xf.format(x);
195        }
196        else {
197            result[1] = getXFormat().format(x);
198        }
199
200        Number y = dataset.getY(series, item);
201        DateFormat yf = getYDateFormat();
202        if (yf != null) {
203            result[2] = yf.format(y);
204        }
205        else {
206            result[2] = getYFormat().format(y);
207        }
208
209        Number z = dataset.getZ(series, item);
210        if (this.zDateFormat != null) {
211            result[3] = this.zDateFormat.format(z);
212        }
213        else {
214            result[3] = this.zFormat.format(z);
215        }
216
217        return result;
218
219    }
220
221    /**
222     * Tests this object for equality with an arbitrary object.
223     *
224     * @param obj  the other object ({@code null} permitted).
225     *
226     * @return A boolean.
227     */
228    @Override
229    public boolean equals(Object obj) {
230        if (obj == this) {
231            return true;
232        }
233        if (!(obj instanceof StandardXYZToolTipGenerator)) {
234            return false;
235        }
236        if (!super.equals(obj)) {
237            return false;
238        }
239        StandardXYZToolTipGenerator that = (StandardXYZToolTipGenerator) obj;
240        if (!Objects.equals(this.zFormat, that.zFormat)) {
241            return false;
242        }
243        if (!Objects.equals(this.zDateFormat, that.zDateFormat)) {
244            return false;
245        }
246        return true;
247
248    }
249
250}