1 39 40 package org.jfree.chart.renderer; 41 42 import java.awt.Color ; 43 import java.awt.GradientPaint ; 44 import java.awt.Graphics2D ; 45 import java.awt.Paint ; 46 import java.awt.Stroke ; 47 import java.awt.geom.Rectangle2D ; 48 import java.io.IOException ; 49 import java.io.ObjectInputStream ; 50 import java.io.ObjectOutputStream ; 51 import java.io.Serializable ; 52 53 import org.jfree.chart.axis.CategoryAxis; 54 import org.jfree.chart.axis.ValueAxis; 55 import org.jfree.chart.entity.CategoryItemEntity; 56 import org.jfree.chart.entity.EntityCollection; 57 import org.jfree.chart.labels.CategoryItemLabelGenerator; 58 import org.jfree.chart.plot.CategoryPlot; 59 import org.jfree.chart.plot.PlotOrientation; 60 import org.jfree.data.CategoryDataset; 61 import org.jfree.io.SerialUtilities; 62 import org.jfree.ui.GradientPaintTransformType; 63 import org.jfree.ui.RectangleEdge; 64 import org.jfree.ui.StandardGradientPaintTransformer; 65 import org.jfree.util.PaintUtils; 66 import org.jfree.util.PublicCloneable; 67 68 72 public class WaterfallBarRenderer extends BarRenderer 73 implements Cloneable , PublicCloneable, Serializable { 74 75 76 private transient Paint firstBarPaint; 77 78 79 private transient Paint lastBarPaint; 80 81 82 private transient Paint positiveBarPaint; 83 84 85 private transient Paint negativeBarPaint; 86 87 90 public WaterfallBarRenderer() { 91 this(new GradientPaint (0.0f, 0.0f, new Color (0x22, 0x22, 0xFF), 92 0.0f, 0.0f, new Color (0x66, 0x66, 0xFF)), 93 new GradientPaint (0.0f, 0.0f, new Color (0x22, 0xFF, 0x22), 94 0.0f, 0.0f, new Color (0x66, 0xFF, 0x66)), 95 new GradientPaint (0.0f, 0.0f, new Color (0xFF, 0x22, 0x22), 96 0.0f, 0.0f, new Color (0xFF, 0x66, 0x66)), 97 new GradientPaint (0.0f, 0.0f, new Color (0xFF, 0xFF, 0x22), 98 0.0f, 0.0f, new Color (0xFF, 0xFF, 0x66))); 99 } 100 101 109 public WaterfallBarRenderer(Paint firstBarPaint, 110 Paint positiveBarPaint, 111 Paint negativeBarPaint, 112 Paint lastBarPaint) { 113 super(); 114 this.firstBarPaint = firstBarPaint; 115 this.lastBarPaint = lastBarPaint; 116 this.positiveBarPaint = positiveBarPaint; 117 this.negativeBarPaint = negativeBarPaint; 118 setGradientPaintTransformer( 119 new StandardGradientPaintTransformer(GradientPaintTransformType.CENTER_VERTICAL)); 120 setMinimumBarLength(1.0); 121 } 122 123 128 public RangeType getRangeType() { 129 return RangeType.SERIES_CUMULATIVE; 130 } 131 132 137 public Paint getFirstBarPaint() { 138 return this.firstBarPaint; 139 } 140 141 146 public void setFirstBarPaint(Paint paint) { 147 this.firstBarPaint = paint; 148 } 149 150 155 public Paint getLastBarPaint() { 156 return this.lastBarPaint; 157 } 158 159 164 public void setLastBarPaint(Paint paint) { 165 this.lastBarPaint = paint; 166 } 167 168 173 public Paint getPositiveBarPaint() { 174 return this.positiveBarPaint; 175 } 176 177 182 public void setPositiveBarPaint(Paint paint) { 183 this.positiveBarPaint = paint; 184 } 185 186 191 public Paint getNegativeBarPaint() { 192 return this.negativeBarPaint; 193 } 194 195 200 public void setNegativeBarPaint(Paint paint) { 201 this.negativeBarPaint = paint; 202 } 203 204 217 public void drawItem(Graphics2D g2, 218 CategoryItemRendererState state, 219 Rectangle2D dataArea, 220 CategoryPlot plot, 221 CategoryAxis domainAxis, 222 ValueAxis rangeAxis, 223 CategoryDataset dataset, 224 int row, 225 int column) { 226 227 double previous = state.getSeriesRunningTotal(); 228 if (column == dataset.getColumnCount() - 1) { 229 previous = 0.0; 230 } 231 double current = 0.0; 232 Number n = dataset.getValue(row, column); 233 if (n != null) { 234 current = previous + n.doubleValue(); 235 } 236 state.setSeriesRunningTotal(current); 237 238 int seriesCount = getRowCount(); 239 int categoryCount = getColumnCount(); 240 PlotOrientation orientation = plot.getOrientation(); 241 242 double rectX = 0.0; 243 double rectY = 0.0; 244 245 RectangleEdge domainAxisLocation = plot.getDomainAxisEdge(); 246 RectangleEdge rangeAxisLocation = plot.getRangeAxisEdge(); 247 248 double j2dy0 = rangeAxis.translateValueToJava2D(previous, dataArea, rangeAxisLocation); 250 251 double j2dy1 = rangeAxis.translateValueToJava2D(current, dataArea, rangeAxisLocation); 253 254 double valDiff = current - previous; 255 if (j2dy1 < j2dy0) { 256 double temp = j2dy1; 257 j2dy1 = j2dy0; 258 j2dy0 = temp; 259 } 260 261 double rectWidth = state.getBarWidth(); 263 264 double rectHeight = Math.abs(j2dy1 - j2dy0); 266 267 if (orientation == PlotOrientation.HORIZONTAL) { 268 rectY = domainAxis.getCategoryStart(column, getColumnCount(), dataArea, 270 domainAxisLocation); 271 if (seriesCount > 1) { 272 double seriesGap = dataArea.getHeight() * getItemMargin() 273 / (categoryCount * (seriesCount - 1)); 274 rectY = rectY + row * (state.getBarWidth() + seriesGap); 275 } 276 else { 277 rectY = rectY + row * state.getBarWidth(); 278 } 279 280 rectX = j2dy0; 281 rectHeight = state.getBarWidth(); 282 rectWidth = Math.abs(j2dy1 - j2dy0); 283 284 } 285 else if (orientation == PlotOrientation.VERTICAL) { 286 rectX = domainAxis.getCategoryStart(column, getColumnCount(), dataArea, 288 domainAxisLocation); 289 290 if (seriesCount > 1) { 291 double seriesGap = dataArea.getWidth() * getItemMargin() 292 / (categoryCount * (seriesCount - 1)); 293 rectX = rectX + row * (state.getBarWidth() + seriesGap); 294 } 295 else { 296 rectX = rectX + row * state.getBarWidth(); 297 } 298 299 rectY = j2dy0; 300 } 301 Rectangle2D bar = new Rectangle2D.Double (rectX, rectY, rectWidth, rectHeight); 302 Paint seriesPaint = this.firstBarPaint; 303 if (column == 0) { 304 seriesPaint = this.firstBarPaint; 305 } 306 else if (column == categoryCount - 1) { 307 seriesPaint = this.lastBarPaint; 308 } 309 else { 310 if (valDiff < 0.0) { 311 seriesPaint = this.negativeBarPaint; 312 } 313 else if (valDiff > 0.0) { 314 seriesPaint = this.positiveBarPaint; 315 } 316 else { 317 seriesPaint = this.lastBarPaint; 318 } 319 } 320 if (getGradientPaintTransformer() != null && seriesPaint instanceof GradientPaint ) { 321 GradientPaint gp = (GradientPaint ) seriesPaint; 322 seriesPaint = getGradientPaintTransformer().transform(gp, bar); 323 } 324 g2.setPaint(seriesPaint); 325 g2.fill(bar); 326 327 if (isDrawBarOutline() &&state.getBarWidth() > BAR_OUTLINE_WIDTH_THRESHOLD) { 329 Stroke stroke = getItemOutlineStroke(row, column); 330 Paint paint = getItemOutlinePaint(row, column); 331 if (stroke != null && paint != null) { 332 g2.setStroke(stroke); 333 g2.setPaint(paint); 334 g2.draw(bar); 335 } 336 } 337 338 CategoryItemLabelGenerator generator = getItemLabelGenerator(row, column); 339 if (generator != null && isItemLabelVisible(row, column)) { 340 drawItemLabel(g2, dataset, row, column, plot, generator, bar, (valDiff < 0.0)); 341 } 342 343 if (state.getInfo() != null) { 345 EntityCollection entities = state.getInfo().getOwner().getEntityCollection(); 346 if (entities != null) { 347 String tip = null; 348 if (generator != null) { 349 tip = generator.generateToolTip(dataset, row, column); 350 } 351 String url = null; 352 if (getItemURLGenerator(row, column) != null) { 353 url = getItemURLGenerator(row, column).generateURL(dataset, row, column); 354 } 355 CategoryItemEntity entity = new CategoryItemEntity( 356 bar, tip, url, dataset, row, dataset.getColumnKey(column), column 357 ); 358 entities.addEntity(entity); 359 } 360 } 361 362 } 363 364 371 public boolean equals(Object object) { 372 373 if (object == null) { 374 return false; 375 } 376 377 if (object == this) { 378 return true; 379 } 380 381 if (super.equals(object) && (object instanceof WaterfallBarRenderer)) { 382 383 WaterfallBarRenderer r = (WaterfallBarRenderer) object; 384 boolean b0 = PaintUtils.equal(this.firstBarPaint, r.firstBarPaint); 385 boolean b1 = PaintUtils.equal(this.lastBarPaint, r.lastBarPaint); 386 boolean b2 = PaintUtils.equal(this.positiveBarPaint, r.positiveBarPaint); 387 boolean b3 = PaintUtils.equal(this.negativeBarPaint, r.negativeBarPaint); 388 return b0 && b1 && b2 && b3; 389 } 390 391 return false; 392 393 } 394 395 402 private void writeObject(ObjectOutputStream stream) throws IOException { 403 404 stream.defaultWriteObject(); 405 SerialUtilities.writePaint(this.firstBarPaint, stream); 406 SerialUtilities.writePaint(this.lastBarPaint, stream); 407 SerialUtilities.writePaint(this.positiveBarPaint, stream); 408 SerialUtilities.writePaint(this.negativeBarPaint, stream); 409 410 } 411 412 420 private void readObject(ObjectInputStream stream) throws IOException , ClassNotFoundException { 421 422 stream.defaultReadObject(); 423 this.firstBarPaint = SerialUtilities.readPaint(stream); 424 this.lastBarPaint = SerialUtilities.readPaint(stream); 425 this.positiveBarPaint = SerialUtilities.readPaint(stream); 426 this.negativeBarPaint = SerialUtilities.readPaint(stream); 427 428 } 429 430 } 431 | Popular Tags |