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 * ColorPalette.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: ColorPalette.java,v 1.1.2.4 2007/03/19 16:20:24 mungady Exp $ 036 * 037 * Changes 038 * ------- 039 * 26-Nov-2002 : Version 1 contributed by David M. O'Donnell (DG); 040 * 26-Mar-2003 : Implemented Serializable (DG); 041 * 14-Aug-2003 : Implemented Cloneable (DG); 042 * ------------- JFREECHART 1.0.x --------------------------------------------- 043 * 31-Jan-2007 : Deprecated (DG); 044 * 045 */ 046 047 package org.jfree.chart.plot; 048 049 import java.awt.Color; 050 import java.awt.Paint; 051 import java.io.Serializable; 052 import java.util.Arrays; 053 054 import org.jfree.chart.axis.ValueTick; 055 import org.jfree.chart.renderer.xy.XYBlockRenderer; 056 057 /** 058 * Defines palette used by {@link ContourPlot}. 059 * 060 * @deprecated This class is no longer supported. If you are creating 061 * contour plots, please try to use {@link XYPlot} and 062 * {@link XYBlockRenderer}. 063 */ 064 public abstract class ColorPalette implements Cloneable, Serializable { 065 066 /** For serialization. */ 067 private static final long serialVersionUID = -9029901853079622051L; 068 069 /** The min z-axis value. */ 070 protected double minZ = -1; 071 072 /** The max z-axis value. */ 073 protected double maxZ = -1; 074 075 /** Red components. */ 076 protected int[] r; 077 078 /** Green components. */ 079 protected int[] g; 080 081 /** Blue components. */ 082 protected int[] b; 083 084 /** Tick values are stored for use with stepped palette. */ 085 protected double[] tickValues = null; 086 087 /** Logscale? */ 088 protected boolean logscale = false; 089 090 /** Inverse palette (ie, min and max colors are reversed). */ 091 protected boolean inverse = false; 092 093 /** The palette name. */ 094 protected String paletteName = null; 095 096 /** Controls whether palette colors are stepped (not continuous). */ 097 protected boolean stepped = false; 098 099 /** Constant for converting loge to log10. */ 100 protected static final double log10 = Math.log(10); 101 102 /** 103 * Default contructor. 104 */ 105 public ColorPalette() { 106 super(); 107 } 108 109 /** 110 * Returns the color associated with a value. 111 * 112 * @param value the value. 113 * 114 * @return The color. 115 */ 116 public Paint getColor(double value) { 117 int izV = (int) (253 * (value - this.minZ) 118 / (this.maxZ - this.minZ)) + 2; 119 return new Color(this.r[izV], this.g[izV], this.b[izV]); 120 } 121 122 /** 123 * Returns a color. 124 * 125 * @param izV the index into the palette (zero based). 126 * 127 * @return The color. 128 */ 129 public Color getColor(int izV) { 130 return new Color(this.r[izV], this.g[izV], this.b[izV]); 131 } 132 133 /** 134 * Returns Color by mapping a given value to a linear palette. 135 * 136 * @param value the value. 137 * 138 * @return The color. 139 */ 140 public Color getColorLinear(double value) { 141 int izV = 0; 142 if (this.stepped) { 143 int index = Arrays.binarySearch(this.tickValues, value); 144 if (index < 0) { 145 index = -1 * index - 2; 146 } 147 148 if (index < 0) { // For the case were the first tick is greater 149 // than minZ 150 value = this.minZ; 151 } 152 else { 153 value = this.tickValues[index]; 154 } 155 } 156 izV = (int) (253 * (value - this.minZ) / (this.maxZ - this.minZ)) + 2; 157 izV = Math.min(izV, 255); 158 izV = Math.max(izV, 2); 159 return getColor(izV); 160 } 161 162 /** 163 * Returns Color by mapping a given value to a common log palette. 164 * 165 * @param value the value. 166 * 167 * @return The color. 168 */ 169 public Color getColorLog(double value) { 170 int izV = 0; 171 double minZtmp = this.minZ; 172 double maxZtmp = this.maxZ; 173 if (this.minZ <= 0.0) { 174 // negatives = true; 175 this.maxZ = maxZtmp - minZtmp + 1; 176 this.minZ = 1; 177 value = value - minZtmp + 1; 178 } 179 double minZlog = Math.log(this.minZ) / log10; 180 double maxZlog = Math.log(this.maxZ) / log10; 181 value = Math.log(value) / log10; 182 // value = Math.pow(10,value); 183 if (this.stepped) { 184 int numSteps = this.tickValues.length; 185 int steps = 256 / (numSteps - 1); 186 izV = steps * (int) (numSteps * (value - minZlog) 187 / (maxZlog - minZlog)) + 2; 188 // izV = steps*numSteps*(int)((value/minZ)/(maxZlog-minZlog)) + 2; 189 } 190 else { 191 izV = (int) (253 * (value - minZlog) / (maxZlog - minZlog)) + 2; 192 } 193 izV = Math.min(izV, 255); 194 izV = Math.max(izV, 2); 195 196 this.minZ = minZtmp; 197 this.maxZ = maxZtmp; 198 199 return getColor(izV); 200 } 201 202 /** 203 * Returns the maximum Z value. 204 * 205 * @return The value. 206 */ 207 public double getMaxZ() { 208 return this.maxZ; 209 } 210 211 /** 212 * Returns the minimum Z value. 213 * 214 * @return The value. 215 */ 216 public double getMinZ() { 217 return this.minZ; 218 } 219 220 /** 221 * Returns Paint by mapping a given value to a either a linear or common 222 * log palette as controlled by the value logscale. 223 * 224 * @param value the value. 225 * 226 * @return The paint. 227 */ 228 public Paint getPaint(double value) { 229 if (isLogscale()) { 230 return getColorLog(value); 231 } 232 else { 233 return getColorLinear(value); 234 } 235 } 236 237 /** 238 * Returns the palette name. 239 * 240 * @return The palette name. 241 */ 242 public String getPaletteName () { 243 return this.paletteName; 244 } 245 246 /** 247 * Returns the tick values. 248 * 249 * @return The tick values. 250 */ 251 public double[] getTickValues() { 252 return this.tickValues; 253 } 254 255 /** 256 * Called to initialize the palette's color indexes 257 */ 258 public abstract void initialize(); 259 260 /** 261 * Inverts Palette 262 */ 263 public void invertPalette() { 264 265 int[] red = new int[256]; 266 int[] green = new int[256]; 267 int[] blue = new int[256]; 268 for (int i = 0; i < 256; i++) { 269 red[i] = this.r[i]; 270 green[i] = this.g[i]; 271 blue[i] = this.b[i]; 272 } 273 274 for (int i = 2; i < 256; i++) { 275 this.r[i] = red[257 - i]; 276 this.g[i] = green[257 - i]; 277 this.b[i] = blue[257 - i]; 278 } 279 } 280 281 /** 282 * Returns the inverse flag. 283 * 284 * @return The flag. 285 */ 286 public boolean isInverse () { 287 return this.inverse; 288 } 289 290 /** 291 * Returns the log-scale flag. 292 * 293 * @return The flag. 294 */ 295 public boolean isLogscale() { 296 return this.logscale; 297 } 298 299 /** 300 * Returns the 'is-stepped' flag. 301 * 302 * @return The flag. 303 */ 304 public boolean isStepped () { 305 return this.stepped; 306 } 307 308 /** 309 * Sets the inverse flag. 310 * 311 * @param inverse the new value. 312 */ 313 public void setInverse (boolean inverse) { 314 this.inverse = inverse; 315 initialize(); 316 if (inverse) { 317 invertPalette(); 318 } 319 return; 320 } 321 322 /** 323 * Sets the 'log-scale' flag. 324 * 325 * @param logscale the new value. 326 */ 327 public void setLogscale(boolean logscale) { 328 this.logscale = logscale; 329 } 330 331 /** 332 * Sets the maximum Z value. 333 * 334 * @param newMaxZ the new value. 335 */ 336 public void setMaxZ(double newMaxZ) { 337 this.maxZ = newMaxZ; 338 } 339 340 /** 341 * Sets the minimum Z value. 342 * 343 * @param newMinZ the new value. 344 */ 345 public void setMinZ(double newMinZ) { 346 this.minZ = newMinZ; 347 } 348 349 /** 350 * Sets the palette name. 351 * 352 * @param paletteName the name. 353 */ 354 public void setPaletteName (String paletteName) { 355 //String oldValue = this.paletteName; 356 this.paletteName = paletteName; 357 return; 358 } 359 360 /** 361 * Sets the stepped flag. 362 * 363 * @param stepped the flag. 364 */ 365 public void setStepped (boolean stepped) { 366 this.stepped = stepped; 367 return; 368 } 369 370 /** 371 * Sets the tick values. 372 * 373 * @param newTickValues the tick values. 374 */ 375 public void setTickValues(double[] newTickValues) { 376 this.tickValues = newTickValues; 377 } 378 379 /** 380 * Store ticks. Required when doing stepped axis 381 * 382 * @param ticks the ticks. 383 */ 384 public void setTickValues(java.util.List ticks) { 385 this.tickValues = new double[ticks.size()]; 386 for (int i = 0; i < this.tickValues.length; i++) { 387 this.tickValues[i] = ((ValueTick) ticks.get(i)).getValue(); 388 } 389 } 390 391 /** 392 * Tests an object for equality with this instance. 393 * 394 * @param o the object to test. 395 * 396 * @return A boolean. 397 */ 398 public boolean equals(Object o) { 399 if (this == o) { 400 return true; 401 } 402 if (!(o instanceof ColorPalette)) { 403 return false; 404 } 405 406 ColorPalette colorPalette = (ColorPalette) o; 407 408 if (this.inverse != colorPalette.inverse) { 409 return false; 410 } 411 if (this.logscale != colorPalette.logscale) { 412 return false; 413 } 414 if (this.maxZ != colorPalette.maxZ) { 415 return false; 416 } 417 if (this.minZ != colorPalette.minZ) { 418 return false; 419 } 420 if (this.stepped != colorPalette.stepped) { 421 return false; 422 } 423 if (!Arrays.equals(this.b, colorPalette.b)) { 424 return false; 425 } 426 if (!Arrays.equals(this.g, colorPalette.g)) { 427 return false; 428 } 429 if (this.paletteName != null 430 ? !this.paletteName.equals(colorPalette.paletteName) 431 : colorPalette.paletteName != null) { 432 return false; 433 } 434 if (!Arrays.equals(this.r, colorPalette.r)) { 435 return false; 436 } 437 if (!Arrays.equals(this.tickValues, colorPalette.tickValues)) { 438 return false; 439 } 440 441 return true; 442 } 443 444 /** 445 * Returns a hash code. 446 * 447 * @return A hash code. 448 */ 449 public int hashCode() { 450 int result; 451 long temp; 452 temp = Double.doubleToLongBits(this.minZ); 453 result = (int) (temp ^ (temp >>> 32)); 454 temp = Double.doubleToLongBits(this.maxZ); 455 result = 29 * result + (int) (temp ^ (temp >>> 32)); 456 result = 29 * result + (this.logscale ? 1 : 0); 457 result = 29 * result + (this.inverse ? 1 : 0); 458 result = 29 * result 459 + (this.paletteName != null ? this.paletteName.hashCode() : 0); 460 result = 29 * result + (this.stepped ? 1 : 0); 461 return result; 462 } 463 464 /** 465 * Returns a clone of the palette. 466 * 467 * @return A clone. 468 * 469 * @throws CloneNotSupportedException never. 470 */ 471 public Object clone() throws CloneNotSupportedException { 472 473 ColorPalette clone = (ColorPalette) super.clone(); 474 return clone; 475 476 } 477 478 }