001    package org.jaga.hooks;
002    
003    import java.awt.*;
004    import javax.swing.JPanel;
005    import java.util.ArrayList;
006    
007    
008    /**
009     * TODO: Complete these comments.
010     *
011     * <p><u>Project:</u> JAGA - Java API for Genetic Algorithms.</p>
012     *
013     * <p><u>Company:</u> University College London and JAGA.Org
014     *    (<a href="http://www.jaga.org" target="_blank">http://www.jaga.org</a>).
015     * </p>
016     *
017     * <p><u>Copyright:</u> (c) 2004 by G. Paperin.<br/>
018     *    This program is free software; you can redistribute it and/or modify
019     *    it under the terms of the GNU General Public License as published by
020     *    the Free Software Foundation, ONLY if you include a note of the original
021     *    author(s) in any redistributed/modified copy.<br/>
022     *    This program is distributed in the hope that it will be useful,
023     *    but WITHOUT ANY WARRANTY; without even the implied warranty of
024     *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
025     *    GNU General Public License for more details.<br/>
026     *    You should have received a copy of the GNU General Public License
027     *    along with this program; if not, write to the Free Software
028     *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
029     *    or see http://www.gnu.org/licenses/gpl.html</p>
030     *
031     * @author Greg Paperin (greg@jaga.org)
032     *
033     * @version JAGA public release 1.0 beta
034     */
035    
036    public class AnalysisGraphPanel extends JPanel {
037    
038            private static final int border = 10;//pixels
039    
040            private AnalysisHook hook = null;
041            private double xFactor = 0;
042            private double yFactor = 0;
043    
044            private AnalysisGraphPanel() {
045                    throw new UnsupportedOperationException("Use AnalysisGraphPanel(AnalysisHook hook) instead");
046            }
047    
048            public AnalysisGraphPanel(AnalysisHook hook) {
049                    super();
050                    if (null == hook)
051                            throw new NullPointerException("Analysis hook may not be null");
052                    setBackground(Color.white);
053                    this.hook = hook;
054            }
055    
056            public void paint(Graphics g) {
057                    super.paint(g);
058                    if (null == hook || 0 == hook.getMaxPlotCount())
059                            return;
060    
061                    synchronized (hook) {
062    
063                            xFactor = (double) (getWidth() - 2 * border)
064                                              / (double) (hook.getMaxPlotCount() - 1);
065    
066                            if (hook.getMaxPlotVal() == hook.getMinPlotVal())
067                                    yFactor = 0;
068                            else
069                                    yFactor = (double) (getHeight() - 2 * border)
070                                                      / (hook.getMaxPlotVal() - hook.getMinPlotVal());
071    
072                            plotScale(g, Color.LIGHT_GRAY);
073    
074                            if (hook.isAnalyseGenMinFit())
075                                    plotFitnessGraph(g, hook.getGenMinFitnesses(), Color.RED);
076    
077                            if (hook.isAnalyseGenFitStdDeviation())
078                                    plotStdDeviationGraph(g, hook.getGenAverageFitnesses(), Color.ORANGE);
079    
080                            if (hook.isAnalyseGenAverageFit())
081                                    plotFitnessGraph(g, hook.getGenAverageFitnesses(), Color.BLACK);
082    
083                            if (hook.isAnalyseGenMaxFit())
084                                    plotFitnessGraph(g, hook.getGenMaxFitnesses(), Color.GREEN);
085    
086                            if (hook.isAnalyseBestFitness())
087                                    plotBestGraph(g, hook.getBestFitnessValues(), Color.BLUE);
088                    }
089            }
090    
091            private void plotScale(Graphics g, Color col) {
092    
093                    g.setColor(col);
094    
095                    int x1 = scaleX(0);
096                    int y1 = scaleY(0.5 * (hook.getMaxPlotVal() + hook.getMinPlotVal()));
097                    int x2 = scaleX(hook.getMaxPlotCount() - 1);
098                    int y2 = y1;
099                    g.drawLine(x1, y1, x2, y2);
100    
101                    x1 = scaleX(0.5 * (double) (hook.getMaxPlotCount() - 1));
102                    y1 = scaleY(hook.getMaxPlotVal());
103                    x2 = x1;
104                    y2 = scaleY(hook.getMinPlotVal());
105                    g.drawLine(x1, y1, x2, y2);
106    
107                    String s = (new StringBuffer()).append("(gen")
108                                       .append(0.5 * (double) (hook.getMaxPlotCount() - 1))
109                                       .append(", fit=")
110                                       .append(hook.getMaxPlotVal())
111                                       .append(")").toString();
112                    x1 = scaleX(0.5 * (double) (hook.getMaxPlotCount() - 1)) + 3;
113                    y1 = scaleY(hook.getMaxPlotVal()) + g.getFontMetrics().getHeight();
114                    g.drawString(s, x1, y1);
115    
116                    s = (new StringBuffer()).append("(gen=")
117                                       .append(0.5 * (double) (hook.getMaxPlotCount() - 1))
118                                       .append(", fit=")
119                                       .append(hook.getMinPlotVal())
120                                       .append(")").toString();
121                    x1 = scaleX(0.5 * (double) (hook.getMaxPlotCount() - 1))
122                             - (3 + g.getFontMetrics().stringWidth(s));
123                    y1 = scaleY(hook.getMinPlotVal());
124                    g.drawString(s, x1, y1);
125    
126                    s = (new StringBuffer()).append("(gen=")
127                                       .append(0)
128                                       .append(", fit=")
129                                       .append(0.5 * (hook.getMaxPlotVal() + hook.getMinPlotVal()))
130                                       .append(")").toString();
131                    x1 = scaleX(0);
132                    y1 = scaleY(0.5 * (hook.getMaxPlotVal() + hook.getMinPlotVal()))
133                             - g.getFontMetrics().getHeight() / 3;
134                    g.drawString(s, x1, y1);
135    
136                    s = (new StringBuffer()).append("(gen=")
137                                       .append(hook.getMaxPlotCount() - 1)
138                                       .append(", fit=")
139                                       .append(0.5 * (hook.getMaxPlotVal() + hook.getMinPlotVal()))
140                                       .append(")").toString();
141                    x1 = scaleX(hook.getMaxPlotCount() - 1) - g.getFontMetrics().stringWidth(s);
142                    y1 = scaleY(0.5 * (hook.getMaxPlotVal() + hook.getMinPlotVal()))
143                             + g.getFontMetrics().getHeight();
144                    g.drawString(s, x1, y1);
145    
146            }
147    
148            private void plotFitnessGraph(Graphics g, ArrayList data, Color col) {
149    
150                    if (null == data || 0 == data.size())
151                            return;
152    
153                    g.setColor(col);
154    
155                    int x2, y2;
156                    int x1 = getX((AnalysisHook.Entry) data.get(0));
157                    int y1 = getY((AnalysisHook.Entry) data.get(0));
158                    for (int i = 1; i < data.size(); i++) {
159                            x2 = getX((AnalysisHook.Entry) data.get(i));
160                            y2 = getY((AnalysisHook.Entry) data.get(i));
161                            g.drawLine(x1, y1, x2, y2);
162                            x1 = x2;
163                            y1 = y2;
164                    }
165            }
166    
167            private void plotStdDeviationGraph(Graphics g, ArrayList avgFitData, Color col) {
168    
169                    if (null == avgFitData || 0 == avgFitData.size())
170                            return;
171    
172                    g.setColor(col);
173    
174                    int x2, top_y2, bot_y2;
175    
176                    AnalysisHook.Entry e = (AnalysisHook.Entry) avgFitData.get(0);
177    
178                    int top_y1 = scaleY(e.getValue() +
179                                                            hook.getStdDeviation(e.getGeneration()).getValue());
180                    int bot_y1 = scaleY(e.getValue() -
181                                                            hook.getStdDeviation(e.getGeneration()).getValue());
182                    int x1 = scaleX(e.getGeneration());
183    
184                    for (int i = 1; i < avgFitData.size(); i++) {
185    
186                            e = (AnalysisHook.Entry) avgFitData.get(i);
187    
188                            top_y2 = scaleY(e.getValue() +
189                                                            hook.getStdDeviation(e.getGeneration()).getValue());
190                            bot_y2 = scaleY(e.getValue() -
191                                                            hook.getStdDeviation(e.getGeneration()).getValue());
192                            x2 = scaleX(e.getGeneration());
193    
194                            g.drawLine(x1, top_y1, x2, top_y2);
195                            g.drawLine(x1, bot_y1, x2, bot_y2);
196    
197                            top_y1 = top_y2;
198                            bot_y1 = bot_y2;
199                            x1 = x2;
200                    }
201    
202            }
203    
204            private void plotBestGraph(Graphics g, ArrayList data, Color col) {
205    
206                    if (null == data || 0 == data.size())
207                            return;
208    
209                    g.setColor(col);
210    
211                    int x2 = getX((AnalysisHook.Entry) data.get(0));
212                    int y2 = getY((AnalysisHook.Entry) data.get(0));
213                    int x1, y1;
214                    for (int i = 1; i < data.size(); i++) {
215    
216                            x1 = getX((AnalysisHook.Entry) data.get(i-1));
217                            y1 = getY((AnalysisHook.Entry) data.get(i-1));
218                            x2 = getX((AnalysisHook.Entry) data.get(i));
219                            y2 = getY((AnalysisHook.Entry) data.get(i-1));
220                            g.drawLine(x1, y1, x2, y2);
221    
222                            x1 = x2;
223                            y1 = y2;
224                            x2 = x1;
225                            y2 = getY((AnalysisHook.Entry) data.get(i));
226                            g.drawLine(x1, y1, x2, y2);
227                    }
228    
229                    x1 = x2;
230                    y1 = y2;
231                    x2 = scaleX(hook.getMaxPlotCount() - 1);
232                    y2 = y1;
233                    g.drawLine(x1, y1, x2, y2);
234    
235                    /*
236                    int x2, y2;
237                    int x1 = getX((AnalysisHook.Entry) data.get(0));
238                    int y1 = getY((AnalysisHook.Entry) data.get(0));
239                    for (int i = 1; i < data.size(); i++) {
240                            x2 = getX((AnalysisHook.Entry) data.get(i));
241                            y2 = getY((AnalysisHook.Entry) data.get(i));
242                            g.drawLine(x1, y1, x2, y2);
243                            x1 = x2;
244                            y1 = y2;
245                    }
246                    x2 = scaleX(hook.getMaxPlotCount() - 1);
247                    y2 = y1;
248                    g.drawLine(x1, y1, x2, y2);
249                    */
250    
251            }
252    
253            private int getX(AnalysisHook.Entry entry) {
254                    return scaleX(entry.getGeneration());
255            }
256    
257            private int getY(AnalysisHook.Entry entry) {
258                    return scaleY(entry.getValue());
259            }
260    
261            private int scaleX(double x) {
262                    return (int) (border + x * xFactor);
263            }
264    
265            private int scaleY(double y) {
266                    return (int) (getHeight() - border -
267                                              (y - hook.getMinPlotVal()) * yFactor);
268            }
269    
270    }