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.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
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
00184 final NumberAxis domainAxis = (NumberAxis) plot1.getDomainAxis();
00185 domainAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
00186 domainAxis.setRange(-1, this.array.length);
00187
00188
00189 final NumberAxis rangeAxis = (NumberAxis) plot1.getRangeAxis();
00190 rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
00191 rangeAxis.setRange(-1, this.array.length);
00192
00193
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 {
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
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
00239 final NumberAxis domainAxis = (NumberAxis) plot1.getDomainAxis();
00240 domainAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
00241 domainAxis.setRange(-1, 1);
00242 domainAxis.setVisible(false);
00243
00244
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
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
00299
00300 g.drawImage(info, (width + (width / 6)) - info.getWidth(), height
00301 - info.getHeight(), null);
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
00321
00322
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
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 }