1 55 56 package org.jfree.chart.renderer.category; 57 58 import java.awt.Color ; 59 import java.awt.Graphics2D ; 60 import java.awt.Paint ; 61 import java.awt.geom.Line2D ; 62 import java.awt.geom.Rectangle2D ; 63 import java.io.IOException ; 64 import java.io.ObjectInputStream ; 65 import java.io.ObjectOutputStream ; 66 import java.io.Serializable ; 67 68 import org.jfree.chart.axis.CategoryAxis; 69 import org.jfree.chart.axis.ValueAxis; 70 import org.jfree.chart.entity.EntityCollection; 71 import org.jfree.chart.event.RendererChangeEvent; 72 import org.jfree.chart.labels.CategoryItemLabelGenerator; 73 import org.jfree.chart.plot.CategoryPlot; 74 import org.jfree.chart.plot.PlotOrientation; 75 import org.jfree.data.category.CategoryDataset; 76 import org.jfree.data.statistics.StatisticalCategoryDataset; 77 import org.jfree.io.SerialUtilities; 78 import org.jfree.ui.RectangleEdge; 79 import org.jfree.util.PaintUtilities; 80 import org.jfree.util.PublicCloneable; 81 82 88 public class StatisticalBarRenderer extends BarRenderer 89 implements CategoryItemRenderer, 90 Cloneable , PublicCloneable, 91 Serializable { 92 93 94 private static final long serialVersionUID = -4986038395414039117L; 95 96 97 private transient Paint errorIndicatorPaint; 98 99 102 public StatisticalBarRenderer() { 103 super(); 104 this.errorIndicatorPaint = Color.gray; 105 } 106 107 113 public Paint getErrorIndicatorPaint() { 114 return this.errorIndicatorPaint; 115 } 116 117 123 public void setErrorIndicatorPaint(Paint paint) { 124 this.errorIndicatorPaint = paint; 125 notifyListeners(new RendererChangeEvent(this)); 126 } 127 128 143 public void drawItem(Graphics2D g2, 144 CategoryItemRendererState state, 145 Rectangle2D dataArea, 146 CategoryPlot plot, 147 CategoryAxis domainAxis, 148 ValueAxis rangeAxis, 149 CategoryDataset data, 150 int row, 151 int column, 152 int pass) { 153 154 if (!(data instanceof StatisticalCategoryDataset)) { 156 throw new IllegalArgumentException ( 157 "Requires StatisticalCategoryDataset."); 158 } 159 StatisticalCategoryDataset statData = (StatisticalCategoryDataset) data; 160 161 PlotOrientation orientation = plot.getOrientation(); 162 if (orientation == PlotOrientation.HORIZONTAL) { 163 drawHorizontalItem(g2, state, dataArea, plot, domainAxis, 164 rangeAxis, statData, row, column); 165 } 166 else if (orientation == PlotOrientation.VERTICAL) { 167 drawVerticalItem(g2, state, dataArea, plot, domainAxis, rangeAxis, 168 statData, row, column); 169 } 170 } 171 172 185 protected void drawHorizontalItem(Graphics2D g2, 186 CategoryItemRendererState state, 187 Rectangle2D dataArea, 188 CategoryPlot plot, 189 CategoryAxis domainAxis, 190 ValueAxis rangeAxis, 191 StatisticalCategoryDataset dataset, 192 int row, 193 int column) { 194 195 RectangleEdge xAxisLocation = plot.getDomainAxisEdge(); 196 197 double rectY = domainAxis.getCategoryStart(column, getColumnCount(), 199 dataArea, xAxisLocation); 200 201 int seriesCount = getRowCount(); 202 int categoryCount = getColumnCount(); 203 if (seriesCount > 1) { 204 double seriesGap = dataArea.getHeight() * getItemMargin() 205 / (categoryCount * (seriesCount - 1)); 206 rectY = rectY + row * (state.getBarWidth() + seriesGap); 207 } 208 else { 209 rectY = rectY + row * state.getBarWidth(); 210 } 211 212 Number meanValue = dataset.getMeanValue(row, column); 214 215 double value = meanValue.doubleValue(); 216 double base = 0.0; 217 double lclip = getLowerClip(); 218 double uclip = getUpperClip(); 219 220 if (uclip <= 0.0) { if (value >= uclip) { 222 return; } 224 base = uclip; 225 if (value <= lclip) { 226 value = lclip; 227 } 228 } 229 else if (lclip <= 0.0) { if (value >= uclip) { 231 value = uclip; 232 } 233 else { 234 if (value <= lclip) { 235 value = lclip; 236 } 237 } 238 } 239 else { if (value <= lclip) { 241 return; } 243 base = getLowerClip(); 244 if (value >= uclip) { 245 value = uclip; 246 } 247 } 248 249 RectangleEdge yAxisLocation = plot.getRangeAxisEdge(); 250 double transY1 = rangeAxis.valueToJava2D(base, dataArea, yAxisLocation); 251 double transY2 = rangeAxis.valueToJava2D(value, dataArea, 252 yAxisLocation); 253 double rectX = Math.min(transY2, transY1); 254 255 double rectHeight = state.getBarWidth(); 256 double rectWidth = Math.abs(transY2 - transY1); 257 258 Rectangle2D bar = new Rectangle2D.Double (rectX, rectY, rectWidth, 259 rectHeight); 260 Paint seriesPaint = getItemPaint(row, column); 261 g2.setPaint(seriesPaint); 262 g2.fill(bar); 263 if (state.getBarWidth() > 3) { 264 g2.setStroke(getItemStroke(row, column)); 265 g2.setPaint(getItemOutlinePaint(row, column)); 266 g2.draw(bar); 267 } 268 269 double valueDelta = dataset.getStdDevValue(row, column).doubleValue(); 271 double highVal = rangeAxis.valueToJava2D(meanValue.doubleValue() 272 + valueDelta, dataArea, yAxisLocation); 273 double lowVal = rangeAxis.valueToJava2D(meanValue.doubleValue() 274 - valueDelta, dataArea, yAxisLocation); 275 276 if (this.errorIndicatorPaint != null) { 277 g2.setPaint(this.errorIndicatorPaint); 278 } 279 else { 280 g2.setPaint(getItemOutlinePaint(row, column)); 281 } 282 Line2D line = null; 283 line = new Line2D.Double (lowVal, rectY + rectHeight / 2.0d, 284 highVal, rectY + rectHeight / 2.0d); 285 g2.draw(line); 286 line = new Line2D.Double (highVal, rectY + rectHeight * 0.25, 287 highVal, rectY + rectHeight * 0.75); 288 g2.draw(line); 289 line = new Line2D.Double (lowVal, rectY + rectHeight * 0.25, 290 lowVal, rectY + rectHeight * 0.75); 291 g2.draw(line); 292 293 CategoryItemLabelGenerator generator = getItemLabelGenerator(row, 294 column); 295 if (generator != null && isItemLabelVisible(row, column)) { 296 drawItemLabel(g2, dataset, row, column, plot, generator, bar, 297 (value < 0.0)); 298 } 299 300 EntityCollection entities = state.getEntityCollection(); 302 if (entities != null) { 303 addItemEntity(entities, dataset, row, column, bar); 304 } 305 306 } 307 308 321 protected void drawVerticalItem(Graphics2D g2, 322 CategoryItemRendererState state, 323 Rectangle2D dataArea, 324 CategoryPlot plot, 325 CategoryAxis domainAxis, 326 ValueAxis rangeAxis, 327 StatisticalCategoryDataset dataset, 328 int row, 329 int column) { 330 331 RectangleEdge xAxisLocation = plot.getDomainAxisEdge(); 332 333 double rectX = domainAxis.getCategoryStart( 335 column, getColumnCount(), dataArea, xAxisLocation 336 ); 337 338 int seriesCount = getRowCount(); 339 int categoryCount = getColumnCount(); 340 if (seriesCount > 1) { 341 double seriesGap = dataArea.getWidth() * getItemMargin() 342 / (categoryCount * (seriesCount - 1)); 343 rectX = rectX + row * (state.getBarWidth() + seriesGap); 344 } 345 else { 346 rectX = rectX + row * state.getBarWidth(); 347 } 348 349 Number meanValue = dataset.getMeanValue(row, column); 351 352 double value = meanValue.doubleValue(); 353 double base = 0.0; 354 double lclip = getLowerClip(); 355 double uclip = getUpperClip(); 356 357 if (uclip <= 0.0) { if (value >= uclip) { 359 return; } 361 base = uclip; 362 if (value <= lclip) { 363 value = lclip; 364 } 365 } 366 else if (lclip <= 0.0) { if (value >= uclip) { 368 value = uclip; 369 } 370 else { 371 if (value <= lclip) { 372 value = lclip; 373 } 374 } 375 } 376 else { if (value <= lclip) { 378 return; } 380 base = getLowerClip(); 381 if (value >= uclip) { 382 value = uclip; 383 } 384 } 385 386 RectangleEdge yAxisLocation = plot.getRangeAxisEdge(); 387 double transY1 = rangeAxis.valueToJava2D(base, dataArea, yAxisLocation); 388 double transY2 = rangeAxis.valueToJava2D(value, dataArea, 389 yAxisLocation); 390 double rectY = Math.min(transY2, transY1); 391 392 double rectWidth = state.getBarWidth(); 393 double rectHeight = Math.abs(transY2 - transY1); 394 395 Rectangle2D bar = new Rectangle2D.Double (rectX, rectY, rectWidth, 396 rectHeight); 397 Paint seriesPaint = getItemPaint(row, column); 398 g2.setPaint(seriesPaint); 399 g2.fill(bar); 400 if (state.getBarWidth() > 3) { 401 g2.setStroke(getItemStroke(row, column)); 402 g2.setPaint(getItemOutlinePaint(row, column)); 403 g2.draw(bar); 404 } 405 406 double valueDelta = dataset.getStdDevValue(row, column).doubleValue(); 408 double highVal = rangeAxis.valueToJava2D(meanValue.doubleValue() 409 + valueDelta, dataArea, yAxisLocation); 410 double lowVal = rangeAxis.valueToJava2D(meanValue.doubleValue() 411 - valueDelta, dataArea, yAxisLocation); 412 413 if (this.errorIndicatorPaint != null) { 414 g2.setPaint(this.errorIndicatorPaint); 415 } 416 else { 417 g2.setPaint(getItemOutlinePaint(row, column)); 418 } 419 Line2D line = null; 420 line = new Line2D.Double (rectX + rectWidth / 2.0d, lowVal, 421 rectX + rectWidth / 2.0d, highVal); 422 g2.draw(line); 423 line = new Line2D.Double (rectX + rectWidth / 2.0d - 5.0d, highVal, 424 rectX + rectWidth / 2.0d + 5.0d, highVal); 425 g2.draw(line); 426 line = new Line2D.Double (rectX + rectWidth / 2.0d - 5.0d, lowVal, 427 rectX + rectWidth / 2.0d + 5.0d, lowVal); 428 g2.draw(line); 429 430 CategoryItemLabelGenerator generator = getItemLabelGenerator(row, 431 column); 432 if (generator != null && isItemLabelVisible(row, column)) { 433 drawItemLabel(g2, dataset, row, column, plot, generator, bar, 434 (value < 0.0)); 435 } 436 437 EntityCollection entities = state.getEntityCollection(); 439 if (entities != null) { 440 addItemEntity(entities, dataset, row, column, bar); 441 } 442 } 443 444 451 public boolean equals(Object obj) { 452 if (obj == this) { 453 return true; 454 } 455 if (!(obj instanceof StatisticalBarRenderer)) { 456 return false; 457 } 458 if (!super.equals(obj)) { 459 return false; 460 } 461 StatisticalBarRenderer that = (StatisticalBarRenderer) obj; 462 if (!PaintUtilities.equal(this.errorIndicatorPaint, 463 that.errorIndicatorPaint)) { 464 return false; 465 } 466 return true; 467 } 468 469 476 private void writeObject(ObjectOutputStream stream) throws IOException { 477 stream.defaultWriteObject(); 478 SerialUtilities.writePaint(this.errorIndicatorPaint, stream); 479 } 480 481 489 private void readObject(ObjectInputStream stream) 490 throws IOException , ClassNotFoundException { 491 stream.defaultReadObject(); 492 this.errorIndicatorPaint = SerialUtilities.readPaint(stream); 493 } 494 495 } 496 | Popular Tags |