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.renderer;
00032
00033 import java.awt.Color;
00034 import java.awt.GradientPaint;
00035 import java.awt.Graphics2D;
00036 import java.awt.Paint;
00037 import java.awt.Stroke;
00038 import java.awt.geom.Rectangle2D;
00039 import java.awt.geom.RoundRectangle2D;
00040 import java.util.Iterator;
00041
00042 import org.jdom.Element;
00043 import org.jfree.chart.axis.CategoryAxis;
00044 import org.jfree.chart.axis.ValueAxis;
00045 import org.jfree.chart.entity.CategoryItemEntity;
00046 import org.jfree.chart.entity.EntityCollection;
00047 import org.jfree.chart.labels.CategoryItemLabelGenerator;
00048 import org.jfree.chart.labels.CategoryToolTipGenerator;
00049 import org.jfree.chart.plot.CategoryPlot;
00050 import org.jfree.chart.renderer.category.BarRenderer;
00051 import org.jfree.chart.renderer.category.CategoryItemRendererState;
00052 import org.jfree.data.category.CategoryDataset;
00053 import org.jfree.ui.GradientPaintTransformer;
00054 import org.jfree.ui.RectangleEdge;
00055 import org.jfree.util.ObjectList;
00056
00063 public class HierarchicalBarRenderer extends BarRenderer {
00064
00068 private static final long serialVersionUID = -9139779432077336720L;
00069
00070 public static final int INCLUSION_MARGIN = 3;
00071
00072 public static final int CORNER = 2;
00073
00074 private int alpha;
00075
00077 protected ObjectList seriesBarWidthList;
00078
00079 protected Element[] datasetTree;
00080
00081 protected Comparable[] series;
00082
00086 public HierarchicalBarRenderer() {
00087 super();
00088 this.seriesBarWidthList = new ObjectList();
00089 this.alpha = 255;
00090 }
00091
00101 public double getSeriesBarWidth(int series) {
00102 double result = Double.NaN;
00103 Number n = (Number) this.seriesBarWidthList.get(series);
00104 if (n != null) {
00105 result = n.doubleValue();
00106 }
00107 return result;
00108 }
00109
00119 public void setSeriesBarWidth(int series, double width) {
00120 this.seriesBarWidthList.set(series, new Double(width));
00121 }
00122
00123 public Element[] getDatasetTree() {
00124 return this.datasetTree.clone();
00125 }
00126
00127 public void setDatasetTree(Element[] datasetTree) {
00128 this.datasetTree = datasetTree.clone();
00129
00130
00131
00132 for (int i = 0; i < datasetTree.length; i++) {
00133 Iterator it = this.datasetTree[i].getDescendants();
00134 while (it.hasNext()) {
00135 try {
00136 ((Element) it.next()).setAttribute("max", "0");
00137 } catch (ClassCastException e) {
00138 continue;
00139 }
00140 }
00141 }
00142 }
00143
00144 public void setSeries(Comparable[] series) {
00145 this.series = series.clone();
00146 }
00147
00148 public void setAlpha(int alpha) {
00149 this.alpha = alpha;
00150 }
00151
00164 protected void calculateBarWidth(CategoryPlot plot, Rectangle2D dataArea,
00165 int rendererIndex, CategoryItemRendererState state) {
00166
00167
00168
00169
00170
00171 CategoryAxis domainAxis = this.getDomainAxis(plot, rendererIndex);
00172 CategoryDataset dataset = plot.getDataset(rendererIndex);
00173 if (dataset != null) {
00174 int columns = dataset.getColumnCount();
00175 int rows = dataset.getRowCount();
00176 double space = dataArea.getWidth();
00177 double maxWidth = space * this.getMaximumBarWidth();
00178 double categoryMargin = 0.0;
00179 if (columns > 1) {
00180 categoryMargin = domainAxis.getCategoryMargin();
00181 }
00182 double used = space
00183 * (1 - domainAxis.getLowerMargin()
00184 - domainAxis.getUpperMargin() - categoryMargin);
00185 if ((rows * columns) > 0) {
00186 state.setBarWidth(Math.min(used / (dataset.getColumnCount()),
00187 maxWidth));
00188 } else {
00189 state.setBarWidth(Math.min(used, maxWidth));
00190 }
00191 }
00192 }
00193
00218 public void drawItem(Graphics2D g2, CategoryItemRendererState state,
00219 Rectangle2D dataArea, CategoryPlot plot, CategoryAxis domainAxis,
00220 ValueAxis rangeAxis, CategoryDataset data, int row, int column,
00221 int pass) {
00222
00223 Number dataValue = data.getValue(row, column);
00224 if (dataValue == null) {
00225 return;
00226 }
00227
00228
00229 double rectX = domainAxis.getCategoryMiddle(column, this
00230 .getColumnCount(), dataArea, plot.getDomainAxisEdge())
00231 - state.getBarWidth() / 2.0;
00232
00233 int seriesCount = this.getRowCount();
00234
00235
00236 double value = dataValue.doubleValue();
00237 double base = 0.0;
00238 double lclip = this.getLowerClip();
00239 double uclip = this.getUpperClip();
00240
00241 if (uclip <= 0.0) {
00242 if (value >= uclip) {
00243 return;
00244 }
00245 base = uclip;
00246 if (value <= lclip) {
00247 value = lclip;
00248 }
00249 } else if (lclip <= 0.0) {
00250 if (value >= uclip) {
00251 value = uclip;
00252 } else {
00253 if (value <= lclip) {
00254 value = lclip;
00255 }
00256 }
00257 } else {
00258 if (value <= lclip) {
00259 return;
00260 }
00261 base = this.getLowerClip();
00262 if (value >= uclip) {
00263 value = uclip;
00264 }
00265 }
00266
00267 RectangleEdge edge = plot.getRangeAxisEdge();
00268 double transY1 = rangeAxis.valueToJava2D(base, dataArea, edge);
00269 double transY2 = rangeAxis.valueToJava2D(value, dataArea, edge);
00270 double rectY = Math.min(transY2, transY1);
00271
00272 double rectWidth = state.getBarWidth();
00273 double rectHeight = Math.abs(transY2 - transY1);
00274
00275
00276 double shift = 0.0;
00277 rectWidth = 0.0;
00278 double widthFactor = 1.0;
00279 double seriesBarWidth = this.getSeriesBarWidth(row);
00280 if (!Double.isNaN(seriesBarWidth)) {
00281 widthFactor = seriesBarWidth;
00282 }
00283 rectWidth = widthFactor * state.getBarWidth();
00284 rectX = rectX + (1 - widthFactor) * state.getBarWidth() / 2.0;
00285 if (seriesCount > 1) {
00286
00287 shift = rectWidth * 0.20 / (seriesCount - 1);
00288 }
00289
00290 Rectangle2D bar = new Rectangle2D.Double(
00291 (rectX + ((seriesCount - 1 - row) * shift)), rectY,
00292 (rectWidth - (seriesCount - 1 - row) * shift * 2), rectHeight);
00293
00294 double rrX, rrY, rrW, rrH;
00295 if (row == 0) {
00296 Iterator it = this.datasetTree[column].getDescendants();
00297 int numElement = -1;
00298 while (it.hasNext()) {
00299 try {
00300 Element elt = (Element) it.next();
00301 numElement++;
00302 String name = elt.getAttributeValue("name");
00303 dataValue = Double.valueOf(elt.getAttributeValue("avg"));
00304
00305
00306
00307 rectX = domainAxis.getCategoryMiddle(column, this
00308 .getColumnCount(), dataArea, plot
00309 .getDomainAxisEdge())
00310 - state.getBarWidth() / 2.0;
00311
00312 seriesCount = this.getRowCount();
00313
00314
00315 value = dataValue.doubleValue();
00316 base = 0.0;
00317 lclip = this.getLowerClip();
00318 uclip = this.getUpperClip();
00319
00320 if (uclip <= 0.0) {
00321 if (value >= uclip) {
00322 return;
00323 }
00324 base = uclip;
00325 if (value <= lclip) {
00326 value = lclip;
00327 }
00328 } else if (lclip <= 0.0) {
00329 if (value >= uclip) {
00330 value = uclip;
00331 } else {
00332 if (value <= lclip) {
00333 value = lclip;
00334 }
00335 }
00336 } else {
00337 if (value <= lclip) {
00338 return;
00339 }
00340 base = this.getLowerClip();
00341 if (value >= uclip) {
00342 value = uclip;
00343 }
00344 }
00345
00346 edge = plot.getRangeAxisEdge();
00347 transY1 = rangeAxis.valueToJava2D(base, dataArea, edge);
00348 transY2 = rangeAxis.valueToJava2D(value, dataArea, edge);
00349 rectY = Math.min(transY2, transY1);
00350
00351 rectWidth = state.getBarWidth();
00352 rectHeight = Math.abs(transY2 - transY1);
00353
00354
00355 shift = 0.0;
00356 rectWidth = 0.0;
00357 widthFactor = 1.0;
00358 seriesBarWidth = this.getSeriesBarWidth(row);
00359 if (!Double.isNaN(seriesBarWidth)) {
00360 widthFactor = seriesBarWidth;
00361 }
00362 rectWidth = widthFactor * state.getBarWidth();
00363 rectX = rectX + (1 - widthFactor) * state.getBarWidth()
00364 / 2.0;
00365 if (seriesCount > 1) {
00366
00367 shift = rectWidth * 0.20 / (seriesCount - 1);
00368 }
00369 rrX = (rectX + ((seriesCount - 1 - row) * shift));
00370 rrY = rectY;
00371 rrW = (rectWidth - (seriesCount - 1 - row) * shift * 2);
00372 rrH = rectHeight;
00373
00374
00375
00376
00377
00378
00379 if (numElement == 0) {
00380 elt.setAttribute("dev", "" + rrW);
00381 elt.setAttribute("min", "" + rrX);
00382 elt.setAttribute("max", "0");
00383 } else {
00384 Element parent = elt.getParentElement();
00385
00386
00387
00388
00389
00390
00391 double pW = Double.valueOf(parent
00392 .getAttributeValue("dev"));
00393 double pX = Double.valueOf(parent
00394 .getAttributeValue("min"));
00395 int numChild = Integer.valueOf(parent
00396 .getAttributeValue("max"));
00397
00398 rrW = pW / parent.getChildren().size();
00399 rrX = pX + rrW * numChild;
00400 rrX += HierarchicalBarRenderer.INCLUSION_MARGIN;
00401 rrW -= HierarchicalBarRenderer.INCLUSION_MARGIN * 2;
00402 elt.setAttribute("dev", "" + rrW);
00403 elt.setAttribute("min", "" + rrX);
00404 parent.setAttribute("max", "" + (numChild + 1));
00405 }
00406
00407 RoundRectangle2D rbar = new RoundRectangle2D.Double(rrX,
00408 rrY, rrW, rrH, HierarchicalBarRenderer.CORNER,
00409 HierarchicalBarRenderer.CORNER);
00410
00411 Rectangle2D childSumLine = null;
00412 double childSum = Double.valueOf(elt
00413 .getAttributeValue("sum"));
00414 transY1 = rangeAxis.valueToJava2D(base, dataArea, edge);
00415 transY2 = rangeAxis.valueToJava2D(childSum, dataArea, edge);
00416 rectY = Math.min(transY2, transY1);
00417
00418 childSum = (childSum / dataValue.doubleValue()) * rrH;
00419 if (childSum < rrH && childSum > 0 && childSum / rrH < 0.95) {
00420 childSumLine = new Rectangle2D.Double(rrX, rectY, rrW,
00421 1);
00422 }
00423 Paint itemPaint = this.getItemPaintFromName(name,
00424 this.series, column);
00425 GradientPaintTransformer t = this
00426 .getGradientPaintTransformer();
00427 if (t != null && itemPaint instanceof GradientPaint) {
00428 itemPaint = t.transform((GradientPaint) itemPaint, bar);
00429 }
00430 g2.setPaint(itemPaint);
00431
00432 Color c = g2.getColor();
00433 g2.setColor(new Color(c.getRed(), c.getGreen(),
00434 c.getBlue(), this.alpha));
00435 g2.fill(rbar);
00436 g2.setColor(Color.DARK_GRAY);
00437 if (childSumLine != null) {
00438 g2.fill(childSumLine);
00439 }
00440
00441
00442 if (this.isDrawBarOutline()
00443 && state.getBarWidth() > BarRenderer.BAR_OUTLINE_WIDTH_THRESHOLD) {
00444 Stroke stroke = this.getItemOutlineStroke(row, column);
00445 Paint paint = this.getItemOutlinePaint(row, column);
00446 if (stroke != null && paint != null) {
00447 g2.setStroke(stroke);
00448 g2.setPaint(paint);
00449 g2.draw(rbar);
00450 }
00451 }
00452 } catch (ClassCastException e) {
00453 continue;
00454 }
00455 }
00456 }
00457
00458
00459
00460 double transX1 = rangeAxis.valueToJava2D(base, dataArea, edge);
00461 double transX2 = rangeAxis.valueToJava2D(value, dataArea, edge);
00462
00463 CategoryItemLabelGenerator generator = this.getItemLabelGenerator(row,
00464 column);
00465 if (generator != null && this.isItemLabelVisible(row, column)) {
00466 this.drawItemLabel(g2, data, row, column, plot, generator, bar,
00467 (transX1 > transX2));
00468 }
00469
00470
00471 if (state.getInfo() != null) {
00472 EntityCollection entities = state.getEntityCollection();
00473 if (entities != null) {
00474 String tip = null;
00475 CategoryToolTipGenerator tipster = this.getToolTipGenerator(
00476 row, column);
00477 if (tipster != null) {
00478 tip = tipster.generateToolTip(data, row, column);
00479 }
00480 String url = null;
00481 if (this.getItemURLGenerator(row, column) != null) {
00482 url = this.getItemURLGenerator(row, column).generateURL(
00483 data, row, column);
00484 }
00485 CategoryItemEntity entity = new CategoryItemEntity(bar, tip,
00486 url, data, row, data.getColumnKey(column), column);
00487 entities.add(entity);
00488 }
00489 }
00490 }
00491
00492 private Paint getItemPaintFromName(String name, Comparable[] series,
00493 int column) {
00494 for (int i = 0; i < series.length; i++) {
00495 if (series[i].equals(name)) {
00496 return this.getItemPaint(i, column);
00497 }
00498 }
00499 return null;
00500 }
00501 }