1 /* ===========================================================
2  * JFreeChart : a free chart library for the Java(tm) platform
3  * ===========================================================
4  *
5  * (C) Copyright 2000-2013, 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  * [Oracle and Java are registered trademarks of Oracle and/or its affiliates.
25  * Other names may be trademarks of their respective owners.]
26  *
27  * -----------------
28  * ColorPalette.java
29  * -----------------
30  * (C) Copyright 2002-2008, 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      */
ColorPalette()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      */
getColor(double value)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      */
getColor(int izV)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      */
getColorLinear(double value)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      */
getColorLog(double value)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      */
getMaxZ()205     public double getMaxZ() {
206         return this.maxZ;
207     }
208 
209     /**
210      * Returns the minimum Z value.
211      *
212      * @return The value.
213      */
getMinZ()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      */
getPaint(double value)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      */
getPaletteName()240     public String getPaletteName () {
241         return this.paletteName;
242     }
243 
244     /**
245      * Returns the tick values.
246      *
247      * @return The tick values.
248      */
getTickValues()249     public double[] getTickValues() {
250         return this.tickValues;
251     }
252 
253     /**
254      * Called to initialize the palette's color indexes
255      */
initialize()256     public abstract void initialize();
257 
258     /**
259      * Inverts Palette
260      */
invertPalette()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      */
isInverse()284     public boolean isInverse () {
285         return this.inverse;
286     }
287 
288     /**
289      * Returns the log-scale flag.
290      *
291      * @return The flag.
292      */
isLogscale()293     public boolean isLogscale() {
294         return this.logscale;
295     }
296 
297     /**
298      * Returns the 'is-stepped' flag.
299      *
300      * @return The flag.
301      */
isStepped()302     public boolean isStepped () {
303         return this.stepped;
304     }
305 
306     /**
307      * Sets the inverse flag.
308      *
309      * @param inverse  the new value.
310      */
setInverse(boolean inverse)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      */
setLogscale(boolean logscale)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      */
setMaxZ(double newMaxZ)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      */
setMinZ(double newMinZ)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      */
setPaletteName(String paletteName)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      */
setStepped(boolean stepped)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      */
setTickValues(double[] newTickValues)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      */
setTickValues(java.util.List ticks)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
equals(Object o)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
hashCode()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
clone()468     public Object clone() throws CloneNotSupportedException {
469         ColorPalette clone = (ColorPalette) super.clone();
470         return clone;
471     }
472 
473 }
474