1 48 49 package org.jfree.chart.renderer.category; 50 51 import java.awt.AlphaComposite ; 52 import java.awt.Color ; 53 import java.awt.Composite ; 54 import java.awt.Graphics2D ; 55 import java.awt.Image ; 56 import java.awt.Paint ; 57 import java.awt.Shape ; 58 import java.awt.Stroke ; 59 import java.awt.geom.GeneralPath ; 60 import java.awt.geom.Line2D ; 61 import java.awt.geom.Rectangle2D ; 62 import java.io.Serializable ; 63 64 import org.jfree.chart.Effect3D; 65 import org.jfree.chart.axis.CategoryAxis; 66 import org.jfree.chart.axis.ValueAxis; 67 import org.jfree.chart.entity.EntityCollection; 68 import org.jfree.chart.event.RendererChangeEvent; 69 import org.jfree.chart.plot.CategoryPlot; 70 import org.jfree.chart.plot.Marker; 71 import org.jfree.chart.plot.PlotOrientation; 72 import org.jfree.chart.plot.ValueMarker; 73 import org.jfree.data.Range; 74 import org.jfree.data.category.CategoryDataset; 75 import org.jfree.util.ShapeUtilities; 76 77 82 public class LineRenderer3D extends LineAndShapeRenderer 83 implements Effect3D, Serializable { 84 85 86 private static final long serialVersionUID = 5467931468380928736L; 87 88 89 public static final double DEFAULT_X_OFFSET = 12.0; 90 91 92 public static final double DEFAULT_Y_OFFSET = 8.0; 93 94 95 public static final Paint DEFAULT_WALL_PAINT = new Color (0xDD, 0xDD, 0xDD); 96 97 98 private double xOffset; 99 100 101 private double yOffset; 102 103 104 private transient Paint wallPaint; 105 106 109 public LineRenderer3D() { 110 super(true, false); this.xOffset = DEFAULT_X_OFFSET; 112 this.yOffset = DEFAULT_Y_OFFSET; 113 this.wallPaint = DEFAULT_WALL_PAINT; 114 } 115 116 121 public double getXOffset() { 122 return this.xOffset; 123 } 124 125 130 public double getYOffset() { 131 return this.yOffset; 132 } 133 134 139 public void setXOffset(double xOffset) { 140 this.xOffset = xOffset; 141 notifyListeners(new RendererChangeEvent(this)); 142 } 143 144 149 public void setYOffset(double yOffset) { 150 this.yOffset = yOffset; 151 notifyListeners(new RendererChangeEvent(this)); 152 } 153 154 160 public Paint getWallPaint() { 161 return this.wallPaint; 162 } 163 164 170 public void setWallPaint(Paint paint) { 171 this.wallPaint = paint; 172 notifyListeners(new RendererChangeEvent(this)); 173 } 174 175 182 public void drawBackground(Graphics2D g2, CategoryPlot plot, 183 Rectangle2D dataArea) { 184 185 float x0 = (float) dataArea.getX(); 186 float x1 = x0 + (float) Math.abs(this.xOffset); 187 float x3 = (float) dataArea.getMaxX(); 188 float x2 = x3 - (float) Math.abs(this.xOffset); 189 190 float y0 = (float) dataArea.getMaxY(); 191 float y1 = y0 - (float) Math.abs(this.yOffset); 192 float y3 = (float) dataArea.getMinY(); 193 float y2 = y3 + (float) Math.abs(this.yOffset); 194 195 GeneralPath clip = new GeneralPath (); 196 clip.moveTo(x0, y0); 197 clip.lineTo(x0, y2); 198 clip.lineTo(x1, y3); 199 clip.lineTo(x3, y3); 200 clip.lineTo(x3, y1); 201 clip.lineTo(x2, y0); 202 clip.closePath(); 203 204 Paint backgroundPaint = plot.getBackgroundPaint(); 206 if (backgroundPaint != null) { 207 g2.setPaint(backgroundPaint); 208 g2.fill(clip); 209 } 210 211 GeneralPath leftWall = new GeneralPath (); 212 leftWall.moveTo(x0, y0); 213 leftWall.lineTo(x0, y2); 214 leftWall.lineTo(x1, y3); 215 leftWall.lineTo(x1, y1); 216 leftWall.closePath(); 217 g2.setPaint(getWallPaint()); 218 g2.fill(leftWall); 219 220 GeneralPath bottomWall = new GeneralPath (); 221 bottomWall.moveTo(x0, y0); 222 bottomWall.lineTo(x1, y1); 223 bottomWall.lineTo(x3, y1); 224 bottomWall.lineTo(x2, y0); 225 bottomWall.closePath(); 226 g2.setPaint(getWallPaint()); 227 g2.fill(bottomWall); 228 229 g2.setPaint(Color.lightGray); 231 Line2D corner = new Line2D.Double (x0, y0, x1, y1); 232 g2.draw(corner); 233 corner.setLine(x1, y1, x1, y3); 234 g2.draw(corner); 235 corner.setLine(x1, y1, x3, y1); 236 g2.draw(corner); 237 238 Image backgroundImage = plot.getBackgroundImage(); 240 if (backgroundImage != null) { 241 Composite originalComposite = g2.getComposite(); 242 g2.setComposite(AlphaComposite.getInstance( 243 AlphaComposite.SRC, plot.getBackgroundAlpha())); 244 g2.drawImage(backgroundImage, (int) x1, (int) y3, 245 (int) (x3 - x1 + 1), (int) (y1 - y3 + 1), null); 246 g2.setComposite(originalComposite); 247 } 248 249 } 250 251 258 public void drawOutline(Graphics2D g2, CategoryPlot plot, 259 Rectangle2D dataArea) { 260 261 float x0 = (float) dataArea.getX(); 262 float x1 = x0 + (float) Math.abs(this.xOffset); 263 float x3 = (float) dataArea.getMaxX(); 264 float x2 = x3 - (float) Math.abs(this.xOffset); 265 266 float y0 = (float) dataArea.getMaxY(); 267 float y1 = y0 - (float) Math.abs(this.yOffset); 268 float y3 = (float) dataArea.getMinY(); 269 float y2 = y3 + (float) Math.abs(this.yOffset); 270 271 GeneralPath clip = new GeneralPath (); 272 clip.moveTo(x0, y0); 273 clip.lineTo(x0, y2); 274 clip.lineTo(x1, y3); 275 clip.lineTo(x3, y3); 276 clip.lineTo(x3, y1); 277 clip.lineTo(x2, y0); 278 clip.closePath(); 279 280 Stroke outlineStroke = plot.getOutlineStroke(); 282 Paint outlinePaint = plot.getOutlinePaint(); 283 if ((outlineStroke != null) && (outlinePaint != null)) { 284 g2.setStroke(outlineStroke); 285 g2.setPaint(outlinePaint); 286 g2.draw(clip); 287 } 288 289 } 290 291 301 public void drawDomainGridline(Graphics2D g2, 302 CategoryPlot plot, 303 Rectangle2D dataArea, 304 double value) { 305 306 Line2D line1 = null; 307 Line2D line2 = null; 308 PlotOrientation orientation = plot.getOrientation(); 309 if (orientation == PlotOrientation.HORIZONTAL) { 310 double y0 = value; 311 double y1 = value - getYOffset(); 312 double x0 = dataArea.getMinX(); 313 double x1 = x0 + getXOffset(); 314 double x2 = dataArea.getMaxY(); 315 line1 = new Line2D.Double (x0, y0, x1, y1); 316 line2 = new Line2D.Double (x1, y1, x2, y1); 317 } 318 else if (orientation == PlotOrientation.VERTICAL) { 319 double x0 = value; 320 double x1 = value + getXOffset(); 321 double y0 = dataArea.getMaxY(); 322 double y1 = y0 - getYOffset(); 323 double y2 = dataArea.getMinY(); 324 line1 = new Line2D.Double (x0, y0, x1, y1); 325 line2 = new Line2D.Double (x1, y1, x1, y2); 326 } 327 g2.setPaint(plot.getDomainGridlinePaint()); 328 g2.setStroke(plot.getDomainGridlineStroke()); 329 g2.draw(line1); 330 g2.draw(line2); 331 332 } 333 334 345 public void drawRangeGridline(Graphics2D g2, 346 CategoryPlot plot, 347 ValueAxis axis, 348 Rectangle2D dataArea, 349 double value) { 350 351 Range range = axis.getRange(); 352 353 if (!range.contains(value)) { 354 return; 355 } 356 357 Rectangle2D adjusted = new Rectangle2D.Double (dataArea.getX(), 358 dataArea.getY() + getYOffset(), 359 dataArea.getWidth() - getXOffset(), 360 dataArea.getHeight() - getYOffset()); 361 362 Line2D line1 = null; 363 Line2D line2 = null; 364 PlotOrientation orientation = plot.getOrientation(); 365 if (orientation == PlotOrientation.HORIZONTAL) { 366 double x0 = axis.valueToJava2D(value, adjusted, 367 plot.getRangeAxisEdge()); 368 double x1 = x0 + getXOffset(); 369 double y0 = dataArea.getMaxY(); 370 double y1 = y0 - getYOffset(); 371 double y2 = dataArea.getMinY(); 372 line1 = new Line2D.Double (x0, y0, x1, y1); 373 line2 = new Line2D.Double (x1, y1, x1, y2); 374 } 375 else if (orientation == PlotOrientation.VERTICAL) { 376 double y0 = axis.valueToJava2D(value, adjusted, 377 plot.getRangeAxisEdge()); 378 double y1 = y0 - getYOffset(); 379 double x0 = dataArea.getMinX(); 380 double x1 = x0 + getXOffset(); 381 double x2 = dataArea.getMaxX(); 382 line1 = new Line2D.Double (x0, y0, x1, y1); 383 line2 = new Line2D.Double (x1, y1, x2, y1); 384 } 385 g2.setPaint(plot.getRangeGridlinePaint()); 386 g2.setStroke(plot.getRangeGridlineStroke()); 387 g2.draw(line1); 388 g2.draw(line2); 389 390 } 391 392 401 public void drawRangeMarker(Graphics2D g2, 402 CategoryPlot plot, 403 ValueAxis axis, 404 Marker marker, 405 Rectangle2D dataArea) { 406 407 if (marker instanceof ValueMarker) { 408 ValueMarker vm = (ValueMarker) marker; 409 double value = vm.getValue(); 410 Range range = axis.getRange(); 411 if (!range.contains(value)) { 412 return; 413 } 414 415 Rectangle2D adjusted = new Rectangle2D.Double (dataArea.getX(), 416 dataArea.getY() + getYOffset(), 417 dataArea.getWidth() - getXOffset(), 418 dataArea.getHeight() - getYOffset()); 419 420 GeneralPath path = null; 421 PlotOrientation orientation = plot.getOrientation(); 422 if (orientation == PlotOrientation.HORIZONTAL) { 423 float x = (float) axis.valueToJava2D(value, adjusted, 424 plot.getRangeAxisEdge()); 425 float y = (float) adjusted.getMaxY(); 426 path = new GeneralPath (); 427 path.moveTo(x, y); 428 path.lineTo((float) (x + getXOffset()), 429 y - (float) getYOffset()); 430 path.lineTo((float) (x + getXOffset()), 431 (float) (adjusted.getMinY() - getYOffset())); 432 path.lineTo(x, (float) adjusted.getMinY()); 433 path.closePath(); 434 } 435 else if (orientation == PlotOrientation.VERTICAL) { 436 float y = (float) axis.valueToJava2D(value, adjusted, 437 plot.getRangeAxisEdge()); 438 float x = (float) dataArea.getX(); 439 path = new GeneralPath (); 440 path.moveTo(x, y); 441 path.lineTo(x + (float) this.xOffset, y - (float) this.yOffset); 442 path.lineTo((float) (adjusted.getMaxX() + this.xOffset), 443 y - (float) this.yOffset); 444 path.lineTo((float) (adjusted.getMaxX()), y); 445 path.closePath(); 446 } 447 g2.setPaint(marker.getPaint()); 448 g2.fill(path); 449 g2.setPaint(marker.getOutlinePaint()); 450 g2.draw(path); 451 } 452 } 453 454 468 public void drawItem(Graphics2D g2, 469 CategoryItemRendererState state, 470 Rectangle2D dataArea, 471 CategoryPlot plot, 472 CategoryAxis domainAxis, 473 ValueAxis rangeAxis, 474 CategoryDataset dataset, 475 int row, 476 int column, 477 int pass) { 478 479 if (!getItemVisible(row, column)) { 480 return; 481 } 482 483 Number v = dataset.getValue(row, column); 485 if (v == null) { 486 return; 487 } 488 489 Rectangle2D adjusted = new Rectangle2D.Double (dataArea.getX(), 490 dataArea.getY() + getYOffset(), 491 dataArea.getWidth() - getXOffset(), 492 dataArea.getHeight() - getYOffset()); 493 494 PlotOrientation orientation = plot.getOrientation(); 495 496 double x1 = domainAxis.getCategoryMiddle(column, getColumnCount(), 498 adjusted, plot.getDomainAxisEdge()); 499 double value = v.doubleValue(); 500 double y1 = rangeAxis.valueToJava2D(value, adjusted, 501 plot.getRangeAxisEdge()); 502 503 Shape shape = getItemShape(row, column); 504 if (orientation == PlotOrientation.HORIZONTAL) { 505 shape = ShapeUtilities.createTranslatedShape(shape, y1, x1); 506 } 507 else if (orientation == PlotOrientation.VERTICAL) { 508 shape = ShapeUtilities.createTranslatedShape(shape, x1, y1); 509 } 510 511 if (getItemLineVisible(row, column)) { 512 if (column != 0) { 513 514 Number previousValue = dataset.getValue(row, column - 1); 515 if (previousValue != null) { 516 517 double previous = previousValue.doubleValue(); 519 double x0 = domainAxis.getCategoryMiddle(column - 1, 520 getColumnCount(), adjusted, 521 plot.getDomainAxisEdge()); 522 double y0 = rangeAxis.valueToJava2D(previous, adjusted, 523 plot.getRangeAxisEdge()); 524 525 double x2 = x0 + getXOffset(); 526 double y2 = y0 - getYOffset(); 527 double x3 = x1 + getXOffset(); 528 double y3 = y1 - getYOffset(); 529 530 GeneralPath clip = new GeneralPath (); 531 532 if (orientation == PlotOrientation.HORIZONTAL) { 533 clip.moveTo((float) y0, (float) x0); 534 clip.lineTo((float) y1, (float) x1); 535 clip.lineTo((float) y3, (float) x3); 536 clip.lineTo((float) y2, (float) x2); 537 clip.lineTo((float) y0, (float) x0); 538 clip.closePath(); 539 } 540 else if (orientation == PlotOrientation.VERTICAL) { 541 clip.moveTo((float) x0, (float) y0); 542 clip.lineTo((float) x1, (float) y1); 543 clip.lineTo((float) x3, (float) y3); 544 clip.lineTo((float) x2, (float) y2); 545 clip.lineTo((float) x0, (float) y0); 546 clip.closePath(); 547 } 548 549 g2.setPaint(getItemPaint(row, column)); 550 g2.fill(clip); 551 g2.setStroke(getItemOutlineStroke(row, column)); 552 g2.setPaint(getItemOutlinePaint(row, column)); 553 g2.draw(clip); 554 } 555 } 556 } 557 558 if (isItemLabelVisible(row, column)) { 560 drawItemLabel(g2, orientation, dataset, row, column, x1, y1, 561 (value < 0.0)); 562 } 563 564 EntityCollection entities = state.getEntityCollection(); 566 if (entities != null) { 567 addItemEntity(entities, dataset, row, column, shape); 568 } 569 570 } 571 572 } 573 | Popular Tags |