1 67 68 package org.jfree.chart.renderer.xy; 69 70 import java.awt.Graphics2D ; 71 import java.awt.Paint ; 72 import java.awt.Shape ; 73 import java.awt.Stroke ; 74 import java.awt.geom.Line2D ; 75 import java.awt.geom.Rectangle2D ; 76 import java.io.IOException ; 77 import java.io.ObjectInputStream ; 78 import java.io.ObjectOutputStream ; 79 import java.io.Serializable ; 80 81 import org.jfree.chart.axis.ValueAxis; 82 import org.jfree.chart.entity.EntityCollection; 83 import org.jfree.chart.entity.XYItemEntity; 84 import org.jfree.chart.event.RendererChangeEvent; 85 import org.jfree.chart.labels.XYToolTipGenerator; 86 import org.jfree.chart.plot.CrosshairState; 87 import org.jfree.chart.plot.PlotOrientation; 88 import org.jfree.chart.plot.PlotRenderingInfo; 89 import org.jfree.chart.plot.XYPlot; 90 import org.jfree.data.xy.OHLCDataset; 91 import org.jfree.data.xy.XYDataset; 92 import org.jfree.io.SerialUtilities; 93 import org.jfree.ui.RectangleEdge; 94 import org.jfree.util.PaintUtilities; 95 import org.jfree.util.PublicCloneable; 96 97 102 public class HighLowRenderer extends AbstractXYItemRenderer 103 implements XYItemRenderer, 104 Cloneable , 105 PublicCloneable, 106 Serializable { 107 108 109 private static final long serialVersionUID = -8135673815876552516L; 110 111 112 private boolean drawOpenTicks; 113 114 115 private boolean drawCloseTicks; 116 117 121 private transient Paint openTickPaint; 122 123 127 private transient Paint closeTickPaint; 128 129 132 public HighLowRenderer() { 133 super(); 134 this.drawOpenTicks = true; 135 this.drawCloseTicks = true; 136 } 137 138 143 public boolean getDrawOpenTicks() { 144 return this.drawOpenTicks; 145 } 146 147 153 public void setDrawOpenTicks(boolean draw) { 154 this.drawOpenTicks = draw; 155 notifyListeners(new RendererChangeEvent(this)); 156 } 157 158 163 public boolean getDrawCloseTicks() { 164 return this.drawCloseTicks; 165 } 166 167 173 public void setDrawCloseTicks(boolean draw) { 174 this.drawCloseTicks = draw; 175 notifyListeners(new RendererChangeEvent(this)); 176 } 177 178 184 public Paint getOpenTickPaint() { 185 return this.openTickPaint; 186 } 187 188 196 public void setOpenTickPaint(Paint paint) { 197 this.openTickPaint = paint; 198 notifyListeners(new RendererChangeEvent(this)); 199 } 200 201 207 public Paint getCloseTickPaint() { 208 return this.closeTickPaint; 209 } 210 211 219 public void setCloseTickPaint(Paint paint) { 220 this.closeTickPaint = paint; 221 notifyListeners(new RendererChangeEvent(this)); 222 } 223 224 242 public void drawItem(Graphics2D g2, 243 XYItemRendererState state, 244 Rectangle2D dataArea, 245 PlotRenderingInfo info, 246 XYPlot plot, 247 ValueAxis domainAxis, 248 ValueAxis rangeAxis, 249 XYDataset dataset, 250 int series, 251 int item, 252 CrosshairState crosshairState, 253 int pass) { 254 255 double x = dataset.getXValue(series, item); 256 if (!domainAxis.getRange().contains(x)) { 257 return; } 259 double xx = domainAxis.valueToJava2D(x, dataArea, 260 plot.getDomainAxisEdge()); 261 262 Shape entityArea = null; 264 EntityCollection entities = null; 265 if (info != null) { 266 entities = info.getOwner().getEntityCollection(); 267 } 268 269 PlotOrientation orientation = plot.getOrientation(); 270 RectangleEdge location = plot.getRangeAxisEdge(); 271 272 Paint itemPaint = getItemPaint(series, item); 273 Stroke itemStroke = getItemStroke(series, item); 274 g2.setPaint(itemPaint); 275 g2.setStroke(itemStroke); 276 277 if (dataset instanceof OHLCDataset) { 278 OHLCDataset hld = (OHLCDataset) dataset; 279 280 double yHigh = hld.getHighValue(series, item); 281 double yLow = hld.getLowValue(series, item); 282 if (!Double.isNaN(yHigh) && !Double.isNaN(yLow)) { 283 double yyHigh = rangeAxis.valueToJava2D(yHigh, dataArea, 284 location); 285 double yyLow = rangeAxis.valueToJava2D(yLow, dataArea, 286 location); 287 if (orientation == PlotOrientation.HORIZONTAL) { 288 g2.draw(new Line2D.Double (yyLow, xx, yyHigh, xx)); 289 entityArea = new Rectangle2D.Double (Math.min(yyLow, yyHigh), 290 xx - 1.0, Math.abs(yyHigh - yyLow), 2.0); 291 } 292 else if (orientation == PlotOrientation.VERTICAL) { 293 g2.draw(new Line2D.Double (xx, yyLow, xx, yyHigh)); 294 entityArea = new Rectangle2D.Double (xx - 1.0, 295 Math.min(yyLow, yyHigh), 2.0, 296 Math.abs(yyHigh - yyLow)); 297 } 298 } 299 300 double delta = 2.0; 301 if (domainAxis.isInverted()) { 302 delta = -delta; 303 } 304 if (getDrawOpenTicks()) { 305 double yOpen = hld.getOpenValue(series, item); 306 if (!Double.isNaN(yOpen)) { 307 double yyOpen = rangeAxis.valueToJava2D(yOpen, dataArea, 308 location); 309 if (this.openTickPaint != null) { 310 g2.setPaint(this.openTickPaint); 311 } 312 else { 313 g2.setPaint(itemPaint); 314 } 315 if (orientation == PlotOrientation.HORIZONTAL) { 316 g2.draw(new Line2D.Double (yyOpen, xx + delta, yyOpen, 317 xx)); 318 } 319 else if (orientation == PlotOrientation.VERTICAL) { 320 g2.draw(new Line2D.Double (xx - delta, yyOpen, xx, 321 yyOpen)); 322 } 323 } 324 } 325 326 if (getDrawCloseTicks()) { 327 double yClose = hld.getCloseValue(series, item); 328 if (!Double.isNaN(yClose)) { 329 double yyClose = rangeAxis.valueToJava2D( 330 yClose, dataArea, location); 331 if (this.closeTickPaint != null) { 332 g2.setPaint(this.closeTickPaint); 333 } 334 else { 335 g2.setPaint(itemPaint); 336 } 337 if (orientation == PlotOrientation.HORIZONTAL) { 338 g2.draw(new Line2D.Double (yyClose, xx, yyClose, 339 xx - delta)); 340 } 341 else if (orientation == PlotOrientation.VERTICAL) { 342 g2.draw(new Line2D.Double (xx, yyClose, xx + delta, 343 yyClose)); 344 } 345 } 346 } 347 348 } 349 else { 350 if (item > 0) { 353 double x0 = dataset.getXValue(series, item - 1); 354 double y0 = dataset.getYValue(series, item - 1); 355 double y = dataset.getYValue(series, item); 356 if (Double.isNaN(x0) || Double.isNaN(y0) || Double.isNaN(y)) { 357 return; 358 } 359 double xx0 = domainAxis.valueToJava2D(x0, dataArea, 360 plot.getDomainAxisEdge()); 361 double yy0 = rangeAxis.valueToJava2D(y0, dataArea, location); 362 double yy = rangeAxis.valueToJava2D(y, dataArea, location); 363 if (orientation == PlotOrientation.HORIZONTAL) { 364 g2.draw(new Line2D.Double (yy0, xx0, yy, xx)); 365 } 366 else if (orientation == PlotOrientation.VERTICAL) { 367 g2.draw(new Line2D.Double (xx0, yy0, xx, yy)); 368 } 369 } 370 } 371 372 if (entities != null) { 374 String tip = null; 375 XYToolTipGenerator generator = getToolTipGenerator(series, item); 376 if (generator != null) { 377 tip = generator.generateToolTip(dataset, series, item); 378 } 379 String url = null; 380 if (getURLGenerator() != null) { 381 url = getURLGenerator().generateURL(dataset, series, item); 382 } 383 XYItemEntity entity = new XYItemEntity(entityArea, dataset, 384 series, item, tip, url); 385 entities.add(entity); 386 } 387 388 } 389 390 397 public Object clone() throws CloneNotSupportedException { 398 return super.clone(); 399 } 400 401 408 public boolean equals(Object obj) { 409 if (this == obj) { 410 return true; 411 } 412 if (!(obj instanceof HighLowRenderer)) { 413 return false; 414 } 415 HighLowRenderer that = (HighLowRenderer) obj; 416 if (this.drawOpenTicks != that.drawOpenTicks) { 417 return false; 418 } 419 if (this.drawCloseTicks != that.drawCloseTicks) { 420 return false; 421 } 422 if (!PaintUtilities.equal(this.openTickPaint, that.openTickPaint)) { 423 return false; 424 } 425 if (!PaintUtilities.equal(this.closeTickPaint, that.closeTickPaint)) { 426 return false; 427 } 428 if (!super.equals(obj)) { 429 return false; 430 } 431 return true; 432 } 433 434 442 private void readObject(ObjectInputStream stream) 443 throws IOException , ClassNotFoundException { 444 stream.defaultReadObject(); 445 this.openTickPaint = SerialUtilities.readPaint(stream); 446 this.closeTickPaint = SerialUtilities.readPaint(stream); 447 } 448 449 456 private void writeObject(ObjectOutputStream stream) throws IOException { 457 stream.defaultWriteObject(); 458 SerialUtilities.writePaint(this.openTickPaint, stream); 459 SerialUtilities.writePaint(this.closeTickPaint, stream); 460 } 461 462 } 463 | Popular Tags |