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     * OutlierListCollection.java
029     * --------------------------
030     * (C) Copyright 2003, 2004, by David Browning and Contributors.
031     *
032     * Original Author:  David Browning (for Australian Institute of Marine 
033     *                   Science);
034     * Contributor(s):   -;
035     *
036     * $Id: OutlierListCollection.java,v 1.2.2.1 2005/10/25 20:53:40 mungady Exp $
037     *
038     * Changes
039     * -------
040     * 05-Aug-2003 : Version 1, contributed by David Browning (DG);
041     * 01-Sep-2003 : Made storage internal rather than extending ArrayList (DG);
042     *
043     */
044    
045    package org.jfree.chart.renderer;
046    
047    import java.util.ArrayList;
048    import java.util.Iterator;
049    import java.util.List;
050    
051    /**
052     * A collection of outlier lists for a box and whisker plot. Each collection is
053     * associated with a single box and whisker entity.
054     *
055     * Outliers are grouped in lists for each entity. Lists contain
056     * one or more outliers, determined by whether overlaps have
057     * occurred. Overlapping outliers are grouped in the same list.
058     *
059     * @see org.jfree.chart.renderer.OutlierList
060     *
061     * @author David Browning
062     */
063    public class OutlierListCollection {
064    
065        /** Storage for the outlier lists. */
066        private List outlierLists;
067        
068        /** 
069         * Unbelievably, outliers which are more than 2 * interquartile range are
070         * called far outs...  See Tukey EDA  (a classic one of a kind...)
071         */
072        private boolean highFarOut = false;
073    
074        /**
075         * A flag that indicates whether or not the collection contains low far 
076         * out values.
077         */
078        private boolean lowFarOut = false;
079        
080        /**
081         * Creates a new empty collection.
082         */
083        public OutlierListCollection() {
084            this.outlierLists = new ArrayList();
085        }
086        
087        /**
088         * A flag to indicate the presence of one or more far out values at the 
089         * top end of the range.
090         *
091         * @return A <code>boolean</code>.
092         */
093        public boolean isHighFarOut() {
094            return this.highFarOut;
095        }
096    
097        /**
098         * Sets the flag that indicates the presence of one or more far out values 
099         * at the top end of the range.
100         *
101         * @param farOut  the flag.
102         */
103        public void setHighFarOut(boolean farOut) {
104            this.highFarOut = farOut;
105        }
106    
107        /**
108         * A flag to indicate the presence of one or more far out values at the 
109         * bottom end of the range.
110         *
111         * @return A <code>boolean</code>.
112         */
113        public boolean isLowFarOut() {
114            return this.lowFarOut;
115        }
116    
117        /**
118         * Sets the flag that indicates the presence of one or more far out values 
119         * at the bottom end of the range.
120         *
121         * @param farOut  the flag.
122         */
123        public void setLowFarOut(boolean farOut) {
124            this.lowFarOut = farOut;
125        }
126        /**
127         * Appends the specified element as a new <code>OutlierList</code> to the
128         * end of this list if it does not overlap an outlier in an existing list.
129         *
130         * If it does overlap, it is appended to the outlier list which it overlaps
131         * and that list is updated.
132         *
133         * @param outlier  element to be appended to this list.
134         * 
135         * @return <tt>true</tt> (as per the general contract of Collection.add).
136         */
137        public boolean add(Outlier outlier) {
138    
139            if (this.outlierLists.isEmpty()) {
140                return this.outlierLists.add(new OutlierList(outlier));
141            } 
142            else {
143                boolean updated = false;
144                for (Iterator iterator = this.outlierLists.iterator(); 
145                     iterator.hasNext();) {
146                    OutlierList list = (OutlierList) iterator.next();
147                    if (list.isOverlapped(outlier)) {
148                        updated = updateOutlierList(list, outlier);
149                    }
150                }
151                if (!updated) {
152                    //System.err.print(" creating new outlier list ");
153                    updated = this.outlierLists.add(new OutlierList(outlier));
154                }
155                return updated;
156            }
157    
158        }
159    
160        /**
161         * Returns an iterator for the outlier lists.
162         * 
163         * @return An iterator.
164         */
165        public Iterator iterator() {
166            return this.outlierLists.iterator();    
167        }
168        
169        
170        /** 
171         * Updates the outlier list by adding the outlier to the end of the list and
172         * setting the averaged outlier to the average x and y coordinnate values 
173         * of the outliers in the list.
174         *
175         * @param list  the outlier list to be updated.
176         * @param outlier  the outlier to be added
177         *
178         * @return <tt>true</tt> (as per the general contract of Collection.add).
179         */
180        private boolean updateOutlierList(OutlierList list, Outlier outlier) {
181            boolean result = false;
182            result = list.add(outlier);
183            list.updateAveragedOutlier();
184            list.setMultiple(true);
185            return result;
186        }
187    
188    }