Source for org.jfree.chart.plot.ColorPalette

   1: /* ===========================================================
   2:  * JFreeChart : a free chart library for the Java(tm) platform
   3:  * ===========================================================
   4:  *
   5:  * (C) Copyright 2000-2007, by Object Refinery Limited and Contributors.
   6:  *
   7:  * Project Info:  http://www.jfree.org/jfreechart/index.html
   8:  *
   9:  * This library is free software; you can redistribute it and/or modify it 
  10:  * under the terms of the GNU Lesser General Public License as published by 
  11:  * the Free Software Foundation; either version 2.1 of the License, or 
  12:  * (at your option) any later version.
  13:  *
  14:  * This library is distributed in the hope that it will be useful, but 
  15:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
  16:  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
  17:  * License for more details.
  18:  *
  19:  * You should have received a copy of the GNU Lesser General Public
  20:  * License along with this library; if not, write to the Free Software
  21:  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
  22:  * USA.  
  23:  *
  24:  * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 
  25:  * in the United States and other countries.]
  26:  *
  27:  * -----------------
  28:  * ColorPalette.java
  29:  * -----------------
  30:  * (C) Copyright 2002-2007, by David M. O'Donnell and Contributors.
  31:  *
  32:  * Original Author:  David M. O'Donnell;
  33:  * Contributor(s):   David Gilbert (for Object Refinery Limited);
  34:  *
  35:  * $Id: ColorPalette.java,v 1.1.2.4 2007/03/19 16:20:24 mungady Exp $
  36:  *
  37:  * Changes
  38:  * -------
  39:  * 26-Nov-2002 : Version 1 contributed by David M. O'Donnell (DG);
  40:  * 26-Mar-2003 : Implemented Serializable (DG);
  41:  * 14-Aug-2003 : Implemented Cloneable (DG);
  42:  * ------------- JFREECHART 1.0.x ---------------------------------------------
  43:  * 31-Jan-2007 : Deprecated (DG);
  44:  *
  45:  */
  46: 
  47: package org.jfree.chart.plot;
  48: 
  49: import java.awt.Color;
  50: import java.awt.Paint;
  51: import java.io.Serializable;
  52: import java.util.Arrays;
  53: 
  54: import org.jfree.chart.axis.ValueTick;
  55: import org.jfree.chart.renderer.xy.XYBlockRenderer;
  56: 
  57: /**
  58:  * Defines palette used by {@link ContourPlot}.
  59:  * 
  60:  * @deprecated This class is no longer supported.  If you are creating
  61:  *     contour plots, please try to use {@link XYPlot} and 
  62:  *     {@link XYBlockRenderer}.
  63:  */
  64: public abstract class ColorPalette implements Cloneable, Serializable {
  65: 
  66:     /** For serialization. */
  67:     private static final long serialVersionUID = -9029901853079622051L;
  68:     
  69:     /** The min z-axis value. */
  70:     protected double minZ = -1;
  71: 
  72:     /** The max z-axis value. */
  73:     protected double maxZ = -1;
  74: 
  75:     /** Red components. */
  76:     protected int[] r;
  77: 
  78:     /** Green components. */
  79:     protected int[] g;
  80: 
  81:     /** Blue components. */
  82:     protected int[] b;
  83: 
  84:     /** Tick values are stored for use with stepped palette. */
  85:     protected double[] tickValues = null;
  86: 
  87:     /** Logscale? */
  88:     protected boolean logscale = false;
  89: 
  90:     /** Inverse palette (ie, min and max colors are reversed). */
  91:     protected boolean inverse = false;
  92: 
  93:     /** The palette name. */
  94:     protected String paletteName = null;
  95: 
  96:     /** Controls whether palette colors are stepped (not continuous). */
  97:     protected boolean stepped = false;
  98: 
  99:     /** 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: }