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