1 57 58 package org.jfree.chart.renderer.category; 59 60 import java.awt.BasicStroke ; 61 import java.awt.Color ; 62 import java.awt.Component ; 63 import java.awt.Graphics ; 64 import java.awt.Graphics2D ; 65 import java.awt.Paint ; 66 import java.awt.Shape ; 67 import java.awt.Stroke ; 68 import java.awt.geom.AffineTransform ; 69 import java.awt.geom.Arc2D ; 70 import java.awt.geom.GeneralPath ; 71 import java.awt.geom.Line2D ; 72 import java.awt.geom.Rectangle2D ; 73 import java.io.IOException ; 74 import java.io.ObjectInputStream ; 75 import java.io.ObjectOutputStream ; 76 77 import javax.swing.Icon ; 78 79 import org.jfree.chart.axis.CategoryAxis; 80 import org.jfree.chart.axis.ValueAxis; 81 import org.jfree.chart.entity.CategoryItemEntity; 82 import org.jfree.chart.entity.EntityCollection; 83 import org.jfree.chart.event.RendererChangeEvent; 84 import org.jfree.chart.labels.CategoryToolTipGenerator; 85 import org.jfree.chart.plot.CategoryPlot; 86 import org.jfree.data.category.CategoryDataset; 87 import org.jfree.io.SerialUtilities; 88 89 98 public class MinMaxCategoryRenderer extends AbstractCategoryItemRenderer { 99 100 101 private static final long serialVersionUID = 2935615937671064911L; 102 103 104 private boolean plotLines = false; 105 106 109 private transient Paint groupPaint = Color.black; 110 111 114 private transient Stroke groupStroke = new BasicStroke (1.0f); 115 116 117 private transient Icon minIcon = getIcon(new Arc2D.Double (-4, -4, 8, 8, 0, 118 360, Arc2D.OPEN), null, Color.black); 119 120 121 private transient Icon maxIcon = getIcon(new Arc2D.Double (-4, -4, 8, 8, 0, 122 360, Arc2D.OPEN), null, Color.black); 123 124 125 private transient Icon objectIcon = getIcon(new Line2D.Double (-4, 0, 4, 0), 126 false, true); 127 128 129 private int lastCategory = -1; 130 131 132 private double min; 133 134 135 private double max; 136 137 140 public MinMaxCategoryRenderer() { 141 super(); 142 } 143 144 152 public boolean isDrawLines() { 153 return this.plotLines; 154 } 155 156 165 public void setDrawLines(boolean draw) { 166 if (this.plotLines != draw) { 167 this.plotLines = draw; 168 this.notifyListeners(new RendererChangeEvent(this)); 169 } 170 171 } 172 173 181 public Paint getGroupPaint() { 182 return this.groupPaint; 183 } 184 185 194 public void setGroupPaint(Paint paint) { 195 if (paint == null) { 196 throw new IllegalArgumentException ("Null 'paint' argument."); 197 } 198 this.groupPaint = paint; 199 notifyListeners(new RendererChangeEvent(this)); 200 } 201 202 210 public Stroke getGroupStroke() { 211 return this.groupStroke; 212 } 213 214 220 public void setGroupStroke(Stroke groupStroke) { 221 this.groupStroke = groupStroke; 222 } 223 224 231 public Icon getObjectIcon() { 232 return this.objectIcon; 233 } 234 235 242 public void setObjectIcon(Icon icon) { 243 if (icon == null) { 244 throw new IllegalArgumentException ("Null 'icon' argument."); 245 } 246 this.objectIcon = icon; 247 notifyListeners(new RendererChangeEvent(this)); 248 } 249 250 258 public Icon getMaxIcon() { 259 return this.maxIcon; 260 } 261 262 271 public void setMaxIcon(Icon icon) { 272 if (icon == null) { 273 throw new IllegalArgumentException ("Null 'icon' argument."); 274 } 275 this.maxIcon = icon; 276 notifyListeners(new RendererChangeEvent(this)); 277 } 278 279 287 public Icon getMinIcon() { 288 return this.minIcon; 289 } 290 291 300 public void setMinIcon(Icon icon) { 301 if (icon == null) { 302 throw new IllegalArgumentException ("Null 'icon' argument."); 303 } 304 this.minIcon = icon; 305 notifyListeners(new RendererChangeEvent(this)); 306 } 307 308 322 public void drawItem(Graphics2D g2, CategoryItemRendererState state, 323 Rectangle2D dataArea, CategoryPlot plot, CategoryAxis domainAxis, 324 ValueAxis rangeAxis, CategoryDataset dataset, int row, int column, 325 int pass) { 326 327 Number value = dataset.getValue(row, column); 329 if (value != null) { 330 double x1 = domainAxis.getCategoryMiddle( 332 column, getColumnCount(), dataArea, plot.getDomainAxisEdge()); 333 double y1 = rangeAxis.valueToJava2D( 334 value.doubleValue(), dataArea, plot.getRangeAxisEdge()); 335 g2.setPaint(getItemPaint(row, column)); 336 g2.setStroke(getItemStroke(row, column)); 337 Shape shape = null; 338 shape = new Rectangle2D.Double (x1 - 4, y1 - 4, 8.0, 8.0); 339 this.objectIcon.paintIcon(null, g2, (int) x1, (int) y1); 340 if (this.lastCategory == column) { 341 if (this.min > value.doubleValue()) { 342 this.min = value.doubleValue(); 343 } 344 if (this.max < value.doubleValue()) { 345 this.max = value.doubleValue(); 346 } 347 if (dataset.getRowCount() - 1 == row) { 348 g2.setPaint(this.groupPaint); 349 g2.setStroke(this.groupStroke); 350 double minY = rangeAxis.valueToJava2D(this.min, dataArea, 351 plot.getRangeAxisEdge()); 352 double maxY = rangeAxis.valueToJava2D(this.max, dataArea, 353 plot.getRangeAxisEdge()); 354 g2.draw(new Line2D.Double (x1, minY, x1, maxY)); 355 this.minIcon.paintIcon(null, g2, (int) x1, (int) minY); 356 this.maxIcon.paintIcon(null, g2, (int) x1, (int) maxY); 357 } 358 } 359 else { this.lastCategory = column; 361 this.min = value.doubleValue(); 362 this.max = value.doubleValue(); 363 } 364 if (this.plotLines) { 366 if (column != 0) { 367 Number previousValue = dataset.getValue(row, column - 1); 368 if (previousValue != null) { 369 double previous = previousValue.doubleValue(); 371 double x0 = domainAxis.getCategoryMiddle( 372 column - 1, getColumnCount(), dataArea, 373 plot.getDomainAxisEdge()); 374 double y0 = rangeAxis.valueToJava2D( 375 previous, dataArea, plot.getRangeAxisEdge()); 376 g2.setPaint(getItemPaint(row, column)); 377 g2.setStroke(getItemStroke(row, column)); 378 Line2D line = new Line2D.Double (x0, y0, x1, y1); 379 g2.draw(line); 380 } 381 } 382 } 383 384 if (state.getInfo() != null) { 386 EntityCollection entities = state.getEntityCollection(); 387 if (entities != null && shape != null) { 388 String tip = null; 389 CategoryToolTipGenerator tipster 390 = getToolTipGenerator(row, column); 391 if (tipster != null) { 392 tip = tipster.generateToolTip(dataset, row, column); 393 } 394 CategoryItemEntity entity = new CategoryItemEntity( 395 shape, tip, null, dataset, row, 396 dataset.getColumnKey(column), column); 397 entities.add(entity); 398 } 399 } 400 } 401 } 402 403 412 private Icon getIcon(Shape shape, final Paint fillPaint, 413 final Paint outlinePaint) { 414 415 final int width = shape.getBounds().width; 416 final int height = shape.getBounds().height; 417 final GeneralPath path = new GeneralPath (shape); 418 return new Icon () { 419 public void paintIcon(Component c, Graphics g, int x, int y) { 420 Graphics2D g2 = (Graphics2D ) g; 421 path.transform(AffineTransform.getTranslateInstance(x, y)); 422 if (fillPaint != null) { 423 g2.setPaint(fillPaint); 424 g2.fill(path); 425 } 426 if (outlinePaint != null) { 427 g2.setPaint(outlinePaint); 428 g2.draw(path); 429 } 430 path.transform(AffineTransform.getTranslateInstance(-x, -y)); 431 } 432 433 public int getIconWidth() { 434 return width; 435 } 436 437 public int getIconHeight() { 438 return height; 439 } 440 441 }; 442 } 443 444 453 private Icon getIcon(Shape shape, final boolean fill, 454 final boolean outline) { 455 final int width = shape.getBounds().width; 456 final int height = shape.getBounds().height; 457 final GeneralPath path = new GeneralPath (shape); 458 return new Icon () { 459 public void paintIcon(Component c, Graphics g, int x, int y) { 460 Graphics2D g2 = (Graphics2D ) g; 461 path.transform(AffineTransform.getTranslateInstance(x, y)); 462 if (fill) { 463 g2.fill(path); 464 } 465 if (outline) { 466 g2.draw(path); 467 } 468 path.transform(AffineTransform.getTranslateInstance(-x, -y)); 469 } 470 471 public int getIconWidth() { 472 return width; 473 } 474 475 public int getIconHeight() { 476 return height; 477 } 478 }; 479 } 480 481 488 private void writeObject(ObjectOutputStream stream) throws IOException { 489 stream.defaultWriteObject(); 490 SerialUtilities.writeStroke(this.groupStroke, stream); 491 SerialUtilities.writePaint(this.groupPaint, stream); 492 } 493 494 502 private void readObject(ObjectInputStream stream) 503 throws IOException , ClassNotFoundException { 504 stream.defaultReadObject(); 505 this.groupStroke = SerialUtilities.readStroke(stream); 506 this.groupPaint = SerialUtilities.readPaint(stream); 507 508 this.minIcon = getIcon( 509 new Arc2D.Double (-4, -4, 8, 8, 0, 360, Arc2D.OPEN), null, 510 Color.black); 511 this.maxIcon = getIcon( 512 new Arc2D.Double (-4, -4, 8, 8, 0, 360, Arc2D.OPEN), null, 513 Color.black); 514 this.objectIcon = getIcon(new Line2D.Double (-4, 0, 4, 0), false, true); 515 } 516 517 } 518 | Popular Tags |