    001/* ===========================================================
    002 * JFreeChart : a free chart library for the Java(tm) platform
    003 * ===========================================================
    004 *
    005 * (C) Copyright 2000-2011, 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-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}