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 * 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 045package org.jfree.chart.plot; 046 047import java.awt.Color; 048import java.awt.Paint; 049import java.io.Serializable; 050import java.util.Arrays; 051 052import org.jfree.chart.axis.ValueTick; 053import 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 */ 062public 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; 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; 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 } 318 319 /** 320 * Sets the 'log-scale' flag. 321 * 322 * @param logscale the new value. 323 */ 324 public void setLogscale(boolean logscale) { 325 this.logscale = logscale; 326 } 327 328 /** 329 * Sets the maximum Z value. 330 * 331 * @param newMaxZ the new value. 332 */ 333 public void setMaxZ(double newMaxZ) { 334 this.maxZ = newMaxZ; 335 } 336 337 /** 338 * Sets the minimum Z value. 339 * 340 * @param newMinZ the new value. 341 */ 342 public void setMinZ(double newMinZ) { 343 this.minZ = newMinZ; 344 } 345 346 /** 347 * Sets the palette name. 348 * 349 * @param paletteName the name. 350 */ 351 public void setPaletteName (String paletteName) { 352 this.paletteName = paletteName; 353 } 354 355 /** 356 * Sets the stepped flag. 357 * 358 * @param stepped the flag. 359 */ 360 public void setStepped (boolean stepped) { 361 this.stepped = stepped; 362 } 363 364 /** 365 * Sets the tick values. 366 * 367 * @param newTickValues the tick values. 368 */ 369 public void setTickValues(double[] newTickValues) { 370 this.tickValues = newTickValues; 371 } 372 373 /** 374 * Store ticks. Required when doing stepped axis 375 * 376 * @param ticks the ticks. 377 */ 378 public void setTickValues(java.util.List ticks) { 379 this.tickValues = new double[ticks.size()]; 380 for (int i = 0; i < this.tickValues.length; i++) { 381 this.tickValues[i] = ((ValueTick) ticks.get(i)).getValue(); 382 } 383 } 384 385 /** 386 * Tests an object for equality with this instance. 387 * 388 * @param o the object to test. 389 * 390 * @return A boolean. 391 */ 392 @Override 393 public boolean equals(Object o) { 394 if (this == o) { 395 return true; 396 } 397 if (!(o instanceof ColorPalette)) { 398 return false; 399 } 400 401 ColorPalette colorPalette = (ColorPalette) o; 402 403 if (this.inverse != colorPalette.inverse) { 404 return false; 405 } 406 if (this.logscale != colorPalette.logscale) { 407 return false; 408 } 409 if (this.maxZ != colorPalette.maxZ) { 410 return false; 411 } 412 if (this.minZ != colorPalette.minZ) { 413 return false; 414 } 415 if (this.stepped != colorPalette.stepped) { 416 return false; 417 } 418 if (!Arrays.equals(this.b, colorPalette.b)) { 419 return false; 420 } 421 if (!Arrays.equals(this.g, colorPalette.g)) { 422 return false; 423 } 424 if (this.paletteName != null 425 ? !this.paletteName.equals(colorPalette.paletteName) 426 : colorPalette.paletteName != null) { 427 return false; 428 } 429 if (!Arrays.equals(this.r, colorPalette.r)) { 430 return false; 431 } 432 if (!Arrays.equals(this.tickValues, colorPalette.tickValues)) { 433 return false; 434 } 435 436 return true; 437 } 438 439 /** 440 * Returns a hash code. 441 * 442 * @return A hash code. 443 */ 444 @Override 445 public int hashCode() { 446 int result; 447 long temp; 448 temp = Double.doubleToLongBits(this.minZ); 449 result = (int) (temp ^ (temp >>> 32)); 450 temp = Double.doubleToLongBits(this.maxZ); 451 result = 29 * result + (int) (temp ^ (temp >>> 32)); 452 result = 29 * result + (this.logscale ? 1 : 0); 453 result = 29 * result + (this.inverse ? 1 : 0); 454 result = 29 * result 455 + (this.paletteName != null ? this.paletteName.hashCode() : 0); 456 result = 29 * result + (this.stepped ? 1 : 0); 457 return result; 458 } 459 460 /** 461 * Returns a clone of the palette. 462 * 463 * @return A clone. 464 * 465 * @throws CloneNotSupportedException never. 466 */ 467 @Override 468 public Object clone() throws CloneNotSupportedException { 469 ColorPalette clone = (ColorPalette) super.clone(); 470 return clone; 471 } 472 473}