    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     * DefaultStatisticalCategoryDataset.java
    029     * --------------------------------------
    030     * (C) Copyright 2002-2007, by Pascal Collet and Contributors.
    031     *
    032     * Original Author:  Pascal Collet;
    033     * Contributor(s):   David Gilbert (for Object Refinery Limited);
    034     *
    035     * $Id: DefaultStatisticalCategoryDataset.java,v 1.8.2.4 2007/02/02 15:50:24 mungady Exp $
    036     *
    037     * Changes
    038     * -------
    039     * 21-Aug-2002 : Version 1, contributed by Pascal Collet (DG);
    040     * 07-Oct-2002 : Fixed errors reported by Checkstyle (DG);
    041     * 05-Feb-2003 : Revised implementation to use KeyedObjects2D (DG);
    042     * 28-Aug-2003 : Moved from org.jfree.data --> org.jfree.data.statistics (DG);
    043     * 06-Oct-2003 : Removed incorrect Javadoc text (DG);
    044     * 18-Nov-2004 : Updated for changes in RangeInfo interface (DG);
    045     * 11-Jan-2005 : Removed deprecated code in preparation for the 1.0.0
    046     *               release (DG);
    047     * 01-Feb-2005 : Changed minimumRangeValue and maximumRangeValue from Double
    048     *               to double (DG);
    049     * 05-Feb-2005 : Implemented equals() method (DG);
    050     * ------------- JFREECHART 1.0.x ---------------------------------------------
    051     * 08-Aug-2006 : Reworked implementation of RangeInfo methods (DG);
    052     * 02-Feb-2007 : Removed author tags from all over JFreeChart sources (DG);
    053     *
    054     */
    055
    056    package org.jfree.data.statistics;
    057
    058    import java.util.List;
    059
    060    import org.jfree.data.KeyedObjects2D;
    061    import org.jfree.data.Range;
    062    import org.jfree.data.RangeInfo;
    063    import org.jfree.data.general.AbstractDataset;
    064
    065    /**
    066     * A convenience class that provides a default implementation of the
    067     * {@link StatisticalCategoryDataset} interface.
    068     */
    069    public class DefaultStatisticalCategoryDataset extends AbstractDataset
    070        implements StatisticalCategoryDataset, RangeInfo {
    071
    072        /** Storage for the data. */
    073        private KeyedObjects2D data;
    074
    075        /** The minimum range value. */
    076        private double minimumRangeValue;
    077
    078        /** The minimum range value including the standard deviation. */
    079        private double minimumRangeValueIncStdDev;
    080
    081        /** The maximum range value. */
    082        private double maximumRangeValue;
    083
    084        /** The maximum range value including the standard deviation. */
    085        private double maximumRangeValueIncStdDev;
    086
    087        /**
    088         * Creates a new dataset.
    089         */
    090        public DefaultStatisticalCategoryDataset() {
    091            this.data = new KeyedObjects2D();
    092            this.minimumRangeValue = Double.NaN;
    093            this.maximumRangeValue = Double.NaN;
    094            this.minimumRangeValueIncStdDev = Double.NaN;
    095            this.maximumRangeValueIncStdDev = Double.NaN;
    096        }
    097
    098        /**
    099         * Returns the mean value for an item.
    100         *
    101         * @param row  the row index (zero-based).
    102         * @param column  the column index (zero-based).
    103         *
    104         * @return The mean value.
    105         */
    106        public Number getMeanValue(int row, int column) {
    107            Number result = null;
    108            MeanAndStandardDeviation masd
    109                = (MeanAndStandardDeviation) this.data.getObject(row, column);
    110            if (masd != null) {
    111                result = masd.getMean();
    112            }
    113            return result;
    114        }
    115
    116        /**
    117         * Returns the value for an item (for this dataset, the mean value is
    118         * returned).
    119         *
    120         * @param row  the row index.
    121         * @param column  the column index.
    122         *
    123         * @return The value.
    124         */
    125        public Number getValue(int row, int column) {
    126            return getMeanValue(row, column);
    127        }
    128
    129        /**
    130         * Returns the value for an item (for this dataset, the mean value is
    131         * returned).
    132         *
    133         * @param rowKey  the row key.
    134         * @param columnKey  the columnKey.
    135         *
    136         * @return The value.
    137         */
    138        public Number getValue(Comparable rowKey, Comparable columnKey) {
    139            return getMeanValue(rowKey, columnKey);
    140        }
    141
    142        /**
    143         * Returns the mean value for an item.
    144         *
    145         * @param rowKey  the row key.
    146         * @param columnKey  the columnKey.
    147         *
    148         * @return The mean value.
    149         */
    150        public Number getMeanValue(Comparable rowKey, Comparable columnKey) {
    151            Number result = null;
    152            MeanAndStandardDeviation masd
    153                = (MeanAndStandardDeviation) this.data.getObject(rowKey, columnKey);
    154            if (masd != null) {
    155                result = masd.getMean();
    156            }
    157            return result;
    158        }
    159
    160        /**
    161         * Returns the standard deviation value for an item.
    162         *
    163         * @param row  the row index (zero-based).
    164         * @param column  the column index (zero-based).
    165         *
    166         * @return The standard deviation.
    167         */
    168        public Number getStdDevValue(int row, int column) {
    169            Number result = null;
    170            MeanAndStandardDeviation masd
    171                = (MeanAndStandardDeviation) this.data.getObject(row, column);
    172            if (masd != null) {
    173                result = masd.getStandardDeviation();
    174            }
    175            return result;
    176        }
    177
    178        /**
    179         * Returns the standard deviation value for an item.
    180         *
    181         * @param rowKey  the row key.
    182         * @param columnKey  the columnKey.
    183         *
    184         * @return The standard deviation.
    185         */
    186        public Number getStdDevValue(Comparable rowKey, Comparable columnKey) {
    187            Number result = null;
    188            MeanAndStandardDeviation masd
    189                = (MeanAndStandardDeviation) this.data.getObject(rowKey, columnKey);
    190            if (masd != null) {
    191                result = masd.getStandardDeviation();
    192            }
    193            return result;
    194        }
    195
    196        /**
    197         * Returns the column index for a given key.
    198         *
    199         * @param key  the column key.
    200         *
    201         * @return The column index.
    202         */
    203        public int getColumnIndex(Comparable key) {
    204            return this.data.getColumnIndex(key);
    205        }
    206
    207        /**
    208         * Returns a column key.
    209         *
    210         * @param column  the column index (zero-based).
    211         *
    212         * @return The column key.
    213         */
    214        public Comparable getColumnKey(int column) {
    215            return this.data.getColumnKey(column);
    216        }
    217
    218        /**
    219         * Returns the column keys.
    220         *
    221         * @return The keys.
    222         */
    223        public List getColumnKeys() {
    224            return this.data.getColumnKeys();
    225        }
    226
    227        /**
    228         * Returns the row index for a given key.
    229         *
    230         * @param key  the row key.
    231         *
    232         * @return The row index.
    233         */
    234        public int getRowIndex(Comparable key) {
    235            return this.data.getRowIndex(key);
    236        }
    237
    238        /**
    239         * Returns a row key.
    240         *
    241         * @param row  the row index (zero-based).
    242         *
    243         * @return The row key.
    244         */
    245        public Comparable getRowKey(int row) {
    246            return this.data.getRowKey(row);
    247        }
    248
    249        /**
    250         * Returns the row keys.
    251         *
    252         * @return The keys.
    253         */
    254        public List getRowKeys() {
    255            return this.data.getRowKeys();
    256        }
    257
    258        /**
    259         * Returns the number of rows in the table.
    260         *
    261         * @return The row count.
    262         */
    263        public int getRowCount() {
    264            return this.data.getRowCount();
    265        }
    266
    267        /**
    268         * Returns the number of columns in the table.
    269         *
    270         * @return The column count.
    271         */
    272        public int getColumnCount() {
    273            return this.data.getColumnCount();
    274        }
    275
    276        /**
    277         * Adds a mean and standard deviation to the table.
    278         *
    279         * @param mean  the mean.
    280         * @param standardDeviation  the standard deviation.
    281         * @param rowKey  the row key.
    282         * @param columnKey  the column key.
    283         */
    284        public void add(double mean, double standardDeviation,
    285                        Comparable rowKey, Comparable columnKey) {
    286            add(new Double(mean), new Double(standardDeviation), rowKey, columnKey);
    287        }
    288
    289        /**
    290         * Adds a mean and standard deviation to the table.
    291         *
    292         * @param mean  the mean.
    293         * @param standardDeviation  the standard deviation.
    294         * @param rowKey  the row key.
    295         * @param columnKey  the column key.
    296         */
    297        public void add(Number mean, Number standardDeviation,
    298                        Comparable rowKey, Comparable columnKey) {
    299            MeanAndStandardDeviation item = new MeanAndStandardDeviation(
    300                    mean, standardDeviation);
    301            this.data.addObject(item, rowKey, columnKey);
    302            double m = 0.0;
    303            double sd = 0.0;
    304            if (mean != null) {
    305                m = mean.doubleValue();
    306            }
    307            if (standardDeviation != null) {
    308                sd = standardDeviation.doubleValue();
    309            }
    310
    311            if (!Double.isNaN(m)) {
    312                if (Double.isNaN(this.maximumRangeValue)
    313                        || m > this.maximumRangeValue) {
    314                    this.maximumRangeValue = m;
    315                }
    316            }
    317
    318            if (!Double.isNaN(m + sd)) {
    319                if (Double.isNaN(this.maximumRangeValueIncStdDev)
    320                        || (m + sd) > this.maximumRangeValueIncStdDev) {
    321                    this.maximumRangeValueIncStdDev = m + sd;
    322                }
    323            }
    324
    325            if (!Double.isNaN(m)) {
    326                if (Double.isNaN(this.minimumRangeValue)
    327                        || m < this.minimumRangeValue) {
    328                    this.minimumRangeValue = m;
    329                }
    330            }
    331
    332            if (!Double.isNaN(m - sd)) {
    333                if (Double.isNaN(this.minimumRangeValueIncStdDev)
    334                        || (m - sd) < this.minimumRangeValueIncStdDev) {
    335                    this.minimumRangeValueIncStdDev = m - sd;
    336                }
    337            }
    338
    339            fireDatasetChanged();
    340        }
    341
    342        /**
    343         * Returns the minimum y-value in the dataset.
    344         *
    345         * @param includeInterval  a flag that determines whether or not the
    346         *                         y-interval is taken into account (ignored for
    347         *                         this dataset).
    348         *
    349         * @return The minimum value.
    350         */
    351        public double getRangeLowerBound(boolean includeInterval) {
    352            return this.minimumRangeValue;
    353        }
    354
    355        /**
    356         * Returns the maximum y-value in the dataset.
    357         *
    358         * @param includeInterval  a flag that determines whether or not the
    359         *                         y-interval is taken into account (ignored for
    360         *                         this dataset).
    361         *
    362         * @return The maximum value.
    363         */
    364        public double getRangeUpperBound(boolean includeInterval) {
    365            return this.maximumRangeValue;
    366        }
    367
    368        /**
    369         * Returns the range of the values in this dataset's range.
    370         *
    371         * @param includeInterval  a flag that determines whether or not the
    372         *                         y-interval is taken into account.
    373         *
    374         * @return The range.
    375         */
    376        public Range getRangeBounds(boolean includeInterval) {
    377            Range result = null;
    378            if (includeInterval) {
    379                if (!Double.isNaN(this.minimumRangeValueIncStdDev)
    380                        && !Double.isNaN(this.maximumRangeValueIncStdDev))
    381                result = new Range(this.minimumRangeValueIncStdDev,
    382                        this.maximumRangeValueIncStdDev);
    383            }
    384            else {
    385                if (!Double.isNaN(this.minimumRangeValue)
    386                        && !Double.isNaN(this.maximumRangeValue))
    387                result = new Range(this.minimumRangeValue, this.maximumRangeValue);
    388            }
    389            return result;
    390        }
    391
    392        /**
    393         * Tests this instance for equality with an arbitrary object.
    394         *
    395         * @param obj  the object (<code>null</code> permitted).
    396         *
    397         * @return A boolean.
    398         */
    399        public boolean equals(Object obj) {
    400            if (obj == this) {
    401                return true;
    402            }
    403            if (!(obj instanceof DefaultStatisticalCategoryDataset)) {
    404                return false;
    405            }
    406            DefaultStatisticalCategoryDataset that
    407                = (DefaultStatisticalCategoryDataset) obj;
    408            if (!this.data.equals(that.data)) {
    409                return false;
    410            }
    411            return true;
    412        }
    413    }