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.5 2007/04/30 21:16:23 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 (as of version 1.0.4). If
078: * you are creating 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 = DEFAULT_COLORBAR_THICKNESS_PERCENT;
105:
106: /** The color palette. */
107: private ColorPalette colorPalette = null;
108:
109: /** The color bar length. */
110: private int colorBarLength = 0; // default make height of plotArea
111:
112: /** The amount of blank space around the colorbar. */
113: private int outerGap;
114:
115: /**
116: * Constructs a horizontal colorbar axis, using default values where
117: * necessary.
118: *
119: * @param label the axis label.
120: */
121: public ColorBar(String label) {
122:
123: NumberAxis a = new NumberAxis(label);
124: a.setAutoRangeIncludesZero(false);
125: this .axis = a;
126: this .axis.setLowerMargin(0.0);
127: this .axis.setUpperMargin(0.0);
128:
129: this .colorPalette = new RainbowPalette();
130: this .colorBarThickness = DEFAULT_COLORBAR_THICKNESS;
131: this .colorBarThicknessPercent = DEFAULT_COLORBAR_THICKNESS_PERCENT;
132: this .outerGap = DEFAULT_OUTERGAP;
133: this .colorPalette.setMinZ(this .axis.getRange().getLowerBound());
134: this .colorPalette.setMaxZ(this .axis.getRange().getUpperBound());
135:
136: }
137:
138: /**
139: * Configures the color bar.
140: *
141: * @param plot the plot.
142: */
143: public void configure(ContourPlot plot) {
144: double minZ = plot.getDataset().getMinZValue();
145: double maxZ = plot.getDataset().getMaxZValue();
146: setMinimumValue(minZ);
147: setMaximumValue(maxZ);
148: }
149:
150: /**
151: * Returns the axis.
152: *
153: * @return The axis.
154: */
155: public ValueAxis getAxis() {
156: return this .axis;
157: }
158:
159: /**
160: * Sets the axis.
161: *
162: * @param axis the axis.
163: */
164: public void setAxis(ValueAxis axis) {
165: this .axis = axis;
166: }
167:
168: /**
169: * Rescales the axis to ensure that all data are visible.
170: */
171: public void autoAdjustRange() {
172: this .axis.autoAdjustRange();
173: this .colorPalette.setMinZ(this .axis.getLowerBound());
174: this .colorPalette.setMaxZ(this .axis.getUpperBound());
175: }
176:
177: /**
178: * Draws the plot on a Java 2D graphics device (such as the screen or a
179: * printer).
180: *
181: * @param g2 the graphics device.
182: * @param cursor the cursor.
183: * @param plotArea the area within which the chart should be drawn.
184: * @param dataArea the area within which the plot should be drawn (a
185: * subset of the drawArea).
186: * @param reservedArea the reserved area.
187: * @param edge the color bar location.
188: *
189: * @return The new cursor location.
190: */
191: public double draw(Graphics2D g2, double cursor,
192: Rectangle2D plotArea, Rectangle2D dataArea,
193: Rectangle2D reservedArea, RectangleEdge edge) {
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: } else {
206: length = dataArea.getWidth();
207: }
208:
209: if (this .colorBarLength > 0) {
210: length = this .colorBarLength;
211: }
212:
213: if (edge == RectangleEdge.BOTTOM) {
214: colorBarArea = new Rectangle2D.Double(dataArea.getX(),
215: plotArea.getMaxY() + this .outerGap, length,
216: thickness);
217: } else if (edge == RectangleEdge.TOP) {
218: colorBarArea = new Rectangle2D.Double(dataArea.getX(),
219: reservedArea.getMinY() + this .outerGap, length,
220: thickness);
221: } else if (edge == RectangleEdge.LEFT) {
222: colorBarArea = new Rectangle2D.Double(plotArea.getX()
223: - thickness - this .outerGap, dataArea.getMinY(),
224: thickness, length);
225: } else if (edge == RectangleEdge.RIGHT) {
226: colorBarArea = new Rectangle2D.Double(plotArea.getMaxX()
227: + this .outerGap, dataArea.getMinY(), thickness,
228: 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,
240: colorBarArea, RectangleEdge.TOP, null);
241: } else if (edge == RectangleEdge.BOTTOM) {
242: cursor = colorBarArea.getMaxY();
243: state = this .axis.draw(g2, cursor, reservedArea,
244: colorBarArea, RectangleEdge.BOTTOM, null);
245: } else if (edge == RectangleEdge.LEFT) {
246: cursor = colorBarArea.getMinX();
247: state = this .axis.draw(g2, cursor, reservedArea,
248: colorBarArea, RectangleEdge.LEFT, null);
249: } else if (edge == RectangleEdge.RIGHT) {
250: cursor = colorBarArea.getMaxX();
251: state = this .axis.draw(g2, cursor, reservedArea,
252: colorBarArea, RectangleEdge.RIGHT, null);
253: }
254: return state.getCursor();
255:
256: }
257:
258: /**
259: * Draws the plot on a Java 2D graphics device (such as the screen or a
260: * printer).
261: *
262: * @param g2 the graphics device.
263: * @param colorBarArea the area within which the axis should be drawn.
264: * @param edge the location.
265: */
266: public void drawColorBar(Graphics2D g2, Rectangle2D colorBarArea,
267: RectangleEdge edge) {
268:
269: Object antiAlias = g2
270: .getRenderingHint(RenderingHints.KEY_ANTIALIASING);
271: g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
272: RenderingHints.VALUE_ANTIALIAS_OFF);
273:
274: // setTickValues was missing from ColorPalette v. 0.96
275: //colorPalette.setTickValues(this.axis.getTicks());
276:
277: Stroke strokeSaved = g2.getStroke();
278: g2.setStroke(new BasicStroke(1.0f));
279:
280: if (RectangleEdge.isTopOrBottom(edge)) {
281: double y1 = colorBarArea.getY();
282: double y2 = colorBarArea.getMaxY();
283: double xx = colorBarArea.getX();
284: Line2D line = new Line2D.Double();
285: while (xx <= colorBarArea.getMaxX()) {
286: double value = this .axis.java2DToValue(xx,
287: colorBarArea, edge);
288: line.setLine(xx, y1, xx, y2);
289: g2.setPaint(getPaint(value));
290: g2.draw(line);
291: xx += 1;
292: }
293: } else {
294: double y1 = colorBarArea.getX();
295: double y2 = colorBarArea.getMaxX();
296: double xx = colorBarArea.getY();
297: Line2D line = new Line2D.Double();
298: while (xx <= colorBarArea.getMaxY()) {
299: double value = this .axis.java2DToValue(xx,
300: colorBarArea, edge);
301: line.setLine(y1, xx, y2, xx);
302: g2.setPaint(getPaint(value));
303: g2.draw(line);
304: xx += 1;
305: }
306: }
307:
308: g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, antiAlias);
309: g2.setStroke(strokeSaved);
310:
311: }
312:
313: /**
314: * Returns the color palette.
315: *
316: * @return The color palette.
317: */
318: public ColorPalette getColorPalette() {
319: return this .colorPalette;
320: }
321:
322: /**
323: * Returns the Paint associated with a value.
324: *
325: * @param value the value.
326: *
327: * @return The paint.
328: */
329: public Paint getPaint(double value) {
330: return this .colorPalette.getPaint(value);
331: }
332:
333: /**
334: * Sets the color palette.
335: *
336: * @param palette the new palette.
337: */
338: public void setColorPalette(ColorPalette palette) {
339: this .colorPalette = palette;
340: }
341:
342: /**
343: * Sets the maximum value.
344: *
345: * @param value the maximum value.
346: */
347: public void setMaximumValue(double value) {
348: this .colorPalette.setMaxZ(value);
349: this .axis.setUpperBound(value);
350: }
351:
352: /**
353: * Sets the minimum value.
354: *
355: * @param value the minimum value.
356: */
357: public void setMinimumValue(double value) {
358: this .colorPalette.setMinZ(value);
359: this .axis.setLowerBound(value);
360: }
361:
362: /**
363: * Reserves the space required to draw the color bar.
364: *
365: * @param g2 the graphics device.
366: * @param plot the plot that the axis belongs to.
367: * @param plotArea the area within which the plot should be drawn.
368: * @param dataArea the data area.
369: * @param edge the axis location.
370: * @param space the space already reserved.
371: *
372: * @return The space required to draw the axis in the specified plot area.
373: */
374: public AxisSpace reserveSpace(Graphics2D g2, Plot plot,
375: Rectangle2D plotArea, Rectangle2D dataArea,
376: RectangleEdge edge, AxisSpace space) {
377:
378: AxisSpace result = this .axis.reserveSpace(g2, plot, plotArea,
379: edge, space);
380: double thickness = calculateBarThickness(dataArea, edge);
381: result.add(thickness + 2 * this .outerGap, edge);
382: return result;
383:
384: }
385:
386: /**
387: * Calculates the bar thickness.
388: *
389: * @param plotArea the plot area.
390: * @param edge the location.
391: *
392: * @return The thickness.
393: */
394: private double calculateBarThickness(Rectangle2D plotArea,
395: RectangleEdge edge) {
396: double result = 0.0;
397: if (RectangleEdge.isLeftOrRight(edge)) {
398: result = plotArea.getWidth()
399: * this .colorBarThicknessPercent;
400: } else {
401: result = plotArea.getHeight()
402: * this .colorBarThicknessPercent;
403: }
404: return result;
405: }
406:
407: /**
408: * Returns a clone of the object.
409: *
410: * @return A clone.
411: *
412: * @throws CloneNotSupportedException if some component of the color bar
413: * does not support cloning.
414: */
415: public Object clone() throws CloneNotSupportedException {
416:
417: ColorBar clone = (ColorBar) super .clone();
418: clone.axis = (ValueAxis) this .axis.clone();
419: return clone;
420:
421: }
422:
423: /**
424: * Tests this object for equality with another.
425: *
426: * @param obj the object to test against.
427: *
428: * @return A boolean.
429: */
430: public boolean equals(Object obj) {
431:
432: if (obj == this ) {
433: return true;
434: }
435: if (!(obj instanceof ColorBar)) {
436: return false;
437: }
438: ColorBar that = (ColorBar) obj;
439: if (!this .axis.equals(that.axis)) {
440: return false;
441: }
442: if (this .colorBarThickness != that.colorBarThickness) {
443: return false;
444: }
445: if (this .colorBarThicknessPercent != that.colorBarThicknessPercent) {
446: return false;
447: }
448: if (!this .colorPalette.equals(that.colorPalette)) {
449: return false;
450: }
451: if (this .colorBarLength != that.colorBarLength) {
452: return false;
453: }
454: if (this .outerGap != that.outerGap) {
455: return false;
456: }
457: return true;
458:
459: }
460:
461: /**
462: * Returns a hash code for this object.
463: *
464: * @return A hash code.
465: */
466: public int hashCode() {
467: return this.axis.hashCode();
468: }
469:
470: }
|