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