001    /*
002     * Copyright 2011 Christian Kumpe http://kumpe.de/christian/java
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     *     http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package de.kumpe.hadooptimizer.examples.functions;
017    
018    import java.awt.Color;
019    import java.awt.Graphics2D;
020    import java.util.ArrayList;
021    import java.util.Collection;
022    import java.util.Collections;
023    import java.util.Iterator;
024    import java.util.List;
025    
026    import de.kumpe.hadooptimizer.EvaluationResult;
027    import de.kumpe.hadooptimizer.Evaluator;
028    
029    /**
030     * A Panel which draws the graph of the evaluation-function (in the usual
031     * coordinate-system) renders the current population on top of the graph every
032     * {@link #refreshMillis} milliseconds.
033     * 
034     * @author Christian Kumpe <christian@kumpe.de>
035     */
036    public class LiveHistoryPanelReporter extends HistoryPanelReporter {
037            private static final long serialVersionUID = 1L;
038            private final int refreshMillis;
039            private volatile List<double[]> currentPopulation;
040            private volatile long iteration;
041            private long lastRepaint;
042    
043            public LiveHistoryPanelReporter(final Evaluator<double[]> evaluator,
044                            final int refreshMillis) {
045                    super(evaluator);
046                    this.refreshMillis = refreshMillis;
047            }
048    
049            @Override
050            public void report(
051                            final Collection<EvaluationResult<double[]>> evaluationResults) {
052                    iteration++;
053                    final ArrayList<double[]> list = new ArrayList<double[]>();
054                    for (final EvaluationResult<double[]> evaluationResult : evaluationResults) {
055                            list.add(evaluationResult.getIndividual());
056                    }
057                    currentPopulation = Collections.unmodifiableList(list);
058                    final long currentTime = System.currentTimeMillis();
059                    if (currentTime - lastRepaint > refreshMillis) {
060                            repaint();
061                            lastRepaint = currentTime;
062                    }
063            }
064    
065            @Override
066            protected void drawPopulations(final Graphics2D graphics) {
067                    final int width = getWidth();
068                    final int height = getHeight();
069                    final int centerX = width / 2;
070                    final int centerY = height / 2;
071    
072                    if (null == currentPopulation) {
073                            return;
074                    }
075                    final Iterator<double[]> individuals = currentPopulation.iterator();
076                    if (!individuals.hasNext()) {
077                            return;
078                    }
079                    double[] individual = individuals.next();
080                    double x = individual[0];
081                    double y = evaluator.evaluate(individual);
082                    int pixelX = (int) (x * SCALE_FACTOR);
083                    int pixelY = -(int) (y * SCALE_FACTOR);
084                    graphics.setColor(Color.LIGHT_GRAY);
085                    graphics.drawLine(-centerX, pixelY, centerX, pixelY);
086                    graphics.drawLine(pixelX, -centerY, pixelX, centerY);
087    
088                    graphics.setColor(Color.BLACK);
089                    graphics.setFont(HistoryPanelReporter.MEDIUM_FONT);
090                    graphics.drawString(String.format("x=%10.5f y=%10.5f", x, y),
091                                    pixelX + 3, pixelY + 15);
092    
093                    graphics.setFont(HistoryPanelReporter.LARGE_FONT);
094                    graphics.drawString(String.format("Iteration %d: x=%10.5f y=%10.5f",
095                                    iteration, x, y), -centerX, -centerY + 20);
096    
097                    graphics.setColor(Color.BLUE);
098                    graphics.fillOval(pixelX - 3, pixelY - 3, 6, 6);
099    
100                    while (individuals.hasNext()) {
101                            individual = individuals.next();
102                            x = individual[0];
103                            y = evaluator.evaluate(individual);
104                            pixelX = (int) (x * SCALE_FACTOR);
105                            pixelY = -(int) (y * SCALE_FACTOR);
106                            graphics.drawOval(pixelX - 1, pixelY - 1, 2, 2);
107                    }
108            }
109    }