001/* ===========================================================
002 * JFreeChart : a free chart library for the Java(tm) platform
003 * ===========================================================
004 *
005 * (C) Copyright 2000-2014, 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 * [Oracle and Java are registered trademarks of Oracle and/or its affiliates. 
025 * Other names may be trademarks of their respective owners.]
026 *
027 * ---------------------
028 * WindItemRenderer.java
029 * ---------------------
030 * (C) Copyright 2001-2014, 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    @Override
118    public void drawItem(Graphics2D g2, XYItemRendererState state,
119            Rectangle2D plotArea, PlotRenderingInfo info, XYPlot plot,
120            ValueAxis domainAxis, ValueAxis rangeAxis, XYDataset dataset,
121            int series, int item, CrosshairState crosshairState, int pass) {
122
123        WindDataset windData = (WindDataset) dataset;
124
125        Paint seriesPaint = getItemPaint(series, item);
126        Stroke seriesStroke = getItemStroke(series, item);
127        g2.setPaint(seriesPaint);
128        g2.setStroke(seriesStroke);
129
130        // get the data point...
131
132        Number x = windData.getX(series, item);
133        Number windDir = windData.getWindDirection(series, item);
134        Number wforce = windData.getWindForce(series, item);
135        double windForce = wforce.doubleValue();
136
137        double wdirt = Math.toRadians(windDir.doubleValue() * (-30.0) - 90.0);
138
139        double ax1, ax2, ay1, ay2, rax2, ray2;
140
141        RectangleEdge domainAxisLocation = plot.getDomainAxisEdge();
142        RectangleEdge rangeAxisLocation = plot.getRangeAxisEdge();
143        ax1 = domainAxis.valueToJava2D(x.doubleValue(), plotArea,
144                domainAxisLocation);
145        ay1 = rangeAxis.valueToJava2D(0.0, plotArea, rangeAxisLocation);
146
147        rax2 = x.doubleValue() + (windForce * Math.cos(wdirt) * 8000000.0);
148        ray2 = windForce * Math.sin(wdirt);
149
150        ax2 = domainAxis.valueToJava2D(rax2, plotArea, domainAxisLocation);
151        ay2 = rangeAxis.valueToJava2D(ray2, plotArea, rangeAxisLocation);
152
153        int diri = windDir.intValue();
154        int forcei = wforce.intValue();
155        String dirforce = diri + "-" + forcei;
156        Line2D line = new Line2D.Double(ax1, ay1, ax2, ay2);
157
158        g2.draw(line);
159        g2.setPaint(Color.blue);
160        g2.setFont(new Font("Dialog", 1, 9));
161
162        g2.drawString(dirforce, (float) ax1, (float) ay1);
163
164        g2.setPaint(seriesPaint);
165        g2.setStroke(seriesStroke);
166
167        double alx2, aly2, arx2, ary2;
168        double ralx2, raly2, rarx2, rary2;
169
170        double aldir = Math.toRadians(windDir.doubleValue()
171                * (-30.0) - 90.0 - 5.0);
172        ralx2 = wforce.doubleValue() * Math.cos(aldir) * 8000000 * 0.8
173        + x.doubleValue();
174        raly2 = wforce.doubleValue() * Math.sin(aldir) * 0.8;
175
176        alx2 = domainAxis.valueToJava2D(ralx2, plotArea, domainAxisLocation);
177        aly2 = rangeAxis.valueToJava2D(raly2, plotArea, rangeAxisLocation);
178
179        line = new Line2D.Double(alx2, aly2, ax2, ay2);
180        g2.draw(line);
181
182        double ardir = Math.toRadians(windDir.doubleValue()
183                * (-30.0) - 90.0 + 5.0);
184        rarx2 = wforce.doubleValue() * Math.cos(ardir) * 8000000 * 0.8
185                + x.doubleValue();
186        rary2 = wforce.doubleValue() * Math.sin(ardir) * 0.8;
187
188        arx2 = domainAxis.valueToJava2D(rarx2, plotArea, domainAxisLocation);
189        ary2 = rangeAxis.valueToJava2D(rary2, plotArea, rangeAxisLocation);
190
191        line = new Line2D.Double(arx2, ary2, ax2, ay2);
192        g2.draw(line);
193
194    }
195
196    /**
197     * Returns a clone of the renderer.
198     *
199     * @return A clone.
200     *
201     * @throws CloneNotSupportedException  if the renderer cannot be cloned.
202     */
203    @Override
204    public Object clone() throws CloneNotSupportedException {
205        return super.clone();
206    }
207
208}