    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    }