1 73 74 package org.jfree.chart.renderer.xy; 75 76 import java.awt.Graphics2D ; 77 import java.awt.Paint ; 78 import java.awt.Polygon ; 79 import java.awt.Shape ; 80 import java.awt.Stroke ; 81 import java.awt.geom.GeneralPath ; 82 import java.awt.geom.Line2D ; 83 import java.awt.geom.Rectangle2D ; 84 import java.io.IOException ; 85 import java.io.ObjectInputStream ; 86 import java.io.ObjectOutputStream ; 87 import java.io.Serializable ; 88 89 import org.jfree.chart.LegendItem; 90 import org.jfree.chart.axis.ValueAxis; 91 import org.jfree.chart.entity.EntityCollection; 92 import org.jfree.chart.entity.XYItemEntity; 93 import org.jfree.chart.event.RendererChangeEvent; 94 import org.jfree.chart.labels.XYSeriesLabelGenerator; 95 import org.jfree.chart.labels.XYToolTipGenerator; 96 import org.jfree.chart.plot.CrosshairState; 97 import org.jfree.chart.plot.PlotOrientation; 98 import org.jfree.chart.plot.PlotRenderingInfo; 99 import org.jfree.chart.plot.XYPlot; 100 import org.jfree.chart.urls.XYURLGenerator; 101 import org.jfree.data.xy.XYDataset; 102 import org.jfree.io.SerialUtilities; 103 import org.jfree.util.PublicCloneable; 104 import org.jfree.util.ShapeUtilities; 105 106 111 public class XYAreaRenderer extends AbstractXYItemRenderer 112 implements XYItemRenderer, 113 Cloneable , 114 PublicCloneable, 115 Serializable { 116 117 118 private static final long serialVersionUID = -4481971353973876747L; 119 120 123 static class XYAreaRendererState extends XYItemRendererState { 124 125 126 public Polygon area; 127 128 129 public Line2D line; 130 131 136 public XYAreaRendererState(PlotRenderingInfo info) { 137 super(info); 138 this.area = new Polygon (); 139 this.line = new Line2D.Double (); 140 } 141 142 } 143 144 145 public static final int SHAPES = 1; 146 147 148 public static final int LINES = 2; 149 150 153 public static final int SHAPES_AND_LINES = 3; 154 155 156 public static final int AREA = 4; 157 158 161 public static final int AREA_AND_SHAPES = 5; 162 163 164 private boolean plotShapes; 165 166 167 private boolean plotLines; 168 169 170 private boolean plotArea; 171 172 173 private boolean showOutline; 174 175 179 private transient Shape legendArea; 180 181 184 public XYAreaRenderer() { 185 this(AREA); 186 } 187 188 193 public XYAreaRenderer(int type) { 194 this(type, null, null); 195 } 196 197 208 public XYAreaRenderer(int type, XYToolTipGenerator toolTipGenerator, 209 XYURLGenerator urlGenerator) { 210 211 super(); 212 setBaseToolTipGenerator(toolTipGenerator); 213 setURLGenerator(urlGenerator); 214 215 if (type == SHAPES) { 216 this.plotShapes = true; 217 } 218 if (type == LINES) { 219 this.plotLines = true; 220 } 221 if (type == SHAPES_AND_LINES) { 222 this.plotShapes = true; 223 this.plotLines = true; 224 } 225 if (type == AREA) { 226 this.plotArea = true; 227 } 228 if (type == AREA_AND_SHAPES) { 229 this.plotArea = true; 230 this.plotShapes = true; 231 } 232 this.showOutline = false; 233 GeneralPath area = new GeneralPath (); 234 area.moveTo(0.0f, -4.0f); 235 area.lineTo(3.0f, -2.0f); 236 area.lineTo(4.0f, 4.0f); 237 area.lineTo(-4.0f, 4.0f); 238 area.lineTo(-3.0f, -2.0f); 239 area.closePath(); 240 this.legendArea = area; 241 242 } 243 244 250 public boolean isOutline() { 251 return this.showOutline; 252 } 253 254 259 public void setOutline(boolean show) { 260 this.showOutline = show; 261 } 262 263 268 public boolean getPlotShapes() { 269 return this.plotShapes; 270 } 271 272 277 public boolean getPlotLines() { 278 return this.plotLines; 279 } 280 281 286 public boolean getPlotArea() { 287 return this.plotArea; 288 } 289 290 295 public Shape getLegendArea() { 296 return this.legendArea; 297 } 298 299 305 public void setLegendArea(Shape area) { 306 if (area == null) { 307 throw new IllegalArgumentException ("Null 'area' argument."); 308 } 309 this.legendArea = area; 310 notifyListeners(new RendererChangeEvent(this)); 311 } 312 313 326 public XYItemRendererState initialise(Graphics2D g2, Rectangle2D dataArea, 327 XYPlot plot, XYDataset data, PlotRenderingInfo info) { 328 XYAreaRendererState state = new XYAreaRendererState(info); 329 return state; 330 } 331 332 341 public LegendItem getLegendItem(int datasetIndex, int series) { 342 LegendItem result = null; 343 XYPlot xyplot = getPlot(); 344 if (xyplot != null) { 345 XYDataset dataset = xyplot.getDataset(datasetIndex); 346 if (dataset != null) { 347 XYSeriesLabelGenerator lg = getLegendItemLabelGenerator(); 348 String label = lg.generateLabel(dataset, series); 349 String description = label; 350 String toolTipText = null; 351 if (getLegendItemToolTipGenerator() != null) { 352 toolTipText = getLegendItemToolTipGenerator().generateLabel( 353 dataset, series); 354 } 355 String urlText = null; 356 if (getLegendItemURLGenerator() != null) { 357 urlText = getLegendItemURLGenerator().generateLabel( 358 dataset, series); 359 } 360 Paint paint = getSeriesPaint(series); 361 result = new LegendItem(label, description, toolTipText, 362 urlText, this.legendArea, paint); 363 } 364 } 365 return result; 366 } 367 368 386 public void drawItem(Graphics2D g2, XYItemRendererState state, 387 Rectangle2D dataArea, PlotRenderingInfo info, XYPlot plot, 388 ValueAxis domainAxis, ValueAxis rangeAxis, XYDataset dataset, 389 int series, int item, CrosshairState crosshairState, int pass) { 390 391 if (!getItemVisible(series, item)) { 392 return; 393 } 394 XYAreaRendererState areaState = (XYAreaRendererState) state; 395 396 double x1 = dataset.getXValue(series, item); 398 double y1 = dataset.getYValue(series, item); 399 if (Double.isNaN(y1)) { 400 y1 = 0.0; 401 } 402 double transX1 = domainAxis.valueToJava2D(x1, dataArea, 403 plot.getDomainAxisEdge()); 404 double transY1 = rangeAxis.valueToJava2D(y1, dataArea, 405 plot.getRangeAxisEdge()); 406 407 int itemCount = dataset.getItemCount(series); 410 double x0 = dataset.getXValue(series, Math.max(item - 1, 0)); 411 double y0 = dataset.getYValue(series, Math.max(item - 1, 0)); 412 if (Double.isNaN(y0)) { 413 y0 = 0.0; 414 } 415 double transX0 = domainAxis.valueToJava2D(x0, dataArea, 416 plot.getDomainAxisEdge()); 417 double transY0 = rangeAxis.valueToJava2D(y0, dataArea, 418 plot.getRangeAxisEdge()); 419 420 double x2 = dataset.getXValue(series, Math.min(item + 1, 421 itemCount - 1)); 422 double y2 = dataset.getYValue(series, Math.min(item + 1, 423 itemCount - 1)); 424 if (Double.isNaN(y2)) { 425 y2 = 0.0; 426 } 427 double transX2 = domainAxis.valueToJava2D(x2, dataArea, 428 plot.getDomainAxisEdge()); 429 double transY2 = rangeAxis.valueToJava2D(y2, dataArea, 430 plot.getRangeAxisEdge()); 431 432 double transZero = rangeAxis.valueToJava2D(0.0, dataArea, 433 plot.getRangeAxisEdge()); 434 Polygon hotspot = null; 435 if (plot.getOrientation() == PlotOrientation.HORIZONTAL) { 436 hotspot = new Polygon (); 437 hotspot.addPoint((int) transZero, 438 (int) ((transX0 + transX1) / 2.0)); 439 hotspot.addPoint((int) ((transY0 + transY1) / 2.0), 440 (int) ((transX0 + transX1) / 2.0)); 441 hotspot.addPoint((int) transY1, (int) transX1); 442 hotspot.addPoint((int) ((transY1 + transY2) / 2.0), 443 (int) ((transX1 + transX2) / 2.0)); 444 hotspot.addPoint((int) transZero, 445 (int) ((transX1 + transX2) / 2.0)); 446 } 447 else { hotspot = new Polygon (); 449 hotspot.addPoint((int) ((transX0 + transX1) / 2.0), 450 (int) transZero); 451 hotspot.addPoint((int) ((transX0 + transX1) / 2.0), 452 (int) ((transY0 + transY1) / 2.0)); 453 hotspot.addPoint((int) transX1, (int) transY1); 454 hotspot.addPoint((int) ((transX1 + transX2) / 2.0), 455 (int) ((transY1 + transY2) / 2.0)); 456 hotspot.addPoint((int) ((transX1 + transX2) / 2.0), 457 (int) transZero); 458 } 459 460 if (item == 0) { areaState.area = new Polygon (); 462 double zero = rangeAxis.valueToJava2D(0.0, dataArea, 464 plot.getRangeAxisEdge()); 465 if (plot.getOrientation() == PlotOrientation.VERTICAL) { 466 areaState.area.addPoint((int) transX1, (int) zero); 467 } 468 else if (plot.getOrientation() == PlotOrientation.HORIZONTAL) { 469 areaState.area.addPoint((int) zero, (int) transX1); 470 } 471 } 472 473 if (plot.getOrientation() == PlotOrientation.VERTICAL) { 475 areaState.area.addPoint((int) transX1, (int) transY1); 476 } 477 else if (plot.getOrientation() == PlotOrientation.HORIZONTAL) { 478 areaState.area.addPoint((int) transY1, (int) transX1); 479 } 480 481 PlotOrientation orientation = plot.getOrientation(); 482 Paint paint = getItemPaint(series, item); 483 Stroke stroke = getItemStroke(series, item); 484 g2.setPaint(paint); 485 g2.setStroke(stroke); 486 487 Shape shape = null; 488 if (getPlotShapes()) { 489 shape = getItemShape(series, item); 490 if (orientation == PlotOrientation.VERTICAL) { 491 shape = ShapeUtilities.createTranslatedShape(shape, transX1, 492 transY1); 493 } 494 else if (orientation == PlotOrientation.HORIZONTAL) { 495 shape = ShapeUtilities.createTranslatedShape(shape, transY1, 496 transX1); 497 } 498 g2.draw(shape); 499 } 500 501 if (getPlotLines()) { 502 if (item > 0) { 503 if (plot.getOrientation() == PlotOrientation.VERTICAL) { 504 areaState.line.setLine(transX0, transY0, transX1, transY1); 505 } 506 else if (plot.getOrientation() == PlotOrientation.HORIZONTAL) { 507 areaState.line.setLine(transY0, transX0, transY1, transX1); 508 } 509 g2.draw(areaState.line); 510 } 511 } 512 513 if (getPlotArea() && item > 0 && item == (itemCount - 1)) { 516 517 if (orientation == PlotOrientation.VERTICAL) { 518 areaState.area.addPoint((int) transX1, (int) transZero); 520 } 521 else if (orientation == PlotOrientation.HORIZONTAL) { 522 areaState.area.addPoint((int) transZero, (int) transX1); 524 } 525 526 g2.fill(areaState.area); 527 528 if (isOutline()) { 530 g2.setStroke(getItemOutlineStroke(series, item)); 531 g2.setPaint(getItemOutlinePaint(series, item)); 532 g2.draw(areaState.area); 533 } 534 } 535 536 updateCrosshairValues( 537 crosshairState, x1, y1, transX1, transY1, orientation 538 ); 539 540 if (state.getInfo() != null) { 542 EntityCollection entities = state.getEntityCollection(); 543 if (entities != null && hotspot != null) { 544 String tip = null; 545 XYToolTipGenerator generator 546 = getToolTipGenerator(series, item); 547 if (generator != null) { 548 tip = generator.generateToolTip(dataset, series, item); 549 } 550 String url = null; 551 if (getURLGenerator() != null) { 552 url = getURLGenerator().generateURL(dataset, series, item); 553 } 554 XYItemEntity entity = new XYItemEntity(hotspot, dataset, 555 series, item, tip, url); 556 entities.add(entity); 557 } 558 } 559 560 } 561 562 569 public Object clone() throws CloneNotSupportedException { 570 return super.clone(); 571 } 572 573 580 public boolean equals(Object obj) { 581 if (obj == this) { 582 return true; 583 } 584 if (!(obj instanceof XYAreaRenderer)) { 585 return false; 586 } 587 XYAreaRenderer that = (XYAreaRenderer) obj; 588 if (this.plotArea != that.plotArea) { 589 return false; 590 } 591 if (this.plotLines != that.plotLines) { 592 return false; 593 } 594 if (this.plotShapes != that.plotShapes) { 595 return false; 596 } 597 if (this.showOutline != that.showOutline) { 598 return false; 599 } 600 if (!ShapeUtilities.equal(this.legendArea, that.legendArea)) { 601 return false; 602 } 603 return true; 604 } 605 606 614 private void readObject(ObjectInputStream stream) 615 throws IOException , ClassNotFoundException { 616 stream.defaultReadObject(); 617 this.legendArea = SerialUtilities.readShape(stream); 618 } 619 620 627 private void writeObject(ObjectOutputStream stream) throws IOException { 628 stream.defaultWriteObject(); 629 SerialUtilities.writeShape(this.legendArea, stream); 630 } 631 } 632 | Popular Tags |