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 * XYDotRenderer.java 029 * ------------------ 030 * (C) Copyright 2002-2007, by Object Refinery Limited. 031 * 032 * Original Author: David Gilbert (for Object Refinery Limited); 033 * Contributor(s): Christian W. Zuckschwerdt; 034 * 035 * $Id: XYDotRenderer.java,v 1.5.2.4 2007/02/06 16:29:11 mungady Exp $ 036 * 037 * Changes (from 29-Oct-2002) 038 * -------------------------- 039 * 29-Oct-2002 : Added standard header (DG); 040 * 25-Mar-2003 : Implemented Serializable (DG); 041 * 01-May-2003 : Modified drawItem() method signature (DG); 042 * 30-Jul-2003 : Modified entity constructor (CZ); 043 * 20-Aug-2003 : Implemented Cloneable and PublicCloneable (DG); 044 * 16-Sep-2003 : Changed ChartRenderingInfo --> PlotRenderingInfo (DG); 045 * 25-Feb-2004 : Replaced CrosshairInfo with CrosshairState (DG); 046 * 19-Jan-2005 : Now uses only primitives from dataset (DG); 047 * ------------- JFREECHART 1.0.x --------------------------------------------- 048 * 10-Jul-2006 : Added dotWidth and dotHeight attributes (DG); 049 * 06-Feb-2007 : Fixed bug 1086307, crosshairs with multiple axes (DG); 050 * 051 */ 052 053 package org.jfree.chart.renderer.xy; 054 055 import java.awt.Graphics2D; 056 import java.awt.geom.Rectangle2D; 057 import java.io.Serializable; 058 059 import org.jfree.chart.axis.ValueAxis; 060 import org.jfree.chart.event.RendererChangeEvent; 061 import org.jfree.chart.plot.CrosshairState; 062 import org.jfree.chart.plot.PlotOrientation; 063 import org.jfree.chart.plot.PlotRenderingInfo; 064 import org.jfree.chart.plot.XYPlot; 065 import org.jfree.data.xy.XYDataset; 066 import org.jfree.ui.RectangleEdge; 067 import org.jfree.util.PublicCloneable; 068 069 /** 070 * A renderer that draws a small dot at each data point for an {@link XYPlot}. 071 */ 072 public class XYDotRenderer extends AbstractXYItemRenderer 073 implements XYItemRenderer, 074 Cloneable, 075 PublicCloneable, 076 Serializable { 077 078 /** For serialization. */ 079 private static final long serialVersionUID = -2764344339073566425L; 080 081 /** The dot width. */ 082 private int dotWidth; 083 084 /** The dot height. */ 085 private int dotHeight; 086 087 /** 088 * Constructs a new renderer. 089 */ 090 public XYDotRenderer() { 091 super(); 092 this.dotWidth = 1; 093 this.dotHeight = 1; 094 } 095 096 /** 097 * Returns the dot width (the default value is 1). 098 * 099 * @return The dot width. 100 * 101 * @since 1.0.2 102 * @see #setDotWidth(int) 103 */ 104 public int getDotWidth() { 105 return this.dotWidth; 106 } 107 108 /** 109 * Sets the dot width and sends a {@link RendererChangeEvent} to all 110 * registered listeners. 111 * 112 * @param w the new width (must be greater than zero). 113 * 114 * @throws IllegalArgumentException if <code>w</code> is less than one. 115 * 116 * @since 1.0.2 117 * @see #getDotWidth() 118 */ 119 public void setDotWidth(int w) { 120 if (w < 1) { 121 throw new IllegalArgumentException("Requires w > 0."); 122 } 123 this.dotWidth = w; 124 notifyListeners(new RendererChangeEvent(this)); 125 } 126 127 /** 128 * Returns the dot height (the default value is 1). 129 * 130 * @return The dot height. 131 * 132 * @since 1.0.2 133 * @see #setDotHeight(int) 134 */ 135 public int getDotHeight() { 136 return this.dotHeight; 137 } 138 139 /** 140 * Sets the dot height and sends a {@link RendererChangeEvent} to all 141 * registered listeners. 142 * 143 * @param h the new height (must be greater than zero). 144 * 145 * @throws IllegalArgumentException if <code>h</code> is less than one. 146 * 147 * @since 1.0.2 148 * @see #getDotHeight() 149 */ 150 public void setDotHeight(int h) { 151 if (h < 1) { 152 throw new IllegalArgumentException("Requires h > 0."); 153 } 154 this.dotHeight = h; 155 notifyListeners(new RendererChangeEvent(this)); 156 } 157 158 /** 159 * Draws the visual representation of a single data item. 160 * 161 * @param g2 the graphics device. 162 * @param state the renderer state. 163 * @param dataArea the area within which the data is being drawn. 164 * @param info collects information about the drawing. 165 * @param plot the plot (can be used to obtain standard color 166 * information etc). 167 * @param domainAxis the domain (horizontal) axis. 168 * @param rangeAxis the range (vertical) axis. 169 * @param dataset the dataset. 170 * @param series the series index (zero-based). 171 * @param item the item index (zero-based). 172 * @param crosshairState crosshair information for the plot 173 * (<code>null</code> permitted). 174 * @param pass the pass index. 175 */ 176 public void drawItem(Graphics2D g2, 177 XYItemRendererState state, 178 Rectangle2D dataArea, 179 PlotRenderingInfo info, 180 XYPlot plot, 181 ValueAxis domainAxis, 182 ValueAxis rangeAxis, 183 XYDataset dataset, 184 int series, 185 int item, 186 CrosshairState crosshairState, 187 int pass) { 188 189 // get the data point... 190 double x = dataset.getXValue(series, item); 191 double y = dataset.getYValue(series, item); 192 double adjx = (this.dotWidth - 1) / 2.0; 193 double adjy = (this.dotHeight - 1) / 2.0; 194 if (!Double.isNaN(y)) { 195 RectangleEdge xAxisLocation = plot.getDomainAxisEdge(); 196 RectangleEdge yAxisLocation = plot.getRangeAxisEdge(); 197 double transX = domainAxis.valueToJava2D(x, dataArea, 198 xAxisLocation) - adjx; 199 double transY = rangeAxis.valueToJava2D(y, dataArea, yAxisLocation) 200 - adjy; 201 202 g2.setPaint(getItemPaint(series, item)); 203 PlotOrientation orientation = plot.getOrientation(); 204 if (orientation == PlotOrientation.HORIZONTAL) { 205 g2.fillRect((int) transY, (int) transX, this.dotHeight, 206 this.dotWidth); 207 } 208 else if (orientation == PlotOrientation.VERTICAL) { 209 g2.fillRect((int) transX, (int) transY, this.dotWidth, 210 this.dotHeight); 211 } 212 213 int domainAxisIndex = plot.getDomainAxisIndex(domainAxis); 214 int rangeAxisIndex = plot.getRangeAxisIndex(rangeAxis); 215 updateCrosshairValues(crosshairState, x, y, domainAxisIndex, 216 rangeAxisIndex, transX, transY, orientation); 217 } 218 219 } 220 221 /** 222 * Tests this renderer for equality with an arbitrary object. This method 223 * returns <code>true</code> if and only if: 224 * 225 * <ul> 226 * <li><code>obj</code> is not <code>null</code>;</li> 227 * <li><code>obj</code> is an instance of <code>XYDotRenderer</code>;</li> 228 * <li>both renderers have the same attribute values. 229 * </ul> 230 * 231 * @param obj the object (<code>null</code> permitted). 232 * 233 * @return A boolean. 234 */ 235 public boolean equals(Object obj) { 236 if (obj == this) { 237 return true; 238 } 239 if (!(obj instanceof XYDotRenderer)) { 240 return false; 241 } 242 XYDotRenderer that = (XYDotRenderer) obj; 243 if (this.dotWidth != that.dotWidth) { 244 return false; 245 } 246 if (this.dotHeight != that.dotHeight) { 247 return false; 248 } 249 return super.equals(obj); 250 } 251 252 /** 253 * Returns a clone of the renderer. 254 * 255 * @return A clone. 256 * 257 * @throws CloneNotSupportedException if the renderer cannot be cloned. 258 */ 259 public Object clone() throws CloneNotSupportedException { 260 return super.clone(); 261 } 262 263 }