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