001    /**
002     * EvaluationResultGUI.java
003     * jCOLIBRI2 framework. 
004     * @author Juan A. Recio-García.
005     * GAIA - Group for Artificial Intelligence Applications
006     * http://gaia.fdi.ucm.es
007     * 07/05/2007
008     */
009    package jcolibri.evaluation.tools;
010    
011    import java.awt.BorderLayout;
012    import java.awt.Component;
013    import java.awt.Dimension;
014    import java.awt.FileDialog;
015    import java.awt.Graphics;
016    import java.awt.event.ActionEvent;
017    import java.awt.event.ActionListener;
018    import java.awt.event.WindowAdapter;
019    import java.awt.event.WindowEvent;
020    import java.awt.image.BufferedImage;
021    import java.io.File;
022    import java.io.FileOutputStream;
023    import java.io.IOException;
024    import java.io.PrintWriter;
025    import java.util.Vector;
026    
027    import javax.swing.Box;
028    import javax.swing.BoxLayout;
029    import javax.swing.JButton;
030    import javax.swing.JFrame;
031    import javax.swing.JLabel;
032    import javax.swing.JPanel;
033    import javax.swing.JScrollPane;
034    import javax.swing.JTextArea;
035    
036    import jcolibri.evaluation.EvaluationReport;
037    import net.sourceforge.chart2d.Chart2D;
038    import net.sourceforge.chart2d.Chart2DProperties;
039    import net.sourceforge.chart2d.Dataset;
040    import net.sourceforge.chart2d.GraphChart2DProperties;
041    import net.sourceforge.chart2d.GraphProperties;
042    import net.sourceforge.chart2d.LBChart2D;
043    import net.sourceforge.chart2d.LegendProperties;
044    import net.sourceforge.chart2d.MultiColorsProperties;
045    import net.sourceforge.chart2d.Object2DProperties;
046    
047    import com.sun.image.codec.jpeg.JPEGCodec;
048    import com.sun.image.codec.jpeg.JPEGEncodeParam;
049    import com.sun.image.codec.jpeg.JPEGImageEncoder;
050    
051    /**
052     * Class that visualizates the result of an evaluation in a Swing frame.
053     * It generates a chart with the evaluation result an other information returned by the evaluator.
054     * 
055     * @author Juan A. Recio-Garcia
056     *
057     */
058    public class EvaluationResultGUI
059    {
060        private static final long serialVersionUID = 1L;
061        
062        private static Chart2D chart;
063        private static JFrame dialog;
064        private static EvaluationReport evalReport; 
065        
066        public static void show(EvaluationReport er, String title, boolean exitOnClose)
067        {
068            evalReport = er;
069            
070           dialog = new JFrame();
071           dialog.setTitle("jCOLIBRI Evaluation");
072           dialog.getContentPane().setLayout(new BorderLayout());
073           
074           JPanel data = new JPanel();
075           data.setLayout(new BoxLayout(data,BoxLayout.X_AXIS));
076           data.add(new JLabel("Cycles: "+ er.getNumberOfCycles()));
077           data.add(Box.createGlue());
078           data.add(new JLabel("Time: "+ er.getTotalTime()+" ms"));
079           data.add(Box.createGlue());
080           data.add(new JLabel("Time per cycle: "+ er.getTimePerCycle()+" ms"));
081           //data.add(Box.createGlue());
082           //data.add( new JLabel("Average: "+ String.format("%6f",er.getEvaluationAverage())));
083           dialog.getContentPane().add(data,BorderLayout.NORTH);
084    
085           chart = getChart(title, er);
086           
087           JTextArea textArea = new JTextArea();
088           JScrollPane sp = new JScrollPane(textArea);
089           sp.setViewportView(textArea);
090           textArea.setText(er.toString());
091           textArea.setEditable(false);
092                  
093           dialog.getContentPane().add(chart, BorderLayout.CENTER);
094           
095           JPanel buttons = new JPanel();
096           //buttons.setLayout(new BoxLayout(buttons,BoxLayout.X_AXIS));
097           JButton exportData = new JButton("Export data");
098           exportData.addActionListener( new ActionListener(){
099                public void actionPerformed(ActionEvent e)
100                {
101                    try{
102                        FileDialog fd = new FileDialog(dialog, "Save as CSV", FileDialog.SAVE);
103                        fd.setFile("evaluation.csv");
104                        fd.setVisible(true);
105                        String name = fd.getDirectory() + fd.getFile();
106                        File file = new File(name);
107                        saveEvaluationToCSV(evalReport, file);
108                    }
109                    catch(Exception ex) { 
110                        ex.printStackTrace(); 
111                    }                
112                }
113               
114           });
115           
116           
117           JButton exportChart = new JButton("Export chart");
118           exportChart.addActionListener( new ActionListener(){
119                public void actionPerformed(ActionEvent e) {
120                    try{
121                        FileDialog fd = new FileDialog(dialog, "Save as JPG", FileDialog.SAVE);
122                        fd.setFile("evaluation.jpg");
123                        fd.setVisible(true);
124                        String name = fd.getDirectory() + fd.getFile();
125                        File file = new File(name);
126                        saveComponentToJPG(chart, file);
127                    }
128                    catch(Exception ex) { 
129                        ex.printStackTrace(); 
130                    }
131                }
132           });
133    
134           
135           buttons.add(exportData);
136           buttons.add(exportChart);
137           
138           JPanel p = new JPanel();
139           p.setLayout(new BoxLayout(p,BoxLayout.Y_AXIS));
140           p.add(sp);
141           p.add(buttons);
142    
143           
144           dialog.getContentPane().add(p, BorderLayout.SOUTH);
145    
146           /*
147           dialog.addWindowListener(new WindowAdapter()
148           {  public void windowClosing(WindowEvent we)
149              {  System.exit(0);
150              }
151           });
152           */
153           dialog.setPreferredSize(new Dimension(640,400));
154           dialog.pack();
155           dialog.doLayout();
156           dialog.setVisible(true);
157    
158           if(exitOnClose)
159               dialog.addWindowListener(new WindowAdapter() 
160               {   public void windowClosing(WindowEvent arg0) 
161                   {   System.exit(0);
162                   }
163               });
164        }
165        
166        
167        private static Chart2D getChart(String title, EvaluationReport er) {
168    
169            //<-- Begin Chart2D configuration -->
170    
171            //Configure object properties
172            Object2DProperties object2DProps = new Object2DProperties();
173            object2DProps.setObjectTitleText (title);
174    
175            //Configure chart properties
176            Chart2DProperties chart2DProps = new Chart2DProperties();
177            chart2DProps.setChartDataLabelsPrecision (-2);
178    
179            //Configure legend properties
180            LegendProperties legendProps = new LegendProperties();
181            legendProps.setLegendExistence(true);
182            String[] labels = er.getSeriesLabels();
183            legendProps.setLegendLabelsTexts (labels);
184    
185            //Configure graph chart properties
186            GraphChart2DProperties graphChart2DProps = new GraphChart2DProperties();
187            //String[] labelsAxisLabels = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
188            graphChart2DProps.setLabelsAxisExistence(false); //setLabelsAxisLabelsTexts (labelsAxisLabels);
189            //graphChart2DProps.setLabelsAxisTitleText ("Iteration");
190            graphChart2DProps.setNumbersAxisTitleText ("Evaluation");
191            graphChart2DProps.setLabelsAxisTicksAlignment (GraphChart2DProperties.CENTERED);
192            //graphChart2DProps.setChartDatasetCustomGreatestValue(1);
193            //graphChart2DProps.setChartDatasetCustomizeGreatestValue(true);
194    
195            //Configure graph properties
196            GraphProperties graphProps = new GraphProperties();
197            graphProps.setGraphBarsExistence (false);
198            graphProps.setGraphLinesExistence (true);
199            graphProps.setGraphLinesThicknessModel (2);
200            graphProps.setGraphLinesWithinCategoryOverlapRatio (1f);
201            graphProps.setGraphDotsExistence (false);
202            graphProps.setGraphDotsThicknessModel (4);
203            graphProps.setGraphDotsWithinCategoryOverlapRatio (1f);
204            graphProps.setGraphAllowComponentAlignment (true);
205            graphProps.setGraphOutlineComponentsExistence (true);
206    
207            int lines = labels.length;
208            int lineSize = er.getSeries(labels[0]).size();
209            
210            //Configure dataset
211            Dataset dataset = new Dataset (lines, lineSize, 1);
212              
213            for( int l=0; l<lines; l++)
214            {
215                Vector<Double> line = er.getSeries(labels[l]);
216                for (int j = 0; j < dataset.getNumCats(); ++j) {
217                      dataset.set (l, j, 0, (float)line.get(j).floatValue());
218                    }
219            }
220    
221            //Configure graph component colors
222            MultiColorsProperties multiColorsProps = new MultiColorsProperties();
223    
224            //Configure chart
225            LBChart2D chart2D = new LBChart2D();
226            chart2D.setObject2DProperties (object2DProps);
227            chart2D.setChart2DProperties (chart2DProps);
228            chart2D.setLegendProperties (legendProps);
229            chart2D.setGraphChart2DProperties (graphChart2DProps);
230            chart2D.addGraphProperties (graphProps);
231            chart2D.addDataset (dataset);
232            chart2D.addMultiColorsProperties (multiColorsProps);
233    
234            //Optional validation:  Prints debug messages if invalid only.
235            if (!chart2D.validate (false)) chart2D.validate (true);
236    
237            //<-- End Chart2D configuration -->
238    
239            return chart2D;
240          }
241        
242    
243         static void saveEvaluationToCSV(EvaluationReport er, File file) throws IOException{
244             PrintWriter pw = new PrintWriter(file);
245             pw.println("# Cycles: "+ er.getNumberOfCycles());
246             pw.println("# Time: "+ er.getTotalTime()+" ms");
247             pw.println("# Time per cycle: "+ er.getTimePerCycle()+" ms");
248             //pw.println("# Average: "+ String.format("%6f",er.getEvaluationAverage()));
249             
250             String[] labels = er.getSeriesLabels();
251             
252             for(int l = 0; l<labels.length; l++)
253             {
254                 Vector<Double> res = er.getSeries(labels[l]);
255                 pw.print(labels[l]);
256                 for(int i=0; i<res.size(); i++)
257                     pw.print(";"+res.get(i));
258                 pw.println();
259             }
260                 
261             pw.close();
262         }
263              
264         static void saveComponentToJPG(Component component, File file) throws IOException{
265                BufferedImage image = (BufferedImage)component.createImage(component.getWidth(),component.getHeight());
266                Graphics graphics = image.getGraphics();
267                if(graphics != null) { component.paintAll(graphics); }
268                FileOutputStream fileStream = new FileOutputStream(file);
269                JPEGEncodeParam encodeParam = JPEGCodec.getDefaultJPEGEncodeParam(image);
270                JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(fileStream);
271                encoder.encode(image,encodeParam);
272                fileStream.close();
273         }
274    
275         
276    }