    001    /* ===========================================================
    002     * JFreeChart : a free chart library for the Java(tm) platform
    003     * ===========================================================
    004     *
    005     * (C) Copyright 2000-2005, 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     * AbstractPieItemLabelGenerator.java
    029     * ----------------------------------
    030     * (C) Copyright 2004, 2005, by Object Refinery Limited.
    031     *
    032     * Original Author:  David Gilbert (for Object Refinery Limited);
    033     * Contributor(s):   -;
    034     *
    035     * $Id: AbstractPieItemLabelGenerator.java,v 1.5.2.1 2005/10/25 20:49:02 mungady Exp $
    036     *
    037     * Changes
    038     * -------
    039     * 09-Nov-2004 : Version 1, draws out code from StandardPieItemLabelGenerator
    040     *               and StandardPieToolTipGenerator (DG);
    041     *
    042     */
    043
    044    package org.jfree.chart.labels;
    045
    046    import java.io.Serializable;
    047    import java.text.MessageFormat;
    048    import java.text.NumberFormat;
    049
    050    import org.jfree.data.general.DatasetUtilities;
    051    import org.jfree.data.general.PieDataset;
    052
    053    /**
    054     * A base class used for generating pie chart item labels.
    055     */
    056    public class AbstractPieItemLabelGenerator implements Serializable {
    057
    058        /** For serialization. */
    059        private static final long serialVersionUID = 7347703325267846275L;
    060
    061        /** The label format string. */
    062        private String labelFormat;
    063
    064        /** A number formatter for the value. */
    065        private NumberFormat numberFormat;
    066
    067        /** A number formatter for the percentage. */
    068        private NumberFormat percentFormat;
    069
    070        /**
    071         * Creates an item label generator using the specified number formatters.
    072         *
    073         * @param labelFormat  the label format string (<code>null</code> not
    074         *                     permitted).
    075         * @param numberFormat  the format object for the values (<code>null</code>
    076         *                      not permitted).
    077         * @param percentFormat  the format object for the percentages
    078         *                       (<code>null</code> not permitted).
    079         */
    080        protected AbstractPieItemLabelGenerator(String labelFormat,
    081                                                NumberFormat numberFormat,
    082                                                NumberFormat percentFormat) {
    083
    084            if (labelFormat == null) {
    085                throw new IllegalArgumentException("Null 'labelFormat' argument.");
    086            }
    087            if (numberFormat == null) {
    088                throw new IllegalArgumentException("Null 'numberFormat' argument.");
    089            }
    090            if (percentFormat == null) {
    091                throw new IllegalArgumentException(
    092                    "Null 'percentFormat' argument."
    093                );
    094            }
    095            this.labelFormat = labelFormat;
    096            this.numberFormat = numberFormat;
    097            this.percentFormat = percentFormat;
    098
    099        }
    100
    101        /**
    102         * Returns the label format string.
    103         *
    104         * @return The label format string (never <code>null</code>).
    105         */
    106        public String getLabelFormat() {
    107            return this.labelFormat;
    108        }
    109
    110        /**
    111         * Returns the number formatter.
    112         *
    113         * @return The formatter (never <code>null</code>).
    114         */
    115        public NumberFormat getNumberFormat() {
    116            return this.numberFormat;
    117        }
    118
    119        /**
    120         * Returns the percent formatter.
    121         *
    122         * @return The formatter (never <code>null</code>).
    123         */
    124        public NumberFormat getPercentFormat() {
    125            return this.percentFormat;
    126        }
    127
    128        /**
    129         * Creates the array of items that can be passed to the
    130         * {@link MessageFormat} class for creating labels.  The returned array
    131         * contains four values:
    132         * <ul>
    133         * <li>result[0] = the section key converted to a <code>String</code>;</li>
    134         * <li>result[1] = the formatted data value;</li>
    135         * <li>result[2] = the formatted percentage (of the total);</li>
    136         * <li>result[3] = the formatted total value.</li>
    137         * </ul>
    138         *
    139         * @param dataset  the dataset (<code>null</code> not permitted).
    140         * @param key  the key (<code>null</code> not permitted).
    141         *
    142         * @return The items (never <code>null</code>).
    143         */
    144        protected Object[] createItemArray(PieDataset dataset, Comparable key) {
    145            Object[] result = new Object[4];
    146            double total = DatasetUtilities.calculatePieDatasetTotal(dataset);
    147            result[0] = key.toString();
    148            Number value = dataset.getValue(key);
    149            if (value != null) {
    150                result[1] = this.numberFormat.format(value);
    151            }
    152            else {
    153                result[1] = "null";
    154            }
    155            double percent = 0.0;
    156            if (value != null) {
    157                double v = value.doubleValue();
    158                if (v > 0.0) {
    159                    percent = v / total;
    160                }
    161            }
    162            result[2] = this.percentFormat.format(percent);
    163            result[3] = this.numberFormat.format(total);
    164            return result;
    165        }
    166
    167        /**
    168         * Generates a label for a pie section.
    169         *
    170         * @param dataset  the dataset (<code>null</code> not permitted).
    171         * @param key  the section key (<code>null</code> not permitted).
    172         *
    173         * @return The label (possibly <code>null</code>).
    174         */
    175        protected String generateSectionLabel(PieDataset dataset, Comparable key) {
    176            String result = null;
    177            if (dataset != null) {
    178                Object[] items = createItemArray(dataset, key);
    179                result = MessageFormat.format(this.labelFormat, items);
    180            }
    181            return result;
    182        }
    183
    184        /**
    185         * Tests the generator for equality with an arbitrary object.
    186         *
    187         * @param obj  the object to test against (<code>null</code> permitted).
    188         *
    189         * @return A boolean.
    190         */
    191        public boolean equals(Object obj) {
    192            if (obj == this) {
    193                return true;
    194            }
    195            if (!(obj instanceof AbstractPieItemLabelGenerator)) {
    196                return false;
    197            }
    198
    199            AbstractPieItemLabelGenerator that
    200                = (AbstractPieItemLabelGenerator) obj;
    201            if (!this.labelFormat.equals(that.labelFormat)) {
    202                return false;
    203            }
    204            if (!this.numberFormat.equals(that.numberFormat)) {
    205                return false;
    206            }
    207            if (!this.percentFormat.equals(that.percentFormat)) {
    208                return false;
    209            }
    210            return true;
    211
    212        }
    213
    214        /**
    215         * Returns an independent copy of the generator.
    216         *
    217         * @return A clone.
    218         *
    219         * @throws CloneNotSupportedException  should not happen.
    220         */
    221        public Object clone() throws CloneNotSupportedException {
    222            AbstractPieItemLabelGenerator clone
    223                = (AbstractPieItemLabelGenerator) super.clone();
    224            if (this.numberFormat != null) {
    225                clone.numberFormat = (NumberFormat) this.numberFormat.clone();
    226            }
    227            return clone;
    228        }
    229
    230    }