1. /* ===========================================================
  2. * JFreeChart : a free chart library for the Java(tm) platform
  3. * ===========================================================
  4. *
  5. * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
  6. *
  7. * Project Info: http://www.jfree.org/jfreechart/index.html
  8. *
  9. * This library is free software; you can redistribute it and/or modify it under the terms
  10. * of the GNU Lesser General Public License as published by the Free Software Foundation;
  11. * either version 2.1 of the License, or (at your option) any later version.
  12. *
  13. * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
  14. * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  15. * See the GNU Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public License along with this
  18. * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  19. * Boston, MA 02111-1307, USA.
  20. *
  21. * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
  22. * in the United States and other countries.]
  23. *
  24. * ---------------------
  25. * XYLine3DRenderer.java
  26. * ---------------------
  27. * (C) Copyright 2005, by Object Refinery Limited.
  28. *
  29. * Original Author: Thomas Morgner;
  30. * Contributor(s): David Gilbert (for Object Refinery Limited);
  31. *
  32. * $Id: XYLine3DRenderer.java,v 1.2 2005/01/14 17:39:16 mungady Exp $
  33. *
  34. * Changes
  35. * -------
  36. * 14-Jan-2005 : Added standard header (DG);
  37. *
  38. *
  39. *
  40. *
  41. */
  42. package org.jfree.chart.renderer.xy;
  43. import java.awt.Color;
  44. import java.awt.Graphics2D;
  45. import java.awt.Paint;
  46. import java.awt.Shape;
  47. import org.jfree.chart.Effect3D;
  48. import org.jfree.chart.event.RendererChangeEvent;
  49. /**
  50. * A XYLineAndShapeRenderer that adds a shadow line to the graph
  51. * to emulate a 3D-effect.
  52. */
  53. public class XYLine3DRenderer extends XYLineAndShapeRenderer implements Effect3D {
  54. /** The default x-offset for the 3D effect. */
  55. public static final double DEFAULT_X_OFFSET = 12.0;
  56. /** The default y-offset for the 3D effect. */
  57. public static final double DEFAULT_Y_OFFSET = 8.0;
  58. /** The default wall paint. */
  59. public static final Paint DEFAULT_WALL_PAINT = new Color(0xDD, 0xDD, 0xDD);
  60. /** The size of x-offset for the 3D effect. */
  61. private double xOffset;
  62. /** The size of y-offset for the 3D effect. */
  63. private double yOffset;
  64. /** The paint used to shade the left and lower 3D wall. */
  65. private transient Paint wallPaint;
  66. /**
  67. * Creates a new renderer.
  68. */
  69. public XYLine3DRenderer() {
  70. this.wallPaint = DEFAULT_WALL_PAINT;
  71. this.xOffset = DEFAULT_X_OFFSET;
  72. this.yOffset = DEFAULT_Y_OFFSET;
  73. }
  74. /**
  75. * Returns the x-offset for the 3D effect.
  76. *
  77. * @return The 3D effect.
  78. */
  79. public double getXOffset() {
  80. return this.xOffset;
  81. }
  82. /**
  83. * Returns the y-offset for the 3D effect.
  84. *
  85. * @return The 3D effect.
  86. */
  87. public double getYOffset() {
  88. return this.yOffset;
  89. }
  90. /**
  91. * Sets the x-offset and sends a {@link RendererChangeEvent} to all
  92. * registered listeners.
  93. *
  94. * @param xOffset the x-offset.
  95. */
  96. public void setXOffset(double xOffset) {
  97. this.xOffset = xOffset;
  98. notifyListeners(new RendererChangeEvent(this));
  99. }
  100. /**
  101. * Sets the y-offset and sends a {@link RendererChangeEvent} to all
  102. * registered listeners.
  103. *
  104. * @param yOffset the y-offset.
  105. */
  106. public void setYOffset(double yOffset) {
  107. this.yOffset = yOffset;
  108. notifyListeners(new RendererChangeEvent(this));
  109. }
  110. /**
  111. * Returns the paint used to highlight the left and bottom wall in the plot background.
  112. *
  113. * @return The paint.
  114. */
  115. public Paint getWallPaint() {
  116. return this.wallPaint;
  117. }
  118. /**
  119. * Sets the paint used to hightlight the left and bottom walls in the plot background.
  120. *
  121. * @param paint the paint.
  122. */
  123. public void setWallPaint(Paint paint) {
  124. this.wallPaint = paint;
  125. notifyListeners(new RendererChangeEvent(this));
  126. }
  127. /**
  128. * Returns the number of passes through the data that the renderer requires in order to
  129. * draw the chart. Most charts will require a single pass, but some require two passes.
  130. *
  131. * @return The pass count.
  132. */
  133. public int getPassCount() {
  134. return 3;
  135. }
  136. /**
  137. * Returns <code>true</code> if the specified pass involves drawing lines.
  138. *
  139. * @param pass the pass.
  140. *
  141. * @return A boolean.
  142. */
  143. protected boolean isLinePass(int pass) {
  144. return pass == 0 || pass == 1;
  145. }
  146. /**
  147. * Returns <code>true</code> if the specified pass involves drawing items.
  148. *
  149. * @param pass the pass.
  150. *
  151. * @return A boolean.
  152. */
  153. protected boolean isItemPass(int pass) {
  154. return pass == 2;
  155. }
  156. /**
  157. * Returns <code>true</code> if the specified pass involves drawing shadows.
  158. *
  159. * @param pass the pass.
  160. *
  161. * @return A boolean.
  162. */
  163. protected boolean isShadowPass (int pass) {
  164. return pass == 0;
  165. }
  166. /**
  167. * Overrides the method in the subclass to draw a shadow in the first pass.
  168. *
  169. * @param g2 the graphics device.
  170. * @param pass the pass.
  171. * @param series the series index (zero-based).
  172. * @param item the item index (zero-based).
  173. * @param shape the shape.
  174. */
  175. protected void drawFirstPassShape(Graphics2D g2,
  176. int pass,
  177. int series,
  178. int item,
  179. Shape shape) {
  180. if (isShadowPass(pass)) {
  181. if (getWallPaint() != null) {
  182. g2.setStroke(getItemStroke(series, item));
  183. g2.setPaint(getWallPaint());
  184. g2.translate(getXOffset(), getYOffset());
  185. g2.draw(shape);
  186. g2.translate(-getXOffset(), -getYOffset());
  187. }
  188. }
  189. else {
  190. // now draw the real shape
  191. super.drawFirstPassShape(g2, pass, series, item, shape);
  192. }
  193. }
  194. }