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 }