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 * 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 }