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