org/objectweb/proactive/benchmarks/timit/util/charts/MatrixChart.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.BasicStroke;
00034 import java.awt.Color;
00035 import java.awt.GradientPaint;
00036 import java.awt.Graphics2D;
00037 import java.awt.Paint;
00038 import java.awt.geom.Rectangle2D;
00039 import java.awt.geom.RoundRectangle2D;
00040 import java.awt.image.BufferedImage;
00041 import java.io.File;
00042 import java.io.IOException;
00043 import java.util.List;
00044 
00045 import javax.imageio.ImageIO;
00046 
00047 import org.jdom.Element;
00048 import org.jfree.chart.ChartFactory;
00049 import org.jfree.chart.JFreeChart;
00050 import org.jfree.chart.axis.AxisLocation;
00051 import org.jfree.chart.axis.AxisState;
00052 import org.jfree.chart.axis.NumberAxis;
00053 import org.jfree.chart.axis.NumberTick;
00054 import org.jfree.chart.axis.NumberTickUnit;
00055 import org.jfree.chart.axis.ValueAxis;
00056 import org.jfree.chart.plot.CrosshairState;
00057 import org.jfree.chart.plot.PlotOrientation;
00058 import org.jfree.chart.plot.PlotRenderingInfo;
00059 import org.jfree.chart.plot.XYPlot;
00060 import org.jfree.chart.renderer.xy.StandardXYItemRenderer;
00061 import org.jfree.chart.renderer.xy.XYItemRendererState;
00062 import org.jfree.chart.title.TextTitle;
00063 import org.jfree.data.xy.MatrixSeriesCollection;
00064 import org.jfree.data.xy.NormalizedMatrixSeries;
00065 import org.jfree.data.xy.XYDataset;
00066 import org.jfree.ui.RectangleEdge;
00067 import org.objectweb.proactive.benchmarks.timit.TimIt;
00068 import org.objectweb.proactive.benchmarks.timit.config.ConfigChart;
00069 import org.objectweb.proactive.benchmarks.timit.util.BenchmarkStatistics;
00070 
00077 public class MatrixChart implements Chart {
00078 
00082     private static final long serialVersionUID = -9045078395503131290L;
00083 
00084     public static final String logoFile = org.objectweb.proactive.benchmarks.timit.config.ConfigReader.PROJECT_PATH+"/src/org/objectweb/proactive/benchmarks/timit/pics/TimItProActive.png";
00085 
00086     private Chart.LegendFormat legendFormatMode;
00087 
00088     private Chart.Scale scaleMode;
00089 
00091     private int[][] array;
00092 
00094     private int[] legendValues;
00095 
00097     private int maxValue;
00098 
00100     private JFreeChart mainChart;
00101 
00103     private JFreeChart legendChart;    
00104 
00105     public void generateChart(Element eTimit, BenchmarkStatistics bstats,
00106             ConfigChart cChart) {                       
00107         
00108         String name = cChart.get("eventName");
00109         int[][] a = (int[][]) bstats.getEventsStatistics().getEventDataValue(
00110                 name);
00111         this.array = (a == null ? MatrixChart.build2DArray(16) : a);
00112         this.maxValue = MatrixChart.getMaxValue(this.array);
00113         this.scaleMode =
00114             ConfigChart.scaleValue(cChart.get("scaleMode"));
00115         this.legendFormatMode =
00116             ConfigChart.legendValue(cChart.get("legendFormatMode"));
00117 
00118         if (this.scaleMode == Chart.Scale.DEFAULT) {
00119             this.scaleMode = Chart.Scale.LOGARITHMIC;
00120         }
00121         if (this.legendFormatMode == Chart.LegendFormat.DEFAULT) {
00122             this.legendFormatMode = Chart.LegendFormat.POW2;
00123         }
00124 
00125         this.buildFinalChart(cChart);
00126     }
00127 
00135     private static int[][] build2DArray(int size) {
00136         int[][] res = new int[size][size];
00137 
00138         for (int i = 0; i < res.length; i++) {
00139             for (int j = 0; j < res.length; j++) {
00140                 res[i][j] = i * 100000;
00141             }
00142         }
00143         return res;
00144     }
00145 
00146     private static int getMaxValue(int[][] a) {
00147         int i, j, max = 0;
00148 
00149         for (i = 0; i < a.length; i++) {
00150             for (j = 0; j < a.length; j++) {
00151                 if (a[i][j] > max) {
00152                     max = a[i][j];
00153                 }
00154             }
00155         }
00156         return max;
00157     }
00158 
00159     private void buildMainChart(String title, String subTitle,
00160             String xAxisLabel, String yAxisLabel, String fileName) {
00161 
00162         final MatrixSeriesCollection dataset = new MatrixSeriesCollection(this
00163                 .createMatrixDataSet());
00164 
00165         final JFreeChart chart = ChartFactory.createBubbleChart(title,
00166                 xAxisLabel, yAxisLabel, dataset, PlotOrientation.VERTICAL,
00167                 true, true, false);
00168 
00169         chart.addSubtitle(new TextTitle(subTitle));
00170         chart.setBackgroundPaint(new GradientPaint(0, 0, Color.white, 0, 1000,
00171                 Color.WHITE));
00172         chart.removeLegend();
00173 
00174         // Perform customizations starts here ...
00175         final XYPlot plot1 = chart.getXYPlot();
00176 
00177         plot1.setDomainGridlinesVisible(false);
00178         plot1.setRangeGridlinesVisible(false);
00179         plot1.setForegroundAlpha(0.5f);
00180         plot1.setDomainAxis(new CustomAxis(plot1.getDomainAxis().getLabel()));
00181         plot1.setRangeAxis(new CustomAxis(plot1.getRangeAxis().getLabel()));
00182 
00183         // Custumize the domain axis ( y )
00184         final NumberAxis domainAxis = (NumberAxis) plot1.getDomainAxis();
00185         domainAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
00186         domainAxis.setRange(-1, this.array.length);
00187 
00188         // Custumize the range axis ( y )
00189         final NumberAxis rangeAxis = (NumberAxis) plot1.getRangeAxis();
00190         rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
00191         rangeAxis.setRange(-1, this.array.length);
00192 
00193         // Create custom renderer
00194         StandardXYItemRenderer ren = new CustomRenderer(false);
00195         ren.setSeriesItemLabelPaint(0, Color.BLACK);
00196         plot1.setRenderer(ren);
00197         this.mainChart = chart;
00198     }
00199 
00200     private void buildLegendChart(int nbValues) {
00201 
00202         this.legendValues = new int[nbValues + 1];
00203         this.legendValues[0] = 0;
00204         int offset = 255 / nbValues;
00205         int step = offset;
00206 
00207         if (this.scaleMode == Chart.Scale.LOGARITHMIC) {
00208             double logStep = (Math.log(this.maxValue) / Math.log(2)) / nbValues;
00209             for (int i = 1; i < nbValues + 1; i++) {
00210                 this.legendValues[i] = (int) Math.pow(2, logStep * i);
00211             }
00212         } else { // Linear scale mode
00213             for (int i = 1; i < nbValues + 1; i++) {
00214                 this.legendValues[i] = (step * this.maxValue) / 255;
00215                 step += offset;
00216             }
00217         }
00218 
00219         final MatrixSeriesCollection dataset = new MatrixSeriesCollection(this
00220                 .createLegendDataSet());
00221 
00222         final JFreeChart chart = ChartFactory.createBubbleChart("", "", "",
00223                 dataset, PlotOrientation.VERTICAL, true, true, false);
00224 
00225         chart.setBackgroundPaint(new GradientPaint(0, 0, Color.white, 0, 1000,
00226                 Color.WHITE));
00227         chart.removeLegend();
00228 
00229         // Perform customizations starts here ...
00230         final XYPlot plot1 = chart.getXYPlot();
00231 
00232         plot1.setDomainGridlinesVisible(false);
00233         plot1.setRangeGridlinesVisible(false);
00234         plot1.setForegroundAlpha(0.5f);
00235         plot1.setDomainAxis(new CustomAxis(plot1.getDomainAxis().getLabel()));
00236         plot1.setRangeAxis(new CustomAxis(plot1.getRangeAxis().getLabel()));
00237 
00238         // Custumize the domain axis ( x )
00239         final NumberAxis domainAxis = (NumberAxis) plot1.getDomainAxis();
00240         domainAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
00241         domainAxis.setRange(-1, 1);
00242         domainAxis.setVisible(false);
00243 
00244         // Custumize the range axis ( y )
00245         final NumberAxis rangeAxis = (NumberAxis) plot1.getRangeAxis();
00246         rangeAxis.setTickUnit(new CustomTickUnit(rangeAxis.getTickUnit()
00247                 .getSize()));
00248         rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
00249         rangeAxis.setRange(-1, this.legendValues.length);
00250         rangeAxis.setTickLabelsVisible(true);
00251         rangeAxis.setTickMarkInsideLength(4);
00252 
00253         // Create custom renderer
00254         StandardXYItemRenderer ren = new CustomRenderer(true);
00255         ren.setSeriesItemLabelPaint(0, Color.BLUE);
00256         plot1.setRenderer(ren);
00257         plot1.setRangeAxisLocation(AxisLocation.TOP_OR_RIGHT);
00258 
00259         this.legendChart = chart;
00260     }
00261 
00262     private void buildFinalChart(ConfigChart cChart) {
00263         this.buildFinalChart(cChart.get("title"), cChart.get("subTitle"),
00264                 cChart.get("filename"), cChart.get("xAxisLabel"), cChart
00265                         .get("yAxisLabel"), Integer
00266                         .valueOf(cChart.get("width")), Integer.valueOf(cChart
00267                         .get("height")));
00268     }
00269 
00270     private void buildFinalChart(String title, String subTitle,
00271             String filename, String xAxisLabel, String yAxisLabel, int width,
00272             int height) {
00273 
00274         this.buildMainChart(title, subTitle, xAxisLabel, yAxisLabel, filename);
00275 
00276         this.buildLegendChart(5);
00277 
00278         BufferedImage mainChartImage = this.mainChart.createBufferedImage(
00279                 width, height);
00280         BufferedImage legendChartImage = this.legendChart.createBufferedImage(
00281                 width / 6, height / 3);
00282         BufferedImage info = null;
00283         try {
00284             info = ImageIO.read(new File(MatrixChart.logoFile));
00285         } catch (IOException ex) {
00286         }
00287 
00288         BufferedImage total = new BufferedImage(width + (width / 6), height,
00289                 BufferedImage.TYPE_INT_RGB);
00290         Graphics2D g = total.createGraphics();
00291 
00292         g.drawImage(mainChartImage, 0, 0, null);
00293         g.drawImage(legendChartImage, width, height / 4, null);
00294         g.setPaint(Color.WHITE);
00295         g.fillRect(width, 0, width, height / 4);
00296         g.fillRect(width, height / 4 + height / 3, width, height);
00297         if (info != null) {
00298             // g.drawImage(info, (width+(width/6))-info.getWidth(),10, null); //
00299             // up-right
00300             g.drawImage(info, (width + (width / 6)) - info.getWidth(), height
00301                     - info.getHeight(), null); // down-right
00302         }
00303         g.dispose();
00304 
00305         try {
00306             javax.imageio.ImageIO.write(total, "png", new java.io.File(filename
00307                     + ".png"));
00308         } catch (IOException ex) {
00309             ex.printStackTrace();
00310         }
00311     }
00312 
00316     private NormalizedMatrixSeries createMatrixDataSet() {
00317 
00318         NormalizedMatrixSeries matrix = new NormalizedMatrixSeries("s",
00319                 this.array.length, this.array.length);
00320         // for (int i = 0; i<array.length; i++){
00321         // for(int j = 0; j<array[i].length; j++){
00322         // matrix.update(i,j,array[i][j]);
00323         // }
00324         // }
00325         return matrix;
00326     }
00327 
00331     private NormalizedMatrixSeries createLegendDataSet() {
00332         NormalizedMatrixSeries matrix = new NormalizedMatrixSeries("Legend",
00333                 this.legendValues.length, 1);
00334 
00335         return matrix;
00336     }
00337 
00342     private class CustomRenderer extends StandardXYItemRenderer {
00343 
00347         private static final long serialVersionUID = -7987810288979911261L;
00348 
00350         private int currentRow = 0;
00351 
00353         private boolean legendMode = false;
00354 
00361         public CustomRenderer(boolean legendMode) {
00362             super();
00363             this.legendMode = legendMode;
00364         }
00365 
00377         public Paint getItemPaint(final int series, final int item) {
00378             int value = 0;
00379             if (this.legendMode) {
00380                 if (MatrixChart.this.scaleMode == Chart.Scale.LOGARITHMIC) {
00381                     value = (255 / (MatrixChart.this.legendValues.length - 1))
00382                             * item;
00383                 } else {
00384                     value = (MatrixChart.this.legendValues[item] * 255)
00385                             / (MatrixChart.this.maxValue == 0 ? 1
00386                                     : MatrixChart.this.maxValue);
00387                 }
00388             } else {
00389                 if (item != 0 && item % MatrixChart.this.array.length == 0) {
00390                     this.currentRow++;
00391                 }
00392                 value = (int) ((MatrixChart.this.array[this.currentRow][item
00393                         % MatrixChart.this.array.length] / (MatrixChart.this.maxValue + 0.01)) * 255);
00394 
00395                 if (MatrixChart.this.scaleMode == Chart.Scale.LOGARITHMIC) {
00396                     value = (int) (((Math.log((value == 255 ? 255 : value + 1)) / Math
00397                             .log(2)) / (Math.log(255) / Math.log(2))) * 255);
00398                 }
00399             }
00400 
00401             return new Color(0, 0,
00402                     (int) (255 - Math.pow(value / 255.0, 6) * 80), value);
00403         }
00404 
00435         public void drawItem(Graphics2D g2, XYItemRendererState state,
00436                 Rectangle2D dataArea, PlotRenderingInfo info, XYPlot plot,
00437                 ValueAxis domainAxis, ValueAxis rangeAxis, XYDataset dataset,
00438                 int series, int item, CrosshairState crosshairState, int pass) {
00439 
00440             PlotOrientation orientation = plot.getOrientation();
00441 
00442             // get the data point...
00443             double x = dataset.getXValue(series, item);
00444             double y = dataset.getYValue(series, item);
00445             double z = 0.97d;
00446 
00447             RectangleEdge domainAxisLocation = plot.getDomainAxisEdge();
00448             RectangleEdge rangeAxisLocation = plot.getRangeAxisEdge();
00449             double transX = domainAxis.valueToJava2D(x, dataArea,
00450                     domainAxisLocation);
00451             double transY = rangeAxis.valueToJava2D(y, dataArea,
00452                     rangeAxisLocation);
00453 
00454             double transDomain = 0.0;
00455             double transRange = 0.0;
00456 
00457             double zero1 = domainAxis.valueToJava2D(0.0, dataArea,
00458                     domainAxisLocation);
00459             double zero2 = rangeAxis.valueToJava2D(0.0, dataArea,
00460                     rangeAxisLocation);
00461             transDomain = domainAxis.valueToJava2D(z, dataArea,
00462                     domainAxisLocation)
00463                     - zero1;
00464             transRange = zero2
00465                     - rangeAxis.valueToJava2D(z, dataArea, rangeAxisLocation);
00466 
00467             transDomain = Math.abs(transDomain);
00468             transRange = Math.abs(transRange);
00469 
00470             RoundRectangle2D.Double rect = new RoundRectangle2D.Double(transX
00471                     - transDomain / 2.0, transY - transRange / 2.0,
00472                     transDomain, transRange, 10, 10);
00473 
00474             g2.setPaint(this.getItemPaint(series, item));
00475             g2.fill(rect);
00476             g2.setStroke(new BasicStroke(1.0f));
00477             g2.setPaint(Color.LIGHT_GRAY);
00478             g2.draw(rect);
00479 
00480             this.updateCrosshairValues(crosshairState, x, y, transX, transY,
00481                     orientation);
00482         }
00483     }
00484 
00485     private static class CustomAxis extends NumberAxis {
00489         private static final long serialVersionUID = -1624475755178533032L;
00490 
00491         public CustomAxis(String labelName) {
00492             super(labelName);
00493         }
00494 
00511         public List<NumberTick> refreshTicks(Graphics2D g2, AxisState state,
00512                 Rectangle2D dataArea, RectangleEdge edge) {
00513 
00514             List<NumberTick> result = new java.util.ArrayList<NumberTick>();
00515             if (RectangleEdge.isTopOrBottom(edge)) {
00516                 result = this.refreshTicksHorizontal(g2, dataArea, edge);
00517             } else if (RectangleEdge.isLeftOrRight(edge)) {
00518                 result = this.refreshTicksVertical(g2, dataArea, edge);
00519             }
00520 
00521             int size = result.size();
00522             NumberTick first = result.get(0);
00523             NumberTick last = result.get(size - 1);
00524 
00525             NumberTick newFirst = new NumberTick(0, "", first.getTextAnchor(),
00526                     first.getRotationAnchor(), first.getAngle());
00527 
00528             NumberTick newLast = new NumberTick(0, "", last.getTextAnchor(),
00529                     last.getRotationAnchor(), last.getAngle());
00530 
00531             result.set(0, newFirst);
00532             result.set(size - 1, newLast);
00533             return result;
00534 
00535         }
00536     }
00537 
00538     private class CustomTickUnit extends NumberTickUnit {
00539 
00543         private static final long serialVersionUID = -6476772736783076413L;
00544 
00545         public CustomTickUnit(double size) {
00546             super(size);
00547         }
00548 
00557         public String valueToString(double value) {
00558             if( MatrixChart.this.legendFormatMode
00559                     == Chart.LegendFormat.POW10 ) {
00560                 return (value >= 0
00561                         && value < MatrixChart.this.legendValues.length ? ""
00562                                 + MatrixChart.formatDataSize(
00563                                         MatrixChart.this.legendValues[(int) value],
00564                                         1000) : "");
00565             } else if( MatrixChart.this.legendFormatMode
00566                     == Chart.LegendFormat.POW2 ) {
00567                 return (value >= 0
00568                         && value < MatrixChart.this.legendValues.length ? ""
00569                                 + MatrixChart.formatDataSize(
00570                                         MatrixChart.this.legendValues[(int) value],
00571                                         1024) : "");
00572             } else {
00573                 return (value >= 0
00574                         && value < MatrixChart.this.legendValues.length ? ""
00575                                 + MatrixChart.this.legendValues[(int) value] : "");
00576             }
00577         }
00578     }
00579 
00580     private static String formatDataSize(int value, int base) {
00581         int selector = 0;
00582         double v = value;
00583         while (v > base) {
00584             selector++;
00585             v /= base;
00586         }
00587         switch (selector) {
00588         case 1:
00589             return "" + TimIt.df.format(v) + "K";
00590         case 2:
00591             return "" + TimIt.df.format(v) + "M";
00592         case 3:
00593             return "" + TimIt.df.format(v) + "G";
00594         case 4:
00595             return "" + TimIt.df.format(v) + "T";
00596         case 5:
00597             return "" + TimIt.df.format(v) + "P";
00598         default:
00599             return "" + value;
00600         }
00601     }
00602 }

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