001 /* =========================================================== 002 * JFreeChart : a free chart library for the Java(tm) platform 003 * =========================================================== 004 * 005 * (C) Copyright 2000-2005, 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 * XYLine3DRenderer.java 029 * --------------------- 030 * (C) Copyright 2005, by Object Refinery Limited. 031 * 032 * Original Author: Thomas Morgner; 033 * Contributor(s): David Gilbert (for Object Refinery Limited); 034 * 035 * $Id: XYLine3DRenderer.java,v 1.4.2.1 2005/10/25 20:56:21 mungady Exp $ 036 * 037 * Changes 038 * ------- 039 * 14-Jan-2005 : Added standard header (DG); 040 */ 041 042 package org.jfree.chart.renderer.xy; 043 044 import java.awt.Color; 045 import java.awt.Graphics2D; 046 import java.awt.Paint; 047 import java.awt.Shape; 048 import java.io.Serializable; 049 050 import org.jfree.chart.Effect3D; 051 import org.jfree.chart.event.RendererChangeEvent; 052 053 /** 054 * A XYLineAndShapeRenderer that adds a shadow line to the graph 055 * to emulate a 3D-effect. 056 */ 057 public class XYLine3DRenderer extends XYLineAndShapeRenderer 058 implements Effect3D, Serializable { 059 060 /** For serialization. */ 061 private static final long serialVersionUID = 588933208243446087L; 062 063 /** The default x-offset for the 3D effect. */ 064 public static final double DEFAULT_X_OFFSET = 12.0; 065 066 /** The default y-offset for the 3D effect. */ 067 public static final double DEFAULT_Y_OFFSET = 8.0; 068 069 /** The default wall paint. */ 070 public static final Paint DEFAULT_WALL_PAINT = new Color(0xDD, 0xDD, 0xDD); 071 072 /** The size of x-offset for the 3D effect. */ 073 private double xOffset; 074 075 /** The size of y-offset for the 3D effect. */ 076 private double yOffset; 077 078 /** The paint used to shade the left and lower 3D wall. */ 079 private transient Paint wallPaint; 080 081 /** 082 * Creates a new renderer. 083 */ 084 public XYLine3DRenderer() { 085 this.wallPaint = DEFAULT_WALL_PAINT; 086 this.xOffset = DEFAULT_X_OFFSET; 087 this.yOffset = DEFAULT_Y_OFFSET; 088 } 089 090 /** 091 * Returns the x-offset for the 3D effect. 092 * 093 * @return The 3D effect. 094 */ 095 public double getXOffset() { 096 return this.xOffset; 097 } 098 099 /** 100 * Returns the y-offset for the 3D effect. 101 * 102 * @return The 3D effect. 103 */ 104 public double getYOffset() { 105 return this.yOffset; 106 } 107 108 /** 109 * Sets the x-offset and sends a {@link RendererChangeEvent} to all 110 * registered listeners. 111 * 112 * @param xOffset the x-offset. 113 */ 114 public void setXOffset(double xOffset) { 115 this.xOffset = xOffset; 116 notifyListeners(new RendererChangeEvent(this)); 117 } 118 119 /** 120 * Sets the y-offset and sends a {@link RendererChangeEvent} to all 121 * registered listeners. 122 * 123 * @param yOffset the y-offset. 124 */ 125 public void setYOffset(double yOffset) { 126 this.yOffset = yOffset; 127 notifyListeners(new RendererChangeEvent(this)); 128 } 129 130 /** 131 * Returns the paint used to highlight the left and bottom wall in the plot 132 * background. 133 * 134 * @return The paint. 135 */ 136 public Paint getWallPaint() { 137 return this.wallPaint; 138 } 139 140 /** 141 * Sets the paint used to hightlight the left and bottom walls in the plot 142 * background. 143 * 144 * @param paint the paint. 145 */ 146 public void setWallPaint(Paint paint) { 147 this.wallPaint = paint; 148 notifyListeners(new RendererChangeEvent(this)); 149 } 150 151 /** 152 * Returns the number of passes through the data that the renderer requires 153 * in order to draw the chart. Most charts will require a single pass, 154 * but some require two passes. 155 * 156 * @return The pass count. 157 */ 158 public int getPassCount() { 159 return 3; 160 } 161 162 /** 163 * Returns <code>true</code> if the specified pass involves drawing lines. 164 * 165 * @param pass the pass. 166 * 167 * @return A boolean. 168 */ 169 protected boolean isLinePass(int pass) { 170 return pass == 0 || pass == 1; 171 } 172 173 /** 174 * Returns <code>true</code> if the specified pass involves drawing items. 175 * 176 * @param pass the pass. 177 * 178 * @return A boolean. 179 */ 180 protected boolean isItemPass(int pass) { 181 return pass == 2; 182 } 183 184 /** 185 * Returns <code>true</code> if the specified pass involves drawing shadows. 186 * 187 * @param pass the pass. 188 * 189 * @return A boolean. 190 */ 191 protected boolean isShadowPass (int pass) { 192 return pass == 0; 193 } 194 195 /** 196 * Overrides the method in the subclass to draw a shadow in the first pass. 197 * 198 * @param g2 the graphics device. 199 * @param pass the pass. 200 * @param series the series index (zero-based). 201 * @param item the item index (zero-based). 202 * @param shape the shape. 203 */ 204 protected void drawFirstPassShape(Graphics2D g2, 205 int pass, 206 int series, 207 int item, 208 Shape shape) { 209 if (isShadowPass(pass)) { 210 if (getWallPaint() != null) { 211 g2.setStroke(getItemStroke(series, item)); 212 g2.setPaint(getWallPaint()); 213 g2.translate(getXOffset(), getYOffset()); 214 g2.draw(shape); 215 g2.translate(-getXOffset(), -getYOffset()); 216 } 217 } 218 else { 219 // now draw the real shape 220 super.drawFirstPassShape(g2, pass, series, item, shape); 221 } 222 } 223 224 }