001/* ===========================================================
002 * JFreeChart : a free chart library for the Java(tm) platform
003 * ===========================================================
004 *
005 * (C) Copyright 2000-present, by David Gilbert 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-present, by Achilleus Mantzios and Contributors.
031 *
032 * Original Author:  Achilleus Mantzios;
033 * Contributor(s):   David Gilbert;
034 *
035 */
036
037package org.jfree.chart.renderer.xy;
038
039import java.awt.Color;
040import java.awt.Font;
041import java.awt.Graphics2D;
042import java.awt.Paint;
043import java.awt.Stroke;
044import java.awt.geom.Line2D;
045import java.awt.geom.Rectangle2D;
046import java.io.Serializable;
047
048import org.jfree.chart.axis.ValueAxis;
049import org.jfree.chart.plot.CrosshairState;
050import org.jfree.chart.plot.PlotRenderingInfo;
051import org.jfree.chart.plot.XYPlot;
052import org.jfree.chart.ui.RectangleEdge;
053import org.jfree.chart.util.PublicCloneable;
054import org.jfree.data.xy.WindDataset;
055import org.jfree.data.xy.XYDataset;
056
057/**
058 * A specialised renderer for displaying wind intensity/direction data.
059 * The example shown here is generated by the {@code WindChartDemo1.java}
060 * program included in the JFreeChart demo collection:
061 * <br><br>
062 * <img src="doc-files/WindItemRendererSample.png"
063 * alt="WindItemRendererSample.png">
064 */
065public class WindItemRenderer extends AbstractXYItemRenderer
066        implements XYItemRenderer, Cloneable, PublicCloneable, Serializable {
067
068    /** For serialization. */
069    private static final long serialVersionUID = 8078914101916976844L;
070
071    /**
072     * Creates a new renderer.
073     */
074    public WindItemRenderer() {
075        super();
076    }
077
078    /**
079     * Draws the visual representation of a single data item.
080     *
081     * @param g2  the graphics device.
082     * @param state  the renderer state.
083     * @param plotArea  the area within which the plot is being drawn.
084     * @param info  optional information collection.
085     * @param plot  the plot (can be used to obtain standard color
086     *              information etc).
087     * @param domainAxis  the horizontal axis.
088     * @param rangeAxis  the vertical axis.
089     * @param dataset  the dataset.
090     * @param series  the series index (zero-based).
091     * @param item  the item index (zero-based).
092     * @param crosshairState  crosshair information for the plot
093     *                        ({@code null} permitted).
094     * @param pass  the pass index.
095     */
096    @Override
097    public void drawItem(Graphics2D g2, XYItemRendererState state,
098            Rectangle2D plotArea, PlotRenderingInfo info, XYPlot plot,
099            ValueAxis domainAxis, ValueAxis rangeAxis, XYDataset dataset,
100            int series, int item, CrosshairState crosshairState, int pass) {
101
102        WindDataset windData = (WindDataset) dataset;
103
104        Paint seriesPaint = getItemPaint(series, item);
105        Stroke seriesStroke = getItemStroke(series, item);
106        g2.setPaint(seriesPaint);
107        g2.setStroke(seriesStroke);
108
109        // get the data point...
110
111        Number x = windData.getX(series, item);
112        Number windDir = windData.getWindDirection(series, item);
113        Number wforce = windData.getWindForce(series, item);
114        double windForce = wforce.doubleValue();
115
116        double wdirt = Math.toRadians(windDir.doubleValue() * (-30.0) - 90.0);
117
118        double ax1, ax2, ay1, ay2, rax2, ray2;
119
120        RectangleEdge domainAxisLocation = plot.getDomainAxisEdge();
121        RectangleEdge rangeAxisLocation = plot.getRangeAxisEdge();
122        ax1 = domainAxis.valueToJava2D(x.doubleValue(), plotArea,
123                domainAxisLocation);
124        ay1 = rangeAxis.valueToJava2D(0.0, plotArea, rangeAxisLocation);
125
126        rax2 = x.doubleValue() + (windForce * Math.cos(wdirt) * 8000000.0);
127        ray2 = windForce * Math.sin(wdirt);
128
129        ax2 = domainAxis.valueToJava2D(rax2, plotArea, domainAxisLocation);
130        ay2 = rangeAxis.valueToJava2D(ray2, plotArea, rangeAxisLocation);
131
132        int diri = windDir.intValue();
133        int forcei = wforce.intValue();
134        String dirforce = diri + "-" + forcei;
135        Line2D line = new Line2D.Double(ax1, ay1, ax2, ay2);
136
137        g2.draw(line);
138        g2.setPaint(Color.BLUE);
139        g2.setFont(new Font("Dialog", 1, 9));
140
141        g2.drawString(dirforce, (float) ax1, (float) ay1);
142
143        g2.setPaint(seriesPaint);
144        g2.setStroke(seriesStroke);
145
146        double alx2, aly2, arx2, ary2;
147        double ralx2, raly2, rarx2, rary2;
148
149        double aldir = Math.toRadians(windDir.doubleValue()
150                * (-30.0) - 90.0 - 5.0);
151        ralx2 = wforce.doubleValue() * Math.cos(aldir) * 8000000 * 0.8
152        + x.doubleValue();
153        raly2 = wforce.doubleValue() * Math.sin(aldir) * 0.8;
154
155        alx2 = domainAxis.valueToJava2D(ralx2, plotArea, domainAxisLocation);
156        aly2 = rangeAxis.valueToJava2D(raly2, plotArea, rangeAxisLocation);
157
158        line = new Line2D.Double(alx2, aly2, ax2, ay2);
159        g2.draw(line);
160
161        double ardir = Math.toRadians(windDir.doubleValue()
162                * (-30.0) - 90.0 + 5.0);
163        rarx2 = wforce.doubleValue() * Math.cos(ardir) * 8000000 * 0.8
164                + x.doubleValue();
165        rary2 = wforce.doubleValue() * Math.sin(ardir) * 0.8;
166
167        arx2 = domainAxis.valueToJava2D(rarx2, plotArea, domainAxisLocation);
168        ary2 = rangeAxis.valueToJava2D(rary2, plotArea, rangeAxisLocation);
169
170        line = new Line2D.Double(arx2, ary2, ax2, ay2);
171        g2.draw(line);
172
173    }
174
175    /**
176     * Returns a clone of the renderer.
177     *
178     * @return A clone.
179     *
180     * @throws CloneNotSupportedException  if the renderer cannot be cloned.
181     */
182    @Override
183    public Object clone() throws CloneNotSupportedException {
184        return super.clone();
185    }
186
187}