001 /* =========================================================== 002 * JFreeChart : a free chart library for the Java(tm) platform 003 * =========================================================== 004 * 005 * (C) Copyright 2000-2007, by Object Refinery Limited and Contributors. 006 * 007 * Project Info: http://www.jfree.org/jfreechart/index.html 008 * 009 * This library is free software; you can redistribute it and/or modify it 010 * under the terms of the GNU Lesser General Public License as published by 011 * the Free Software Foundation; either version 2.1 of the License, or 012 * (at your option) any later version. 013 * 014 * This library is distributed in the hope that it will be useful, but 015 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 016 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 017 * License for more details. 018 * 019 * You should have received a copy of the GNU Lesser General Public 020 * License along with this library; if not, write to the Free Software 021 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 022 * USA. 023 * 024 * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 025 * in the United States and other countries.] 026 * 027 * ------------- 028 * ColorBar.java 029 * ------------- 030 * (C) Copyright 2002-2007, by David M. O'Donnell and Contributors. 031 * 032 * Original Author: David M. O'Donnell; 033 * Contributor(s): David Gilbert (for Object Refinery Limited); 034 * 035 * $Id: ColorBar.java,v 1.6.2.3 2007/01/31 15:56:18 mungady Exp $ 036 * 037 * Changes 038 * ------- 039 * 26-Nov-2002 : Version 1 contributed by David M. O'Donnell (DG); 040 * 14-Jan-2003 : Changed autoRangeMinimumSize from Number --> double (DG); 041 * 17-Jan-2003 : Moved plot classes to separate package (DG); 042 * 20-Jan-2003 : Removed unnecessary constructors (DG); 043 * 26-Mar-2003 : Implemented Serializable (DG); 044 * 09-Jul-2003 : Changed ColorBar from extending axis classes to enclosing 045 * them (DG); 046 * 05-Aug-2003 : Applied changes in bug report 780298 (DG); 047 * 14-Aug-2003 : Implemented Cloneable (DG); 048 * 08-Sep-2003 : Changed ValueAxis API (DG); 049 * 21-Jan-2004 : Update for renamed method in ValueAxis (DG); 050 * ------------- JFREECHART 1.0.x --------------------------------------------- 051 * 31-Jan-2007 : Deprecated (DG); 052 * 053 */ 054 055 package org.jfree.chart.axis; 056 057 import java.awt.BasicStroke; 058 import java.awt.Graphics2D; 059 import java.awt.Paint; 060 import java.awt.RenderingHints; 061 import java.awt.Stroke; 062 import java.awt.geom.Line2D; 063 import java.awt.geom.Rectangle2D; 064 import java.io.Serializable; 065 066 import org.jfree.chart.plot.ColorPalette; 067 import org.jfree.chart.plot.ContourPlot; 068 import org.jfree.chart.plot.Plot; 069 import org.jfree.chart.plot.RainbowPalette; 070 import org.jfree.chart.plot.XYPlot; 071 import org.jfree.chart.renderer.xy.XYBlockRenderer; 072 import org.jfree.ui.RectangleEdge; 073 074 /** 075 * A color bar. 076 * 077 * @deprecated This class is no longer supported. If you are creating 078 * contour plots, please try to use {@link XYPlot} and 079 * {@link XYBlockRenderer}. 080 */ 081 public class ColorBar implements Cloneable, Serializable { 082 083 /** For serialization. */ 084 private static final long serialVersionUID = -2101776212647268103L; 085 086 /** The default color bar thickness. */ 087 public static final int DEFAULT_COLORBAR_THICKNESS = 0; 088 089 /** The default color bar thickness percentage. */ 090 public static final double DEFAULT_COLORBAR_THICKNESS_PERCENT = 0.10; 091 092 /** The default outer gap. */ 093 public static final int DEFAULT_OUTERGAP = 2; 094 095 /** The axis. */ 096 private ValueAxis axis; 097 098 /** The color bar thickness. */ 099 private int colorBarThickness = DEFAULT_COLORBAR_THICKNESS; 100 101 /** 102 * The color bar thickness as a percentage of the height of the data area. 103 */ 104 private double colorBarThicknessPercent 105 = DEFAULT_COLORBAR_THICKNESS_PERCENT; 106 107 /** The color palette. */ 108 private ColorPalette colorPalette = null; 109 110 /** The color bar length. */ 111 private int colorBarLength = 0; // default make height of plotArea 112 113 /** The amount of blank space around the colorbar. */ 114 private int outerGap; 115 116 /** 117 * Constructs a horizontal colorbar axis, using default values where 118 * necessary. 119 * 120 * @param label the axis label. 121 */ 122 public ColorBar(String label) { 123 124 NumberAxis a = new NumberAxis(label); 125 a.setAutoRangeIncludesZero(false); 126 this.axis = a; 127 this.axis.setLowerMargin(0.0); 128 this.axis.setUpperMargin(0.0); 129 130 this.colorPalette = new RainbowPalette(); 131 this.colorBarThickness = DEFAULT_COLORBAR_THICKNESS; 132 this.colorBarThicknessPercent = DEFAULT_COLORBAR_THICKNESS_PERCENT; 133 this.outerGap = DEFAULT_OUTERGAP; 134 this.colorPalette.setMinZ(this.axis.getRange().getLowerBound()); 135 this.colorPalette.setMaxZ(this.axis.getRange().getUpperBound()); 136 137 } 138 139 /** 140 * Configures the color bar. 141 * 142 * @param plot the plot. 143 */ 144 public void configure(ContourPlot plot) { 145 double minZ = plot.getDataset().getMinZValue(); 146 double maxZ = plot.getDataset().getMaxZValue(); 147 setMinimumValue(minZ); 148 setMaximumValue(maxZ); 149 } 150 151 /** 152 * Returns the axis. 153 * 154 * @return The axis. 155 */ 156 public ValueAxis getAxis() { 157 return this.axis; 158 } 159 160 /** 161 * Sets the axis. 162 * 163 * @param axis the axis. 164 */ 165 public void setAxis(ValueAxis axis) { 166 this.axis = axis; 167 } 168 169 /** 170 * Rescales the axis to ensure that all data are visible. 171 */ 172 public void autoAdjustRange() { 173 this.axis.autoAdjustRange(); 174 this.colorPalette.setMinZ(this.axis.getLowerBound()); 175 this.colorPalette.setMaxZ(this.axis.getUpperBound()); 176 } 177 178 /** 179 * Draws the plot on a Java 2D graphics device (such as the screen or a 180 * printer). 181 * 182 * @param g2 the graphics device. 183 * @param cursor the cursor. 184 * @param plotArea the area within which the chart should be drawn. 185 * @param dataArea the area within which the plot should be drawn (a 186 * subset of the drawArea). 187 * @param reservedArea the reserved area. 188 * @param edge the color bar location. 189 * 190 * @return The new cursor location. 191 */ 192 public double draw(Graphics2D g2, double cursor, 193 Rectangle2D plotArea, Rectangle2D dataArea, 194 Rectangle2D reservedArea, RectangleEdge edge) { 195 196 197 Rectangle2D colorBarArea = null; 198 199 double thickness = calculateBarThickness(dataArea, edge); 200 if (this.colorBarThickness > 0) { 201 thickness = this.colorBarThickness; // allow fixed thickness 202 } 203 204 double length = 0.0; 205 if (RectangleEdge.isLeftOrRight(edge)) { 206 length = dataArea.getHeight(); 207 } 208 else { 209 length = dataArea.getWidth(); 210 } 211 212 if (this.colorBarLength > 0) { 213 length = this.colorBarLength; 214 } 215 216 if (edge == RectangleEdge.BOTTOM) { 217 colorBarArea = new Rectangle2D.Double( 218 dataArea.getX(), plotArea.getMaxY() + this.outerGap, 219 length, thickness 220 ); 221 } 222 else if (edge == RectangleEdge.TOP) { 223 colorBarArea = new Rectangle2D.Double( 224 dataArea.getX(), reservedArea.getMinY() + this.outerGap, 225 length, thickness 226 ); 227 } 228 else if (edge == RectangleEdge.LEFT) { 229 colorBarArea = new Rectangle2D.Double( 230 plotArea.getX() - thickness - this.outerGap , 231 dataArea.getMinY(), thickness, length 232 ); 233 } 234 else if (edge == RectangleEdge.RIGHT) { 235 colorBarArea = new Rectangle2D.Double( 236 plotArea.getMaxX() + this.outerGap, dataArea.getMinY(), 237 thickness, length 238 ); 239 } 240 241 // update, but dont draw tick marks (needed for stepped colors) 242 this.axis.refreshTicks( 243 g2, new AxisState(), colorBarArea, edge 244 ); 245 246 drawColorBar(g2, colorBarArea, edge); 247 248 AxisState state = null; 249 if (edge == RectangleEdge.TOP) { 250 cursor = colorBarArea.getMinY(); 251 state = this.axis.draw( 252 g2, cursor, reservedArea, colorBarArea, RectangleEdge.TOP, null 253 ); 254 } 255 else if (edge == RectangleEdge.BOTTOM) { 256 cursor = colorBarArea.getMaxY(); 257 state = this.axis.draw( 258 g2, cursor, reservedArea, colorBarArea, RectangleEdge.BOTTOM, 259 null 260 ); 261 } 262 else if (edge == RectangleEdge.LEFT) { 263 cursor = colorBarArea.getMinX(); 264 state = this.axis.draw( 265 g2, cursor, reservedArea, colorBarArea, RectangleEdge.LEFT, null 266 ); 267 } 268 else if (edge == RectangleEdge.RIGHT) { 269 cursor = colorBarArea.getMaxX(); 270 state = this.axis.draw( 271 g2, cursor, reservedArea, colorBarArea, RectangleEdge.RIGHT, 272 null 273 ); 274 } 275 return state.getCursor(); 276 277 } 278 279 /** 280 * Draws the plot on a Java 2D graphics device (such as the screen or a 281 * printer). 282 * 283 * @param g2 the graphics device. 284 * @param colorBarArea the area within which the axis should be drawn. 285 * @param edge the location. 286 */ 287 public void drawColorBar(Graphics2D g2, Rectangle2D colorBarArea, 288 RectangleEdge edge) { 289 290 Object antiAlias = g2.getRenderingHint(RenderingHints.KEY_ANTIALIASING); 291 g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 292 RenderingHints.VALUE_ANTIALIAS_OFF); 293 294 // setTickValues was missing from ColorPalette v. 0.96 295 //colorPalette.setTickValues(this.axis.getTicks()); 296 297 Stroke strokeSaved = g2.getStroke(); 298 g2.setStroke(new BasicStroke(1.0f)); 299 300 if (RectangleEdge.isTopOrBottom(edge)) { 301 double y1 = colorBarArea.getY(); 302 double y2 = colorBarArea.getMaxY(); 303 double xx = colorBarArea.getX(); 304 Line2D line = new Line2D.Double(); 305 while (xx <= colorBarArea.getMaxX()) { 306 double value = this.axis.java2DToValue(xx, colorBarArea, edge); 307 line.setLine(xx, y1, xx, y2); 308 g2.setPaint(getPaint(value)); 309 g2.draw(line); 310 xx += 1; 311 } 312 } 313 else { 314 double y1 = colorBarArea.getX(); 315 double y2 = colorBarArea.getMaxX(); 316 double xx = colorBarArea.getY(); 317 Line2D line = new Line2D.Double(); 318 while (xx <= colorBarArea.getMaxY()) { 319 double value = this.axis.java2DToValue(xx, colorBarArea, edge); 320 line.setLine(y1, xx, y2, xx); 321 g2.setPaint(getPaint(value)); 322 g2.draw(line); 323 xx += 1; 324 } 325 } 326 327 g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, antiAlias); 328 g2.setStroke(strokeSaved); 329 330 } 331 332 /** 333 * Returns the color palette. 334 * 335 * @return The color palette. 336 */ 337 public ColorPalette getColorPalette() { 338 return this.colorPalette; 339 } 340 341 /** 342 * Returns the Paint associated with a value. 343 * 344 * @param value the value. 345 * 346 * @return The paint. 347 */ 348 public Paint getPaint(double value) { 349 return this.colorPalette.getPaint(value); 350 } 351 352 /** 353 * Sets the color palette. 354 * 355 * @param palette the new palette. 356 */ 357 public void setColorPalette(ColorPalette palette) { 358 this.colorPalette = palette; 359 } 360 361 /** 362 * Sets the maximum value. 363 * 364 * @param value the maximum value. 365 */ 366 public void setMaximumValue(double value) { 367 this.colorPalette.setMaxZ(value); 368 this.axis.setUpperBound(value); 369 } 370 371 /** 372 * Sets the minimum value. 373 * 374 * @param value the minimum value. 375 */ 376 public void setMinimumValue(double value) { 377 this.colorPalette.setMinZ(value); 378 this.axis.setLowerBound(value); 379 } 380 381 /** 382 * Reserves the space required to draw the color bar. 383 * 384 * @param g2 the graphics device. 385 * @param plot the plot that the axis belongs to. 386 * @param plotArea the area within which the plot should be drawn. 387 * @param dataArea the data area. 388 * @param edge the axis location. 389 * @param space the space already reserved. 390 * 391 * @return The space required to draw the axis in the specified plot area. 392 */ 393 public AxisSpace reserveSpace(Graphics2D g2, Plot plot, 394 Rectangle2D plotArea, 395 Rectangle2D dataArea, RectangleEdge edge, 396 AxisSpace space) { 397 398 AxisSpace result = this.axis.reserveSpace( 399 g2, plot, plotArea, edge, space 400 ); 401 double thickness = calculateBarThickness(dataArea, edge); 402 result.add(thickness + 2 * this.outerGap, edge); 403 return result; 404 405 } 406 407 /** 408 * Calculates the bar thickness. 409 * 410 * @param plotArea the plot area. 411 * @param edge the location. 412 * 413 * @return The thickness. 414 */ 415 private double calculateBarThickness(Rectangle2D plotArea, 416 RectangleEdge edge) { 417 double result = 0.0; 418 if (RectangleEdge.isLeftOrRight(edge)) { 419 result = plotArea.getWidth() * this.colorBarThicknessPercent; 420 } 421 else { 422 result = plotArea.getHeight() * this.colorBarThicknessPercent; 423 } 424 return result; 425 } 426 427 /** 428 * Returns a clone of the object. 429 * 430 * @return A clone. 431 * 432 * @throws CloneNotSupportedException if some component of the color bar 433 * does not support cloning. 434 */ 435 public Object clone() throws CloneNotSupportedException { 436 437 ColorBar clone = (ColorBar) super.clone(); 438 clone.axis = (ValueAxis) this.axis.clone(); 439 return clone; 440 441 } 442 443 /** 444 * Tests this object for equality with another. 445 * 446 * @param obj the object to test against. 447 * 448 * @return A boolean. 449 */ 450 public boolean equals(Object obj) { 451 452 if (obj == this) { 453 return true; 454 } 455 if (!(obj instanceof ColorBar)) { 456 return false; 457 } 458 ColorBar that = (ColorBar) obj; 459 if (!this.axis.equals(that.axis)) { 460 return false; 461 } 462 if (this.colorBarThickness != that.colorBarThickness) { 463 return false; 464 } 465 if (this.colorBarThicknessPercent != that.colorBarThicknessPercent) { 466 return false; 467 } 468 if (!this.colorPalette.equals(that.colorPalette)) { 469 return false; 470 } 471 if (this.colorBarLength != that.colorBarLength) { 472 return false; 473 } 474 if (this.outerGap != that.outerGap) { 475 return false; 476 } 477 return true; 478 479 } 480 481 /** 482 * Returns a hash code for this object. 483 * 484 * @return A hash code. 485 */ 486 public int hashCode() { 487 return this.axis.hashCode(); 488 } 489 490 }