    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    }