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:  * Changes
  36:  * -------
  37:  * 26-Nov-2002 : Version 1 contributed by David M. O'Donnell (DG);
  38:  * 26-Mar-2003 : Implemented Serializable (DG);
  39:  * 14-Aug-2003 : Implemented Cloneable (DG);
  40:  * ------------- JFREECHART 1.0.x ---------------------------------------------
  41:  * 31-Jan-2007 : Deprecated (DG);
  42:  *
  43:  */
  44: 
  45: package org.jfree.chart.plot;
  46: 
  47: import java.awt.Color;
  48: import java.awt.Paint;
  49: import java.io.Serializable;
  50: import java.util.Arrays;
  51: 
  52: import org.jfree.chart.axis.ValueTick;
  53: import org.jfree.chart.renderer.xy.XYBlockRenderer;
  54: 
  55: /**
  56:  * Defines palette used by {@link ContourPlot}.
  57:  * 
  58:  * @deprecated This class is no longer supported (as of version 1.0.4).  If 
  59:  *     you are creating contour plots, please try to use {@link XYPlot} and 
  60:  *     {@link XYBlockRenderer}.
  61:  */
  62: public abstract class ColorPalette implements Cloneable, Serializable {
  63: 
  64:     /** For serialization. */
  65:     private static final long serialVersionUID = -9029901853079622051L;
  66:     
  67:     /** The min z-axis value. */
  68:     protected double minZ = -1;
  69: 
  70:     /** The max z-axis value. */
  71:     protected double maxZ = -1;
  72: 
  73:     /** Red components. */
  74:     protected int[] r;
  75: 
  76:     /** Green components. */
  77:     protected int[] g;
  78: 
  79:     /** Blue components. */
  80:     protected int[] b;
  81: 
  82:     /** Tick values are stored for use with stepped palette. */
  83:     protected double[] tickValues = null;
  84: 
  85:     /** Logscale? */
  86:     protected boolean logscale = false;
  87: 
  88:     /** Inverse palette (ie, min and max colors are reversed). */
  89:     protected boolean inverse = false;
  90: 
  91:     /** The palette name. */
  92:     protected String paletteName = null;
  93: 
  94:     /** Controls whether palette colors are stepped (not continuous). */
  95:     protected boolean stepped = false;
  96: 
  97:     /** Constant for converting loge to log10. */
  98:     protected static final double log10 = Math.log(10);
  99:     
 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: }