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 }