org/objectweb/proactive/benchmarks/timit/util/charts/HierarchicalBarChart.java

00001 /* 
00002  * ################################################################
00003  * 
00004  * ProActive: The Java(TM) library for Parallel, Distributed, 
00005  *            Concurrent computing with Security and Mobility
00006  * 
00007  * Copyright (C) 1997-2007 INRIA/University of Nice-Sophia Antipolis
00008  * Contact: proactive@objectweb.org
00009  * 
00010  * This library is free software; you can redistribute it and/or
00011  * modify it under the terms of the GNU Lesser General Public
00012  * License as published by the Free Software Foundation; either
00013  * version 2.1 of the License, or any later version.
00014  *  
00015  * This library is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018  * Lesser General Public License for more details.
00019  * 
00020  * You should have received a copy of the GNU Lesser General Public
00021  * License along with this library; if not, write to the Free Software
00022  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
00023  * USA
00024  *  
00025  *  Initial developer(s):               The ProActive Team
00026  *                        http://www.inria.fr/oasis/ProActive/contacts.html
00027  *  Contributor(s): 
00028  * 
00029  * ################################################################
00030  */ 
00031 package org.objectweb.proactive.benchmarks.timit.util.charts;
00032 
00033 import java.awt.Color;
00034 import java.awt.Rectangle;
00035 import java.util.Iterator;
00036 import java.util.List;
00037 import java.util.Vector;
00038 import org.jdom.Element;
00039 import org.jdom.filter.ElementFilter;
00040 import org.jfree.chart.ChartUtilities;
00041 import org.jfree.chart.JFreeChart;
00042 import org.jfree.chart.axis.CategoryAxis;
00043 import org.jfree.chart.axis.NumberAxis;
00044 import org.jfree.chart.axis.ValueAxis;
00045 import org.jfree.chart.plot.CategoryPlot;
00046 import org.jfree.chart.plot.PlotOrientation;
00047 import org.jfree.chart.title.TextTitle;
00048 import org.jfree.data.category.CategoryDataset;
00049 import org.jfree.data.general.DatasetUtilities;
00050 import org.objectweb.proactive.benchmarks.timit.config.ConfigChart;
00051 import org.objectweb.proactive.benchmarks.timit.util.BenchmarkStatistics;
00052 import org.objectweb.proactive.benchmarks.timit.util.XMLHelper;
00053 import org.objectweb.proactive.benchmarks.timit.util.charts.renderer.HierarchicalBarRenderer;
00054 
00055 public class HierarchicalBarChart implements Chart {
00056 
00060     private static final long serialVersionUID = 321266061715197229L;
00061 
00062     private static double CATEGORY_MARGIN = 0.0;
00063 
00064     private Element[] timers;
00065 
00066     private Comparable[] categories;
00067 
00068 
00069     public void generateChart(Element eTimit, BenchmarkStatistics bstats,
00070             ConfigChart cChart) {
00071 
00072         Element eTimitClone = (Element) eTimit.clone();
00073         
00074         // Apply filter on elements
00075         Iterator<Element> itTimers =
00076             eTimitClone.getDescendants(new ElementFilter("timers"));
00077 
00078         while (itTimers.hasNext()) {
00079             XMLHelper.tagFiltering(
00080                     itTimers.next(),
00081                     cChart.get("filter").split(","));
00082         }
00083         
00084         // Get values from XML tree (Element)
00085         List fstats = eTimitClone.getChildren();
00086         this.timers = new Element[fstats.size()];
00087         this.categories = new Comparable[fstats.size()];
00088 
00089         for (int i = 0; i < fstats.size(); i++) {
00090             Element fstat = (Element) fstats.get(i);
00091             fstat.removeChild("events");
00092             this.timers[i] = fstat.getChild("timers");
00093             this.categories[i] = fstat.getAttributeValue("name");
00094         }
00095 
00096         this.buildFinalChart(cChart);
00097     }
00098 
00099     private void buildFinalChart(ConfigChart cChart) {
00100         Chart.Scale scaleMode =
00101             ConfigChart.scaleValue(cChart.get("scaleMode"));
00102         Chart.LegendFormat legendFormatMode =
00103             ConfigChart.legendValue(cChart.get("legendFormatMode"));
00104         int alpha = Integer.valueOf(cChart.get("alpha"));
00105         
00106         if (scaleMode == Chart.Scale.DEFAULT) {
00107             scaleMode = Chart.Scale.LINEAR;
00108         }
00109         if (legendFormatMode == Chart.LegendFormat.DEFAULT) {
00110             legendFormatMode = Chart.LegendFormat.NONE;
00111         }
00112         this.buildFinalChart(
00113                 cChart.get("title"), cChart.get("subTitle"),
00114                 cChart.get("xAxisLabel"), cChart.get("yAxisLabel"),
00115                 Integer.valueOf(cChart.get("height")),
00116                 Integer.valueOf(cChart.get("width")),
00117                 cChart.get("filename"),
00118                 scaleMode, legendFormatMode, alpha);
00119     }
00120 
00121     private void buildFinalChart(
00122             String title, String subTitle,
00123             String xAxisLabel, String yAxisLabel,
00124             int height, int width,
00125             String filename,
00126             Chart.Scale scaleMode,
00127             Chart.LegendFormat legendFormatMode,
00128             int alpha) {
00129 
00130         Vector[] vec = new Vector[this.timers.length];
00131         boolean exist;
00132 
00133         // create the dataset...
00134         for (int i = 0; i < this.timers.length; i++) {
00135             vec[i] = new Vector();
00136             Iterator it = this.timers[i].getDescendants();
00137             while (it.hasNext()) {
00138                 try {
00139                     Element elt = (Element) it.next();
00140                     String name = elt.getAttributeValue("name");
00141                     double value = Double.valueOf(elt.getAttributeValue("avg"));
00142                     exist = false;
00143                     for (int j = 0; j < vec[i].size(); j++) {
00144                         if (((Counter) vec[i].get(j)).getName().equals(name)) {
00145                             ((Counter) vec[i].get(j)).addValue(value);
00146                             exist = true;
00147                             break;
00148                         }
00149                     }
00150                     if (!exist) {
00151                         vec[i].add(new Counter(name, value));
00152                     }
00153                 } catch (ClassCastException e) {
00154                     continue;
00155                 }
00156             }
00157         }
00158 
00159         CategoryDataset dataset = null;
00160         try {
00161             dataset = DatasetUtilities.createCategoryDataset(toSeries(vec[0]),
00162                     this.categories, toDataset(vec));
00163                         
00164         } catch (IllegalArgumentException e) {
00165             e.printStackTrace();
00166             throw new IllegalArgumentException(
00167                     "Benchmark names must have different names. Be sure that your filter contains correct timers names");
00168         }
00169 
00170         // create the chart...
00171         final CategoryAxis categoryAxis = new CategoryAxis(xAxisLabel);
00172         final ValueAxis valueAxis = new NumberAxis(yAxisLabel);
00173 
00174         final CategoryPlot plot = new CategoryPlot(dataset, categoryAxis,
00175                 valueAxis, new HierarchicalBarRenderer());
00176 
00177         plot.setOrientation(PlotOrientation.VERTICAL);
00178         final JFreeChart chart = new JFreeChart(title,
00179                 JFreeChart.DEFAULT_TITLE_FONT, plot, true);
00180         chart.addSubtitle(new TextTitle(subTitle));
00181 
00182         // set the background color for the chart...
00183         chart.setBackgroundPaint(Color.white);
00184 
00185         final HierarchicalBarRenderer renderer = (HierarchicalBarRenderer) plot
00186                 .getRenderer();
00187 
00188         renderer.setItemMargin(0.01);
00189         renderer.setDatasetTree(this.timers);
00190         renderer.setSeries(toSeries(vec[0]));
00191         renderer.setAlpha(alpha);
00192 
00193         final CategoryAxis domainAxis = plot.getDomainAxis();
00194         domainAxis.setCategoryMargin(HierarchicalBarChart.CATEGORY_MARGIN);
00195         domainAxis.setUpperMargin(0.05);
00196         domainAxis.setLowerMargin(0.05);
00197 
00198         try {
00199             ChartUtilities.saveChartAsPNG(new java.io.File(filename + ".png"),
00200                     chart, width, height);
00201 
00202             Utilities.saveChartAsSVG(chart, new Rectangle(width, height),
00203                     new java.io.File(filename + ".svg"));
00204 
00205         } catch (java.io.IOException e) {
00206             System.err.println("Error writing chart image to file");
00207             e.printStackTrace();
00208         }
00209     }
00210 
00211     private static double[][] toDataset(Vector[] counter) {
00212         try {
00213             double[][] result = new double[counter[0].size()][counter.length];
00214 
00215             for (int i = 0; i < counter.length; i++) {
00216                 for (int j = 0; j < counter[i].size(); j++) {
00217                     result[j][i] = ((Counter) counter[i].get(j)).getValue();
00218                 }
00219             }
00220             return result;
00221         } catch (ArrayIndexOutOfBoundsException e) {
00222             throw new IllegalArgumentException(
00223                     "Can't generate chart with irregular type of values");
00224         }
00225     }
00226 
00227     private static Comparable[] toSeries(Vector counter) {
00228         Comparable[] result = new Comparable[counter.size()];
00229         for (int i = 0; i < counter.size(); i++) {
00230             result[i] = ((Counter) counter.get(i)).getName();
00231         }
00232         return result;
00233     }
00234 
00235     private static class Counter {
00236         private String name;
00237 
00238         private double value;
00239 
00240         public Counter(String name, double value) {
00241             this.name = name;
00242             this.value = value;
00243         }
00244 
00245         public String getName() {
00246             return this.name;
00247         }
00248 
00249         public double getValue() {
00250             return this.value;
00251         }
00252 
00253         public void addValue(double value) {
00254             this.value += value;
00255         }
00256 
00257         public String toString() {
00258             return "[" + this.name + "=" + this.value + "]";
00259         }
00260     }
00261 }

Generated on Mon Jan 22 15:16:04 2007 for ProActive by  doxygen 1.5.1