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 * WindItemRenderer.java
029 * ---------------------
030 * (C) Copyright 2001-2007, by Achilleus Mantzios and Contributors.
031 *
032 * Original Author:  Achilleus Mantzios;
033 * Contributor(s):   David Gilbert (for Object Refinery Limited);
034 *
035 * Changes
036 * -------
037 * 06-Feb-2002 : Version 1, based on code contributed by Achilleus 
038 *               Mantzios (DG);
039 * 28-Mar-2002 : Added a property change listener mechanism so that renderers 
040 *               no longer need to be immutable.  Changed StrictMath --> Math 
041 *               to retain JDK1.2 compatibility (DG);
042 * 09-Apr-2002 : Changed return type of the drawItem method to void, reflecting 
043 *               the change in the XYItemRenderer method (DG);
044 * 01-Oct-2002 : Fixed errors reported by Checkstyle (DG);
045 * 21-Jan-2003 : Added new constructor (DG);
046 * 25-Mar-2003 : Implemented Serializable (DG);
047 * 01-May-2003 : Modified drawItem() method signature (DG);
048 * 20-Aug-2003 : Implemented Cloneable and PublicCloneable (DG);
049 * 16-Sep-2003 : Changed ChartRenderingInfo --> PlotRenderingInfo (DG);
050 * 25-Feb-2004 : Replaced CrosshairInfo with CrosshairState (DG);
051 * 15-Jul-2004 : Switched getX() with getXValue() and getY() with 
052 *               getYValue() (DG);
053 * ------------- JFREECHART 1.0.x ---------------------------------------------
054 * 02-Feb-2007 : Removed author tags from all over JFreeChart sources (DG);
055 *
056 */
057
058package org.jfree.chart.renderer.xy;
059
060import java.awt.Color;
061import java.awt.Font;
062import java.awt.Graphics2D;
063import java.awt.Paint;
064import java.awt.Stroke;
065import java.awt.geom.Line2D;
066import java.awt.geom.Rectangle2D;
067import java.io.Serializable;
068
069import org.jfree.chart.axis.ValueAxis;
070import org.jfree.chart.plot.CrosshairState;
071import org.jfree.chart.plot.PlotRenderingInfo;
072import org.jfree.chart.plot.XYPlot;
073import org.jfree.data.xy.WindDataset;
074import org.jfree.data.xy.XYDataset;
075import org.jfree.ui.RectangleEdge;
076import org.jfree.util.PublicCloneable;
077
078/**
079 * A specialised renderer for displaying wind intensity/direction data.
080 */
081public class WindItemRenderer extends AbstractXYItemRenderer 
082                              implements XYItemRenderer, 
083                                         Cloneable,
084                                         PublicCloneable,
085                                         Serializable {
086
087    /** For serialization. */
088    private static final long serialVersionUID = 8078914101916976844L;
089    
090    /**
091     * Creates a new renderer.
092     */
093    public WindItemRenderer() {
094        super();
095    }
096
097    /**
098     * Draws the visual representation of a single data item.
099     *
100     * @param g2  the graphics device.
101     * @param state  the renderer state.
102     * @param plotArea  the area within which the plot is being drawn.
103     * @param info  optional information collection.
104     * @param plot  the plot (can be used to obtain standard color 
105     *              information etc).
106     * @param domainAxis  the horizontal axis.
107     * @param rangeAxis  the vertical axis.
108     * @param dataset  the dataset.
109     * @param series  the series index (zero-based).
110     * @param item  the item index (zero-based).
111     * @param crosshairState  crosshair information for the plot 
112     *                        (<code>null</code> permitted).
113     * @param pass  the pass index.
114     */
115    public void drawItem(Graphics2D g2,
116                         XYItemRendererState state,
117                         Rectangle2D plotArea,
118                         PlotRenderingInfo info,
119                         XYPlot plot,
120                         ValueAxis domainAxis,
121                         ValueAxis rangeAxis,
122                         XYDataset dataset,
123                         int series,
124                         int item,
125                         CrosshairState crosshairState,
126                         int pass) {
127
128        WindDataset windData = (WindDataset) dataset;
129
130        Paint seriesPaint = getItemPaint(series, item);
131        Stroke seriesStroke = getItemStroke(series, item);
132        g2.setPaint(seriesPaint);
133        g2.setStroke(seriesStroke);
134
135        // get the data point...
136
137        Number x = windData.getX(series, item);
138        Number windDir = windData.getWindDirection(series, item);
139        Number wforce = windData.getWindForce(series, item);
140        double windForce = wforce.doubleValue();
141
142        double wdirt = Math.toRadians(windDir.doubleValue() * (-30.0) - 90.0);
143
144        double ax1, ax2, ay1, ay2, rax2, ray2;
145
146        RectangleEdge domainAxisLocation = plot.getDomainAxisEdge();
147        RectangleEdge rangeAxisLocation = plot.getRangeAxisEdge();
148        ax1 = domainAxis.valueToJava2D(x.doubleValue(), plotArea, 
149                domainAxisLocation);
150        ay1 = rangeAxis.valueToJava2D(0.0, plotArea, rangeAxisLocation);
151
152        rax2 = x.doubleValue() + (windForce * Math.cos(wdirt) * 8000000.0);
153        ray2 = windForce * Math.sin(wdirt);
154
155        ax2 = domainAxis.valueToJava2D(rax2, plotArea, domainAxisLocation);
156        ay2 = rangeAxis.valueToJava2D(ray2, plotArea, rangeAxisLocation);
157
158        int diri = windDir.intValue();
159        int forcei = wforce.intValue();
160        String dirforce = diri + "-" + forcei;
161        Line2D line = new Line2D.Double(ax1, ay1, ax2, ay2);
162
163        g2.draw(line);
164        g2.setPaint(Color.blue);
165        g2.setFont(new Font("foo", 1, 9));
166
167        g2.drawString(dirforce, (float) ax1, (float) ay1);
168
169        g2.setPaint(seriesPaint);
170        g2.setStroke(seriesStroke);
171
172        double alx2, aly2, arx2, ary2;
173        double ralx2, raly2, rarx2, rary2;
174
175        double aldir = Math.toRadians(windDir.doubleValue() 
176                * (-30.0) - 90.0 - 5.0);
177        ralx2 = wforce.doubleValue() * Math.cos(aldir) * 8000000 * 0.8 
178        + x.doubleValue();
179        raly2 = wforce.doubleValue() * Math.sin(aldir) * 0.8;
180
181        alx2 = domainAxis.valueToJava2D(ralx2, plotArea, domainAxisLocation);
182        aly2 = rangeAxis.valueToJava2D(raly2, plotArea, rangeAxisLocation);
183
184        line = new Line2D.Double(alx2, aly2, ax2, ay2);
185        g2.draw(line);
186
187        double ardir = Math.toRadians(windDir.doubleValue() 
188                * (-30.0) - 90.0 + 5.0);
189        rarx2 = wforce.doubleValue() * Math.cos(ardir) * 8000000 * 0.8 
190                + x.doubleValue();
191        rary2 = wforce.doubleValue() * Math.sin(ardir) * 0.8;
192
193        arx2 = domainAxis.valueToJava2D(rarx2, plotArea, domainAxisLocation);
194        ary2 = rangeAxis.valueToJava2D(rary2, plotArea, rangeAxisLocation);
195
196        line = new Line2D.Double(arx2, ary2, ax2, ay2);
197        g2.draw(line);
198
199    }
200
201    /**
202     * Returns a clone of the renderer.
203     * 
204     * @return A clone.
205     * 
206     * @throws CloneNotSupportedException  if the renderer cannot be cloned.
207     */
208    public Object clone() throws CloneNotSupportedException {
209        return super.clone();
210    }
211
212}