001/* =========================================================== 002 * JFreeChart : a free chart library for the Java(tm) platform 003 * =========================================================== 004 * 005 * (C) Copyright 2000-2013, 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 * [Oracle and Java are registered trademarks of Oracle and/or its affiliates. 025 * Other names may be trademarks of their respective owners.] 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 053package org.jfree.chart.axis; 054 055import java.awt.BasicStroke; 056import java.awt.Graphics2D; 057import java.awt.Paint; 058import java.awt.RenderingHints; 059import java.awt.Stroke; 060import java.awt.geom.Line2D; 061import java.awt.geom.Rectangle2D; 062import java.io.Serializable; 063 064import org.jfree.chart.plot.ColorPalette; 065import org.jfree.chart.plot.ContourPlot; 066import org.jfree.chart.plot.Plot; 067import org.jfree.chart.plot.RainbowPalette; 068import org.jfree.chart.plot.XYPlot; 069import org.jfree.chart.renderer.xy.XYBlockRenderer; 070import 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 */ 079public 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 Rectangle2D colorBarArea = null; 195 196 double thickness = calculateBarThickness(dataArea, edge); 197 if (this.colorBarThickness > 0) { 198 thickness = this.colorBarThickness; // allow fixed thickness 199 } 200 201 double length; 202 if (RectangleEdge.isLeftOrRight(edge)) { 203 length = dataArea.getHeight(); 204 } 205 else { 206 length = dataArea.getWidth(); 207 } 208 209 if (this.colorBarLength > 0) { 210 length = this.colorBarLength; 211 } 212 213 if (edge == RectangleEdge.BOTTOM) { 214 colorBarArea = new Rectangle2D.Double(dataArea.getX(), 215 plotArea.getMaxY() + this.outerGap, length, thickness); 216 } 217 else if (edge == RectangleEdge.TOP) { 218 colorBarArea = new Rectangle2D.Double(dataArea.getX(), 219 reservedArea.getMinY() + this.outerGap, length, thickness); 220 } 221 else if (edge == RectangleEdge.LEFT) { 222 colorBarArea = new Rectangle2D.Double(plotArea.getX() - thickness 223 - this.outerGap, dataArea.getMinY(), thickness, length); 224 } 225 else if (edge == RectangleEdge.RIGHT) { 226 colorBarArea = new Rectangle2D.Double(plotArea.getMaxX() 227 + this.outerGap, dataArea.getMinY(), thickness, length); 228 } 229 230 // update, but dont draw tick marks (needed for stepped colors) 231 this.axis.refreshTicks(g2, new AxisState(), colorBarArea, edge); 232 233 drawColorBar(g2, colorBarArea, edge); 234 235 AxisState state = null; 236 assert colorBarArea != null; // suppresses compiler warnings 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 assert state != null; // suppresses compiler warning 258 return state.getCursor(); 259 260 } 261 262 /** 263 * Draws the plot on a Java 2D graphics device (such as the screen or a 264 * printer). 265 * 266 * @param g2 the graphics device. 267 * @param colorBarArea the area within which the axis should be drawn. 268 * @param edge the location. 269 */ 270 public void drawColorBar(Graphics2D g2, Rectangle2D colorBarArea, 271 RectangleEdge edge) { 272 273 Object antiAlias = g2.getRenderingHint(RenderingHints.KEY_ANTIALIASING); 274 g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 275 RenderingHints.VALUE_ANTIALIAS_OFF); 276 277 // setTickValues was missing from ColorPalette v. 0.96 278 //colorPalette.setTickValues(this.axis.getTicks()); 279 280 Stroke strokeSaved = g2.getStroke(); 281 g2.setStroke(new BasicStroke(1.0f)); 282 283 if (RectangleEdge.isTopOrBottom(edge)) { 284 double y1 = colorBarArea.getY(); 285 double y2 = colorBarArea.getMaxY(); 286 double xx = colorBarArea.getX(); 287 Line2D line = new Line2D.Double(); 288 while (xx <= colorBarArea.getMaxX()) { 289 double value = this.axis.java2DToValue(xx, colorBarArea, edge); 290 line.setLine(xx, y1, xx, y2); 291 g2.setPaint(getPaint(value)); 292 g2.draw(line); 293 xx += 1; 294 } 295 } 296 else { 297 double y1 = colorBarArea.getX(); 298 double y2 = colorBarArea.getMaxX(); 299 double xx = colorBarArea.getY(); 300 Line2D line = new Line2D.Double(); 301 while (xx <= colorBarArea.getMaxY()) { 302 double value = this.axis.java2DToValue(xx, colorBarArea, edge); 303 line.setLine(y1, xx, y2, xx); 304 g2.setPaint(getPaint(value)); 305 g2.draw(line); 306 xx += 1; 307 } 308 } 309 310 g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, antiAlias); 311 g2.setStroke(strokeSaved); 312 313 } 314 315 /** 316 * Returns the color palette. 317 * 318 * @return The color palette. 319 */ 320 public ColorPalette getColorPalette() { 321 return this.colorPalette; 322 } 323 324 /** 325 * Returns the Paint associated with a value. 326 * 327 * @param value the value. 328 * 329 * @return The paint. 330 */ 331 public Paint getPaint(double value) { 332 return this.colorPalette.getPaint(value); 333 } 334 335 /** 336 * Sets the color palette. 337 * 338 * @param palette the new palette. 339 */ 340 public void setColorPalette(ColorPalette palette) { 341 this.colorPalette = palette; 342 } 343 344 /** 345 * Sets the maximum value. 346 * 347 * @param value the maximum value. 348 */ 349 public void setMaximumValue(double value) { 350 this.colorPalette.setMaxZ(value); 351 this.axis.setUpperBound(value); 352 } 353 354 /** 355 * Sets the minimum value. 356 * 357 * @param value the minimum value. 358 */ 359 public void setMinimumValue(double value) { 360 this.colorPalette.setMinZ(value); 361 this.axis.setLowerBound(value); 362 } 363 364 /** 365 * Reserves the space required to draw the color bar. 366 * 367 * @param g2 the graphics device. 368 * @param plot the plot that the axis belongs to. 369 * @param plotArea the area within which the plot should be drawn. 370 * @param dataArea the data area. 371 * @param edge the axis location. 372 * @param space the space already reserved. 373 * 374 * @return The space required to draw the axis in the specified plot area. 375 */ 376 public AxisSpace reserveSpace(Graphics2D g2, Plot plot, 377 Rectangle2D plotArea, 378 Rectangle2D dataArea, RectangleEdge edge, 379 AxisSpace space) { 380 381 AxisSpace result = this.axis.reserveSpace(g2, plot, plotArea, edge, 382 space); 383 double thickness = calculateBarThickness(dataArea, edge); 384 result.add(thickness + 2 * this.outerGap, edge); 385 return result; 386 387 } 388 389 /** 390 * Calculates the bar thickness. 391 * 392 * @param plotArea the plot area. 393 * @param edge the location. 394 * 395 * @return The thickness. 396 */ 397 private double calculateBarThickness(Rectangle2D plotArea, 398 RectangleEdge edge) { 399 double result; 400 if (RectangleEdge.isLeftOrRight(edge)) { 401 result = plotArea.getWidth() * this.colorBarThicknessPercent; 402 } 403 else { 404 result = plotArea.getHeight() * this.colorBarThicknessPercent; 405 } 406 return result; 407 } 408 409 /** 410 * Returns a clone of the object. 411 * 412 * @return A clone. 413 * 414 * @throws CloneNotSupportedException if some component of the color bar 415 * does not support cloning. 416 */ 417 @Override 418 public Object clone() throws CloneNotSupportedException { 419 ColorBar clone = (ColorBar) super.clone(); 420 clone.axis = (ValueAxis) this.axis.clone(); 421 return clone; 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 @Override 432 public boolean equals(Object obj) { 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 * Returns a hash code for this object. 463 * 464 * @return A hash code. 465 */ 466 @Override 467 public int hashCode() { 468 return this.axis.hashCode(); 469 } 470 471}