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     * OutlierList.java
029     * ----------------
030     * (C) Copyright 2003, 2004, 2007, by David Browning and Contributors.
031     *
032     * Original Author:  David Browning (for Australian Institute of Marine 
033     *                   Science);
034     * Contributor(s):   David Gilbert (for Object Refinery Limited);
035     *
036     * $Id: OutlierList.java,v 1.2.2.2 2007/02/02 15:52:24 mungady Exp $
037     *
038     * Changes
039     * -------
040     * 05-Aug-2003 : Version 1, contributed by David Browning (DG);
041     * 28-Aug-2003 : Minor tidy-up including Javadocs (DG);
042     * ------------- JFREECHART 1.0.x ---------------------------------------------
043     * 02-Feb-2007 : Removed author tags from all over JFreeChart sources (DG);
044     *
045     */
046    package org.jfree.chart.renderer;
047    
048    import java.awt.geom.Point2D;
049    import java.util.ArrayList;
050    import java.util.Iterator;
051    import java.util.List;
052    
053    /**
054     * A collection of outliers for a single entity in a box and whisker plot.
055     *
056     * Outliers are grouped in lists for each entity. Lists contain
057     * one or more outliers, determined by whether overlaps have
058     * occured. Overlapping outliers are grouped in the same list.
059     *
060     * Each list contains an averaged outlier, which is the same as a single
061     * outlier if there is only one outlier in the list, but the average of
062     * all the outliers in the list if there is more than one.
063     *
064     * NB This is simply my scheme for displaying outliers, and might not be
065     * acceptable by the wider community.
066     */
067    public class OutlierList {
068    
069        /** Storage for the outliers. */
070        private List outliers;
071        
072        /** The averaged outlier. */
073        private Outlier averagedOutlier;
074        
075        /** 
076         * A flag that indicates whether or not there are multiple outliers in the 
077         * list. 
078         */
079        private boolean multiple = false;
080    
081        /**
082         * Creates a new list containing a single outlier.
083         * 
084         * @param outlier  the outlier.
085         */
086        public OutlierList(Outlier outlier) {
087            this.outliers = new ArrayList();
088            setAveragedOutlier(outlier);
089        }
090    
091        /**
092         * Adds an outlier to the list.
093         * 
094         * @param outlier  the outlier.
095         * 
096         * @return A boolean.
097         */
098        public boolean add(Outlier outlier) {
099            return this.outliers.add(outlier);    
100        }
101        
102        /**
103         * Returns the number of outliers in the list.
104         * 
105         * @return The item count.
106         */
107        public int getItemCount() {
108            return this.outliers.size();
109        }
110        
111        /**
112         * Returns the averaged outlier. 
113         * 
114         * @return The averaged outlier.
115         */
116        public Outlier getAveragedOutlier() {
117            return this.averagedOutlier;
118        }
119    
120        /**
121         * Sets the averaged outlier.
122         * 
123         * @param averagedOutlier  the averaged outlier.
124         */
125        public void setAveragedOutlier(Outlier averagedOutlier) {
126            this.averagedOutlier = averagedOutlier;
127        }
128    
129        /**
130         * Returns <code>true</code> if the list contains multiple outliers, and 
131         * <code>false</code> otherwise.
132         * 
133         * @return A boolean.
134         */
135        public boolean isMultiple() {
136            return this.multiple;
137        }
138    
139        /**
140         * Sets the flag that indicates whether or not this list represents 
141         * multiple outliers.
142         * 
143         * @param multiple  the flag.
144         */
145        public void setMultiple(boolean multiple) {
146            this.multiple = multiple;
147        }
148    
149        /**
150         * Returns <code>true</code> if the outlier overlaps, and 
151         * <code>false</code> otherwise.
152         * 
153         * @param other  the outlier.
154         * 
155         * @return A boolean.
156         */
157        public boolean isOverlapped(Outlier other) {
158    
159            if (other == null) {
160                return false;
161            }
162            
163            boolean result = other.overlaps(getAveragedOutlier());
164            return result;
165            
166        }
167    
168        /**
169         * Updates the averaged outlier.
170         *
171         */
172        public void updateAveragedOutlier() {
173            double totalXCoords = 0.0;
174            double totalYCoords = 0.0;
175            int size = getItemCount();
176            for (Iterator iterator = this.outliers.iterator(); 
177                 iterator.hasNext();) {
178                Outlier o = (Outlier) iterator.next();
179                totalXCoords += o.getX();
180                totalYCoords += o.getY();
181            }
182            getAveragedOutlier().getPoint().setLocation(
183                new Point2D.Double(totalXCoords / size, totalYCoords / size)
184            );
185        }
186    
187    }