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 * ColorBar.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: ColorBar.java,v 1.6.2.3 2007/01/31 15:56:18 mungady Exp $
036 *
037 * Changes
038 * -------
039 * 26-Nov-2002 : Version 1 contributed by David M. O'Donnell (DG);
040 * 14-Jan-2003 : Changed autoRangeMinimumSize from Number --> double (DG);
041 * 17-Jan-2003 : Moved plot classes to separate package (DG);
042 * 20-Jan-2003 : Removed unnecessary constructors (DG);
043 * 26-Mar-2003 : Implemented Serializable (DG);
044 * 09-Jul-2003 : Changed ColorBar from extending axis classes to enclosing
045 * them (DG);
046 * 05-Aug-2003 : Applied changes in bug report 780298 (DG);
047 * 14-Aug-2003 : Implemented Cloneable (DG);
048 * 08-Sep-2003 : Changed ValueAxis API (DG);
049 * 21-Jan-2004 : Update for renamed method in ValueAxis (DG);
050 * ------------- JFREECHART 1.0.x ---------------------------------------------
051 * 31-Jan-2007 : Deprecated (DG);
052 *
053 */
054
055 package org.jfree.chart.axis;
056
057 import java.awt.BasicStroke;
058 import java.awt.Graphics2D;
059 import java.awt.Paint;
060 import java.awt.RenderingHints;
061 import java.awt.Stroke;
062 import java.awt.geom.Line2D;
063 import java.awt.geom.Rectangle2D;
064 import java.io.Serializable;
065
066 import org.jfree.chart.plot.ColorPalette;
067 import org.jfree.chart.plot.ContourPlot;
068 import org.jfree.chart.plot.Plot;
069 import org.jfree.chart.plot.RainbowPalette;
070 import org.jfree.chart.plot.XYPlot;
071 import org.jfree.chart.renderer.xy.XYBlockRenderer;
072 import org.jfree.ui.RectangleEdge;
073
074 /**
075 * A color bar.
076 *
077 * @deprecated This class is no longer supported. If you are creating
078 * contour plots, please try to use {@link XYPlot} and
079 * {@link XYBlockRenderer}.
080 */
081 public class ColorBar implements Cloneable, Serializable {
082
083 /** For serialization. */
084 private static final long serialVersionUID = -2101776212647268103L;
085
086 /** The default color bar thickness. */
087 public static final int DEFAULT_COLORBAR_THICKNESS = 0;
088
089 /** The default color bar thickness percentage. */
090 public static final double DEFAULT_COLORBAR_THICKNESS_PERCENT = 0.10;
091
092 /** The default outer gap. */
093 public static final int DEFAULT_OUTERGAP = 2;
094
095 /** The axis. */
096 private ValueAxis axis;
097
098 /** The color bar thickness. */
099 private int colorBarThickness = DEFAULT_COLORBAR_THICKNESS;
100
101 /**
102 * The color bar thickness as a percentage of the height of the data area.
103 */
104 private double colorBarThicknessPercent
105 = DEFAULT_COLORBAR_THICKNESS_PERCENT;
106
107 /** The color palette. */
108 private ColorPalette colorPalette = null;
109
110 /** The color bar length. */
111 private int colorBarLength = 0; // default make height of plotArea
112
113 /** The amount of blank space around the colorbar. */
114 private int outerGap;
115
116 /**
117 * Constructs a horizontal colorbar axis, using default values where
118 * necessary.
119 *
120 * @param label the axis label.
121 */
122 public ColorBar(String label) {
123
124 NumberAxis a = new NumberAxis(label);
125 a.setAutoRangeIncludesZero(false);
126 this.axis = a;
127 this.axis.setLowerMargin(0.0);
128 this.axis.setUpperMargin(0.0);
129
130 this.colorPalette = new RainbowPalette();
131 this.colorBarThickness = DEFAULT_COLORBAR_THICKNESS;
132 this.colorBarThicknessPercent = DEFAULT_COLORBAR_THICKNESS_PERCENT;
133 this.outerGap = DEFAULT_OUTERGAP;
134 this.colorPalette.setMinZ(this.axis.getRange().getLowerBound());
135 this.colorPalette.setMaxZ(this.axis.getRange().getUpperBound());
136
137 }
138
139 /**
140 * Configures the color bar.
141 *
142 * @param plot the plot.
143 */
144 public void configure(ContourPlot plot) {
145 double minZ = plot.getDataset().getMinZValue();
146 double maxZ = plot.getDataset().getMaxZValue();
147 setMinimumValue(minZ);
148 setMaximumValue(maxZ);
149 }
150
151 /**
152 * Returns the axis.
153 *
154 * @return The axis.
155 */
156 public ValueAxis getAxis() {
157 return this.axis;
158 }
159
160 /**
161 * Sets the axis.
162 *
163 * @param axis the axis.
164 */
165 public void setAxis(ValueAxis axis) {
166 this.axis = axis;
167 }
168
169 /**
170 * Rescales the axis to ensure that all data are visible.
171 */
172 public void autoAdjustRange() {
173 this.axis.autoAdjustRange();
174 this.colorPalette.setMinZ(this.axis.getLowerBound());
175 this.colorPalette.setMaxZ(this.axis.getUpperBound());
176 }
177
178 /**
179 * Draws the plot on a Java 2D graphics device (such as the screen or a
180 * printer).
181 *
182 * @param g2 the graphics device.
183 * @param cursor the cursor.
184 * @param plotArea the area within which the chart should be drawn.
185 * @param dataArea the area within which the plot should be drawn (a
186 * subset of the drawArea).
187 * @param reservedArea the reserved area.
188 * @param edge the color bar location.
189 *
190 * @return The new cursor location.
191 */
192 public double draw(Graphics2D g2, double cursor,
193 Rectangle2D plotArea, Rectangle2D dataArea,
194 Rectangle2D reservedArea, RectangleEdge edge) {
195
196
197 Rectangle2D colorBarArea = null;
198
199 double thickness = calculateBarThickness(dataArea, edge);
200 if (this.colorBarThickness > 0) {
201 thickness = this.colorBarThickness; // allow fixed thickness
202 }
203
204 double length = 0.0;
205 if (RectangleEdge.isLeftOrRight(edge)) {
206 length = dataArea.getHeight();
207 }
208 else {
209 length = dataArea.getWidth();
210 }
211
212 if (this.colorBarLength > 0) {
213 length = this.colorBarLength;
214 }
215
216 if (edge == RectangleEdge.BOTTOM) {
217 colorBarArea = new Rectangle2D.Double(
218 dataArea.getX(), plotArea.getMaxY() + this.outerGap,
219 length, thickness
220 );
221 }
222 else if (edge == RectangleEdge.TOP) {
223 colorBarArea = new Rectangle2D.Double(
224 dataArea.getX(), reservedArea.getMinY() + this.outerGap,
225 length, thickness
226 );
227 }
228 else if (edge == RectangleEdge.LEFT) {
229 colorBarArea = new Rectangle2D.Double(
230 plotArea.getX() - thickness - this.outerGap ,
231 dataArea.getMinY(), thickness, length
232 );
233 }
234 else if (edge == RectangleEdge.RIGHT) {
235 colorBarArea = new Rectangle2D.Double(
236 plotArea.getMaxX() + this.outerGap, dataArea.getMinY(),
237 thickness, length
238 );
239 }
240
241 // update, but dont draw tick marks (needed for stepped colors)
242 this.axis.refreshTicks(
243 g2, new AxisState(), colorBarArea, edge
244 );
245
246 drawColorBar(g2, colorBarArea, edge);
247
248 AxisState state = null;
249 if (edge == RectangleEdge.TOP) {
250 cursor = colorBarArea.getMinY();
251 state = this.axis.draw(
252 g2, cursor, reservedArea, colorBarArea, RectangleEdge.TOP, null
253 );
254 }
255 else if (edge == RectangleEdge.BOTTOM) {
256 cursor = colorBarArea.getMaxY();
257 state = this.axis.draw(
258 g2, cursor, reservedArea, colorBarArea, RectangleEdge.BOTTOM,
259 null
260 );
261 }
262 else if (edge == RectangleEdge.LEFT) {
263 cursor = colorBarArea.getMinX();
264 state = this.axis.draw(
265 g2, cursor, reservedArea, colorBarArea, RectangleEdge.LEFT, null
266 );
267 }
268 else if (edge == RectangleEdge.RIGHT) {
269 cursor = colorBarArea.getMaxX();
270 state = this.axis.draw(
271 g2, cursor, reservedArea, colorBarArea, RectangleEdge.RIGHT,
272 null
273 );
274 }
275 return state.getCursor();
276
277 }
278
279 /**
280 * Draws the plot on a Java 2D graphics device (such as the screen or a
281 * printer).
282 *
283 * @param g2 the graphics device.
284 * @param colorBarArea the area within which the axis should be drawn.
285 * @param edge the location.
286 */
287 public void drawColorBar(Graphics2D g2, Rectangle2D colorBarArea,
288 RectangleEdge edge) {
289
290 Object antiAlias = g2.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
291 g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
292 RenderingHints.VALUE_ANTIALIAS_OFF);
293
294 // setTickValues was missing from ColorPalette v. 0.96
295 //colorPalette.setTickValues(this.axis.getTicks());
296
297 Stroke strokeSaved = g2.getStroke();
298 g2.setStroke(new BasicStroke(1.0f));
299
300 if (RectangleEdge.isTopOrBottom(edge)) {
301 double y1 = colorBarArea.getY();
302 double y2 = colorBarArea.getMaxY();
303 double xx = colorBarArea.getX();
304 Line2D line = new Line2D.Double();
305 while (xx <= colorBarArea.getMaxX()) {
306 double value = this.axis.java2DToValue(xx, colorBarArea, edge);
307 line.setLine(xx, y1, xx, y2);
308 g2.setPaint(getPaint(value));
309 g2.draw(line);
310 xx += 1;
311 }
312 }
313 else {
314 double y1 = colorBarArea.getX();
315 double y2 = colorBarArea.getMaxX();
316 double xx = colorBarArea.getY();
317 Line2D line = new Line2D.Double();
318 while (xx <= colorBarArea.getMaxY()) {
319 double value = this.axis.java2DToValue(xx, colorBarArea, edge);
320 line.setLine(y1, xx, y2, xx);
321 g2.setPaint(getPaint(value));
322 g2.draw(line);
323 xx += 1;
324 }
325 }
326
327 g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, antiAlias);
328 g2.setStroke(strokeSaved);
329
330 }
331
332 /**
333 * Returns the color palette.
334 *
335 * @return The color palette.
336 */
337 public ColorPalette getColorPalette() {
338 return this.colorPalette;
339 }
340
341 /**
342 * Returns the Paint associated with a value.
343 *
344 * @param value the value.
345 *
346 * @return The paint.
347 */
348 public Paint getPaint(double value) {
349 return this.colorPalette.getPaint(value);
350 }
351
352 /**
353 * Sets the color palette.
354 *
355 * @param palette the new palette.
356 */
357 public void setColorPalette(ColorPalette palette) {
358 this.colorPalette = palette;
359 }
360
361 /**
362 * Sets the maximum value.
363 *
364 * @param value the maximum value.
365 */
366 public void setMaximumValue(double value) {
367 this.colorPalette.setMaxZ(value);
368 this.axis.setUpperBound(value);
369 }
370
371 /**
372 * Sets the minimum value.
373 *
374 * @param value the minimum value.
375 */
376 public void setMinimumValue(double value) {
377 this.colorPalette.setMinZ(value);
378 this.axis.setLowerBound(value);
379 }
380
381 /**
382 * Reserves the space required to draw the color bar.
383 *
384 * @param g2 the graphics device.
385 * @param plot the plot that the axis belongs to.
386 * @param plotArea the area within which the plot should be drawn.
387 * @param dataArea the data area.
388 * @param edge the axis location.
389 * @param space the space already reserved.
390 *
391 * @return The space required to draw the axis in the specified plot area.
392 */
393 public AxisSpace reserveSpace(Graphics2D g2, Plot plot,
394 Rectangle2D plotArea,
395 Rectangle2D dataArea, RectangleEdge edge,
396 AxisSpace space) {
397
398 AxisSpace result = this.axis.reserveSpace(
399 g2, plot, plotArea, edge, space
400 );
401 double thickness = calculateBarThickness(dataArea, edge);
402 result.add(thickness + 2 * this.outerGap, edge);
403 return result;
404
405 }
406
407 /**
408 * Calculates the bar thickness.
409 *
410 * @param plotArea the plot area.
411 * @param edge the location.
412 *
413 * @return The thickness.
414 */
415 private double calculateBarThickness(Rectangle2D plotArea,
416 RectangleEdge edge) {
417 double result = 0.0;
418 if (RectangleEdge.isLeftOrRight(edge)) {
419 result = plotArea.getWidth() * this.colorBarThicknessPercent;
420 }
421 else {
422 result = plotArea.getHeight() * this.colorBarThicknessPercent;
423 }
424 return result;
425 }
426
427 /**
428 * Returns a clone of the object.
429 *
430 * @return A clone.
431 *
432 * @throws CloneNotSupportedException if some component of the color bar
433 * does not support cloning.
434 */
435 public Object clone() throws CloneNotSupportedException {
436
437 ColorBar clone = (ColorBar) super.clone();
438 clone.axis = (ValueAxis) this.axis.clone();
439 return clone;
440
441 }
442
443 /**
444 * Tests this object for equality with another.
445 *
446 * @param obj the object to test against.
447 *
448 * @return A boolean.
449 */
450 public boolean equals(Object obj) {
451
452 if (obj == this) {
453 return true;
454 }
455 if (!(obj instanceof ColorBar)) {
456 return false;
457 }
458 ColorBar that = (ColorBar) obj;
459 if (!this.axis.equals(that.axis)) {
460 return false;
461 }
462 if (this.colorBarThickness != that.colorBarThickness) {
463 return false;
464 }
465 if (this.colorBarThicknessPercent != that.colorBarThicknessPercent) {
466 return false;
467 }
468 if (!this.colorPalette.equals(that.colorPalette)) {
469 return false;
470 }
471 if (this.colorBarLength != that.colorBarLength) {
472 return false;
473 }
474 if (this.outerGap != that.outerGap) {
475 return false;
476 }
477 return true;
478
479 }
480
481 /**
482 * Returns a hash code for this object.
483 *
484 * @return A hash code.
485 */
486 public int hashCode() {
487 return this.axis.hashCode();
488 }
489
490 }