001/* ===========================================================
002 * JFreeChart : a free chart library for the Java(tm) platform
003 * ===========================================================
004 *
005 * (C) Copyright 2000-2008, 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-2008, 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 * The example shown here is generated by the <code>WindChartDemo1.java</code>
081 * program included in the JFreeChart demo collection:
082 * <br><br>
083 * <img src="../../../../../images/WindItemRendererSample.png"
084 * alt="WindItemRendererSample.png" />
085 */
086public class WindItemRenderer extends AbstractXYItemRenderer
087        implements XYItemRenderer, Cloneable, PublicCloneable, Serializable {
088
089    /** For serialization. */
090    private static final long serialVersionUID = 8078914101916976844L;
091
092    /**
093     * Creates a new renderer.
094     */
095    public WindItemRenderer() {
096        super();
097    }
098
099    /**
100     * Draws the visual representation of a single data item.
101     *
102     * @param g2  the graphics device.
103     * @param state  the renderer state.
104     * @param plotArea  the area within which the plot is being drawn.
105     * @param info  optional information collection.
106     * @param plot  the plot (can be used to obtain standard color
107     *              information etc).
108     * @param domainAxis  the horizontal axis.
109     * @param rangeAxis  the vertical axis.
110     * @param dataset  the dataset.
111     * @param series  the series index (zero-based).
112     * @param item  the item index (zero-based).
113     * @param crosshairState  crosshair information for the plot
114     *                        (<code>null</code> permitted).
115     * @param pass  the pass index.
116     */
117    public void drawItem(Graphics2D g2,
118                         XYItemRendererState state,
119                         Rectangle2D plotArea,
120                         PlotRenderingInfo info,
121                         XYPlot plot,
122                         ValueAxis domainAxis,
123                         ValueAxis rangeAxis,
124                         XYDataset dataset,
125                         int series,
126                         int item,
127                         CrosshairState crosshairState,
128                         int pass) {
129
130        WindDataset windData = (WindDataset) dataset;
131
132        Paint seriesPaint = getItemPaint(series, item);
133        Stroke seriesStroke = getItemStroke(series, item);
134        g2.setPaint(seriesPaint);
135        g2.setStroke(seriesStroke);
136
137        // get the data point...
138
139        Number x = windData.getX(series, item);
140        Number windDir = windData.getWindDirection(series, item);
141        Number wforce = windData.getWindForce(series, item);
142        double windForce = wforce.doubleValue();
143
144        double wdirt = Math.toRadians(windDir.doubleValue() * (-30.0) - 90.0);
145
146        double ax1, ax2, ay1, ay2, rax2, ray2;
147
148        RectangleEdge domainAxisLocation = plot.getDomainAxisEdge();
149        RectangleEdge rangeAxisLocation = plot.getRangeAxisEdge();
150        ax1 = domainAxis.valueToJava2D(x.doubleValue(), plotArea,
151                domainAxisLocation);
152        ay1 = rangeAxis.valueToJava2D(0.0, plotArea, rangeAxisLocation);
153
154        rax2 = x.doubleValue() + (windForce * Math.cos(wdirt) * 8000000.0);
155        ray2 = windForce * Math.sin(wdirt);
156
157        ax2 = domainAxis.valueToJava2D(rax2, plotArea, domainAxisLocation);
158        ay2 = rangeAxis.valueToJava2D(ray2, plotArea, rangeAxisLocation);
159
160        int diri = windDir.intValue();
161        int forcei = wforce.intValue();
162        String dirforce = diri + "-" + forcei;
163        Line2D line = new Line2D.Double(ax1, ay1, ax2, ay2);
164
165        g2.draw(line);
166        g2.setPaint(Color.blue);
167        g2.setFont(new Font("Dialog", 1, 9));
168
169        g2.drawString(dirforce, (float) ax1, (float) ay1);
170
171        g2.setPaint(seriesPaint);
172        g2.setStroke(seriesStroke);
173
174        double alx2, aly2, arx2, ary2;
175        double ralx2, raly2, rarx2, rary2;
176
177        double aldir = Math.toRadians(windDir.doubleValue()
178                * (-30.0) - 90.0 - 5.0);
179        ralx2 = wforce.doubleValue() * Math.cos(aldir) * 8000000 * 0.8
180        + x.doubleValue();
181        raly2 = wforce.doubleValue() * Math.sin(aldir) * 0.8;
182
183        alx2 = domainAxis.valueToJava2D(ralx2, plotArea, domainAxisLocation);
184        aly2 = rangeAxis.valueToJava2D(raly2, plotArea, rangeAxisLocation);
185
186        line = new Line2D.Double(alx2, aly2, ax2, ay2);
187        g2.draw(line);
188
189        double ardir = Math.toRadians(windDir.doubleValue()
190                * (-30.0) - 90.0 + 5.0);
191        rarx2 = wforce.doubleValue() * Math.cos(ardir) * 8000000 * 0.8
192                + x.doubleValue();
193        rary2 = wforce.doubleValue() * Math.sin(ardir) * 0.8;
194
195        arx2 = domainAxis.valueToJava2D(rarx2, plotArea, domainAxisLocation);
196        ary2 = rangeAxis.valueToJava2D(rary2, plotArea, rangeAxisLocation);
197
198        line = new Line2D.Double(arx2, ary2, ax2, ay2);
199        g2.draw(line);
200
201    }
202
203    /**
204     * Returns a clone of the renderer.
205     *
206     * @return A clone.
207     *
208     * @throws CloneNotSupportedException  if the renderer cannot be cloned.
209     */
210    public Object clone() throws CloneNotSupportedException {
211        return super.clone();
212    }
213
214}