00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
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
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
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
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
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
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 }